diff options
136 files changed, 21360 insertions, 0 deletions
diff --git a/plugins/ExternalAPI/m_skins.h b/plugins/ExternalAPI/m_skins.h new file mode 100644 index 0000000000..da01064c64 --- /dev/null +++ b/plugins/ExternalAPI/m_skins.h @@ -0,0 +1,142 @@ +/* 
 +Copyright (C) 2008 Ricardo Pescuma Domenecci
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt.  If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA.  
 +*/
 +
 +
 +#ifndef __M_SKINS_H__
 +# define __M_SKINS_H__
 +
 +#include <windows.h>
 +
 +#define MIID_SKINS { 0x917db7a4, 0xd0fe, 0x4b1c, { 0x8c, 0xa3, 0x6d, 0xc1, 0x44, 0x80, 0xf5, 0xcc } }
 +
 +
 +typedef void * SKINNED_DIALOG;
 +typedef void * SKINNED_FIELD;
 +typedef void * SKINNED_DIALOG_STATE;
 +typedef void * SKINNED_FIELD_STATE;
 +
 +typedef void (*SkinOptionsChangedCallback)(void *param, SKINNED_DIALOG dlg);
 +
 +
 +#define SKN_HALIGN_LEFT 1
 +#define SKN_HALIGN_CENTER 2
 +#define SKN_HALIGN_RIGHT 3
 +
 +#define SKN_VALIGN_TOP 1
 +#define SKN_VALIGN_CENTER 2
 +#define SKN_VALIGN_BOTTOM 3
 +
 +
 +/// Some common parameters:
 +///  - name : internal name and name used inside skin file
 +///  - description : name shown to the user
 +///  - module : the module name where the settings will be stored
 +/// Do not translate any parameters.
 +struct SKIN_INTERFACE
 +{
 +	int cbSize;
 +
 +	// Global methods
 +	SKINNED_DIALOG (*RegisterDialog)(const char *name, const char *description, const char *module);
 +	void (*DeleteDialog)(SKINNED_DIALOG dlg);
 +	void (*SetSkinChangedCallback)(SKINNED_DIALOG dlg, SkinOptionsChangedCallback cb, void *param);
 +	void (*FinishedConfiguring)(SKINNED_DIALOG dlg);
 +
 +	// Dialog methods
 +	SKINNED_FIELD (*AddTextField)(SKINNED_DIALOG dlg, const char *name, const char *description);
 +	SKINNED_FIELD (*AddIconField)(SKINNED_DIALOG dlg, const char *name, const char *description);
 +	SKINNED_FIELD (*AddImageField)(SKINNED_DIALOG dlg, const char *name, const char *description);
 +	SKINNED_FIELD (*GetField)(SKINNED_DIALOG dlg, const char *name);
 +	void (*SetDialogSize)(SKINNED_DIALOG dlg, int width, int height);
 +	void (*SetInfoInt)(SKINNED_DIALOG dlg, const char *name, int value);
 +	void (*SetInfoDouble)(SKINNED_DIALOG dlg, const char *name, double value);
 +	void (*SetInfoBool)(SKINNED_DIALOG dlg, const char *name, BOOL value);
 +	void (*SetInfoString)(SKINNED_DIALOG dlg, const char *name, const TCHAR *value);
 +	void (*RemoveInfo)(SKINNED_DIALOG dlg, const char *name);
 +
 +	// Field methods
 +	void (*SetEnabled)(SKINNED_FIELD field, BOOL enabled);
 +	void (*SetToolTipA)(SKINNED_FIELD field, const char *tooltip);
 +	void (*SetToolTipW)(SKINNED_FIELD field, const WCHAR *tooltip);
 +
 +	// TextField methods
 +	void (*SetTextA)(SKINNED_FIELD field, const char *text);
 +	void (*SetTextW)(SKINNED_FIELD field, const WCHAR *text);
 +
 +	// IconField methods
 +	void (*SetIcon)(SKINNED_FIELD field, HICON hIcon);
 +
 +	// ImageField methods
 +	void (*SetImage)(SKINNED_FIELD field, HBITMAP hBmp);
 +
 +	// Run the skin and get an state from it
 +	SKINNED_DIALOG_STATE (*Run)(SKINNED_DIALOG dialog);
 +
 +	// Dialog State methods
 +	SKINNED_FIELD_STATE (*GetFieldState)(SKINNED_DIALOG_STATE dlg, const char *name);
 +	RECT (*GetDialogBorders)(SKINNED_DIALOG_STATE dlg);
 +
 +	// Field State methods
 +	RECT (*GetRect)(SKINNED_FIELD_STATE field);  // With borders
 +	RECT (*GetInsideRect)(SKINNED_FIELD_STATE field); // Without borders
 +	RECT (*GetRawRect)(SKINNED_FIELD_STATE field);  // With borders, without processing to assert inside window
 +	RECT (*GetRawInsideRect)(SKINNED_FIELD_STATE field); // Without borders, without processing to assert inside window
 +	RECT (*GetBorders)(SKINNED_FIELD_STATE field);
 +	BOOL (*IsVisible)(SKINNED_FIELD_STATE field);
 +	char * (*GetToolTipA)(SKINNED_FIELD field); // You have to free the result
 +	WCHAR * (*GetToolTipW)(SKINNED_FIELD field); // You have to free the result
 +	int (*GetHorizontalAlign)(SKINNED_FIELD_STATE field); // one of SKN_HALIGN_*
 +	int (*GetVerticalAlign)(SKINNED_FIELD_STATE field); // one of SKN_VALIGN_*
 +
 +	// TextField State methods
 +	char * (*GetTextA)(SKINNED_FIELD_STATE field); // You have to free the result
 +	WCHAR * (*GetTextW)(SKINNED_FIELD_STATE field); // You have to free the result
 +	HFONT (*GetFont)(SKINNED_FIELD_STATE field);
 +	COLORREF (*GetFontColor)(SKINNED_FIELD_STATE field);
 +
 +	// IconField State methods
 +	HICON (*GetIcon)(SKINNED_FIELD_STATE field);
 +
 +	// ImageField State methods
 +	HBITMAP (*GetImage)(SKINNED_FIELD_STATE field);
 +};
 +
 +
 +
 +/*
 +Skins/GetInterface service
 +Fill the function pointers for a SKIN_INTERFACE struct
 +
 +wparam = 0
 +lparam = (SKIN_INTERFACE *) struct to be filled
 +returns: 0 on success
 +*/
 +#define MS_SKINS_GETINTERFACE		"Skins/GetInterface"
 +
 +
 +
 +
 +static int mir_skins_getInterface(struct SKIN_INTERFACE *dest)
 +{
 +	dest->cbSize = sizeof(SKIN_INTERFACE);
 +	return CallService(MS_SKINS_GETINTERFACE, 0, (LPARAM) dest);
 +}
 +
 +
 +#endif // __M_SKINS_H__
 diff --git a/plugins/ExternalAPI/m_skins_cpp.h b/plugins/ExternalAPI/m_skins_cpp.h new file mode 100644 index 0000000000..bdc7337419 --- /dev/null +++ b/plugins/ExternalAPI/m_skins_cpp.h @@ -0,0 +1,210 @@ +/* 
 +Copyright (C) 2008 Ricardo Pescuma Domenecci
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt.  If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA.  
 +*/
 +
 +
 +#ifndef __M_SKINS_CPP_H__
 +# define __M_SKINS_CPP_H__
 +
 +#include "m_skins.h"
 +
 +extern struct SKIN_INTERFACE mski;
 +
 +
 +class SkinFieldState
 +{
 +public:
 +	SkinFieldState(SKINNED_FIELD_STATE field) : tooltip(NULL) { this->field = field; }
 +	virtual ~SkinFieldState() { if (tooltip != NULL) mir_free(tooltip); }
 +
 +	bool isValid() { return field != NULL; }
 +
 +	RECT getRect(bool raw = false) { return raw ? mski.GetRawRect(field) : mski.GetRect(field); }
 +	RECT getInsideRect(bool raw = false) { return raw ? mski.GetRawInsideRect(field) : mski.GetInsideRect(field); }
 +	RECT getBorders() { return mski.GetBorders(field); }
 +	bool isVisible() { return mski.IsVisible(field) != FALSE; }
 +	int getHorizontalAlign() { return mski.GetHorizontalAlign(field); } // one of SKN_HALIGN_*
 +	int getVerticalAlign() { return mski.GetVerticalAlign(field); } // one of SKN_VALIGN_*
 +
 +	const TCHAR * getToolTip() { 
 +		if (tooltip != NULL) 
 +			mir_free(tooltip);
 +
 +#ifdef UNICODE 
 +		tooltip = mski.GetToolTipW(field); 
 +#else 
 +		tooltip = mski.GetToolTipA(field); 
 +#endif 
 +		return tooltip;
 +	}
 +
 +protected:
 +	SKINNED_FIELD_STATE field;
 +	TCHAR *tooltip;
 +};
 +
 +class SkinTextFieldState : public SkinFieldState
 +{
 +public:
 +	SkinTextFieldState(SKINNED_FIELD_STATE field) : SkinFieldState(field), text(NULL) {}
 +	virtual ~SkinTextFieldState() { if (text != NULL) mir_free(text); }
 +
 +	const TCHAR * getText() { 
 +		if (text != NULL) 
 +			mir_free(text);
 +
 +#ifdef UNICODE 
 +		text = mski.GetTextW(field); 
 +#else 
 +		text = mski.GetTextA(field); 
 +#endif 
 +		return text;
 +	}
 +
 +	HFONT getFont() { return mski.GetFont(field); }
 +	COLORREF getFontColor() { return mski.GetFontColor(field); }
 +
 +private:
 +	TCHAR *text;
 +};
 +
 +class SkinIconFieldState : public SkinFieldState
 +{
 +public:
 +	SkinIconFieldState(SKINNED_FIELD_STATE field) : SkinFieldState(field) {}
 +
 +	HICON getIcon() { return mski.GetIcon(field); }
 +};
 +
 +class SkinImageFieldState : public SkinFieldState
 +{
 +public:
 +	SkinImageFieldState(SKINNED_FIELD_STATE field) : SkinFieldState(field) {}
 +
 +	HBITMAP getImage() { return mski.GetImage(field); }
 +};
 +
 +
 +class SkinDialogState
 +{
 +public:
 +	SkinDialogState(SKINNED_DIALOG_STATE dlg) { this->dlg = dlg; }
 +
 +	bool isValid() { return dlg != NULL; }
 +
 +	RECT getBorders() { return mski.GetDialogBorders(dlg); }
 +
 +	SkinFieldState getField(const char *name) { return SkinFieldState( mski.GetFieldState(dlg, name) ); }
 +	SkinTextFieldState getTextField(const char *name) { return SkinTextFieldState( mski.GetFieldState(dlg, name) ); }
 +	SkinIconFieldState getIconField(const char *name) { return SkinIconFieldState( mski.GetFieldState(dlg, name) ); }
 +	SkinImageFieldState getImageField(const char *name) { return SkinImageFieldState( mski.GetFieldState(dlg, name) ); }
 +
 +private:
 +	SKINNED_DIALOG_STATE dlg;
 +};
 +
 +
 +class SkinField
 +{
 +public:
 +	SkinField(SKINNED_FIELD field) { this->field = field; }
 +	
 +	bool isValid() { return field != NULL; }
 +	
 +	void setEnabled(bool enabled) { mski.SetEnabled(field, enabled); }
 +
 +	void setToolTip(const TCHAR *tooltip) { 
 +#ifdef UNICODE 
 +		mski.SetToolTipW(field, tooltip); 
 +#else 
 +		mski.SetToolTipA(field, tooltip); 
 +#endif
 +	}
 +
 +protected:
 +	SKINNED_FIELD field;
 +};
 +
 +class SkinTextField : public SkinField
 +{
 +public:
 +	SkinTextField(SKINNED_FIELD field) : SkinField(field) {}
 +
 +	void setText(const TCHAR *text) { 
 +#ifdef UNICODE 
 +		mski.SetTextW(field, text); 
 +#else 
 +		mski.SetTextA(field, text); 
 +#endif
 +	}
 +};
 +
 +class SkinIconField : public SkinField
 +{
 +public:
 +	SkinIconField(SKINNED_FIELD field) : SkinField(field) {}
 +
 +	void setIcon(HICON hIcon) { mski.SetIcon(field, hIcon); }
 +};
 +
 +class SkinImageField : public SkinField
 +{
 +public:
 +	SkinImageField(SKINNED_FIELD field) : SkinField(field) {}
 +
 +	void setImage(HBITMAP hBmp) { mski.SetImage(field, hBmp); }
 +};
 +
 +
 +class SkinDialog
 +{
 +public:
 +	SkinDialog(const char *name, const char *description, const char *module) { dlg = mski.RegisterDialog(name, description, module); }
 +	~SkinDialog() { mski.DeleteDialog(dlg); dlg = NULL; }
 +
 +	bool isValid() { return dlg != NULL; }
 +
 +	void setSkinChangedCallback(SkinOptionsChangedCallback cb, void *param) { mski.SetSkinChangedCallback(dlg, cb, param); }
 +
 +	void finishedConfiguring() { mski.FinishedConfiguring(dlg); }
 +
 +	void setSize(int width, int height) { mski.SetDialogSize(dlg, width, height); }
 +
 +	SkinTextField addTextField(const char *name, const char *description) { return SkinTextField( mski.AddTextField(dlg, name, description) ); }
 +	SkinIconField addIconField(const char *name, const char *description) { return SkinIconField( mski.AddIconField(dlg, name, description) ); }
 +	SkinImageField addImageField(const char *name, const char *description) { return SkinImageField( mski.AddImageField(dlg, name, description) ); }
 +
 +	SkinField getField(const char *name) { return SkinField( mski.GetField(dlg, name) ); }
 +	SkinTextField getTextField(const char *name) { return SkinTextField( mski.GetField(dlg, name) ); }
 +	SkinIconField getIconField(const char *name) { return SkinIconField( mski.GetField(dlg, name) ); }
 +	SkinImageField getImageField(const char *name) { return SkinImageField( mski.GetField(dlg, name) ); }
 +
 +	void setInfoInt(const char *name, int value) { mski.SetInfoInt(dlg, name, value); }
 +	void setInfoDouble(const char *name, double value) { mski.SetInfoDouble(dlg, name, value); }
 +	void setInfoBool(const char *name, bool value) { mski.SetInfoBool(dlg, name, value); }
 +	void setInfoString(const char *name, const TCHAR *value) { mski.SetInfoString(dlg, name, value); }
 +	void removeInfo(const char *name) { mski.RemoveInfo(dlg, name); }
 +
 +	SkinDialogState run() { return SkinDialogState( mski.Run(dlg) ); }
 +
 +private:
 +	SKINNED_DIALOG dlg;
 +};
 +
 +
 +#endif // __M_SKINS_CPP_H__
\ No newline at end of file diff --git a/plugins/MyDetails/Docs/Skins/Default/MyDetails.msk b/plugins/MyDetails/Docs/Skins/Default/MyDetails.msk new file mode 100644 index 0000000000..93c46b457a --- /dev/null +++ b/plugins/MyDetails/Docs/Skins/Default/MyDetails.msk @@ -0,0 +1,399 @@ +function configure()
 +{
 +	// Options for this skin
 +	
 +	opts.align_right.description = "Align to right"
 +	opts.align_right.type = CHECKBOX
 +	opts.align_right.value = false
 +	
 +	opts.show_avatar.description = "Show avatar"
 +	opts.show_avatar.type = CHECKBOX
 +	opts.show_avatar.value = true
 +	
 +	opts.avatar_allow_grow.description = "Allow avatar to grow (be bigger than original image)"
 +	opts.avatar_allow_grow.type = CHECKBOX
 +	opts.avatar_allow_grow.value = false
 +	
 +	opts.avatar_use_fixed_size.description = "Use fixed size avatar"
 +	opts.avatar_use_fixed_size.type = CHECKBOX
 +	opts.avatar_use_fixed_size.value = false
 +	
 +	opts.avatar_fixed_size.description = "Avatar fixed size (pixels)"
 +	opts.avatar_fixed_size.type = NUMBER
 +	opts.avatar_fixed_size.value = 30
 +	opts.avatar_fixed_size.min = 1
 +	opts.avatar_fixed_size.max = 255
 +	
 +	opts.show_protocol.description = "Show protocol"
 +	opts.show_protocol.type = CHECKBOX
 +	opts.show_protocol.value = true
 +	
 +	opts.show_email.description = "Show unread mail count"
 +	opts.show_email.type = CHECKBOX
 +	opts.show_email.value = true
 +	
 +	opts.show_status.description = "Show status"
 +	opts.show_status.type = CHECKBOX
 +	opts.show_status.value = true
 +	
 +	opts.show_status_msg.description = "Show status message"
 +	opts.show_status_msg.type = CHECKBOX
 +	opts.show_status_msg.value = true
 +	
 +	opts.show_listening.description = "Show listening to"
 +	opts.show_listening.type = CHECKBOX
 +	opts.show_listening.value = true
 +	
 +	opts.show_protocol_cycle.description = "Show protocol cycle buttons"
 +	opts.show_protocol_cycle.type = CHECKBOX
 +	opts.show_protocol_cycle.value = false
 +	
 +	opts.use_under_avatar.description = "Use free space (under avatar) to other texts"
 +	opts.use_under_avatar.type = CHECKBOX
 +	opts.use_under_avatar.value = true
 +	
 +	opts.border_left.description = "Left border"
 +	opts.border_left.type = NUMBER
 +	opts.border_left.value = 8
 +	opts.border_left.min = 0
 +	opts.border_left.max = 100
 +	
 +	opts.border_top.description = "Top border"
 +	opts.border_top.type = NUMBER
 +	opts.border_top.value = 8
 +	opts.border_top.min = 0
 +	opts.border_top.max = 100
 +	
 +	opts.border_right.description = "Right border"
 +	opts.border_right.type = NUMBER
 +	opts.border_right.value = 8
 +	opts.border_right.min = 0
 +	opts.border_right.max = 100
 +	
 +	opts.border_bottom.description = "Bottom border"
 +	opts.border_bottom.type = NUMBER
 +	opts.border_bottom.value = 8
 +	opts.border_bottom.min = 0
 +	opts.border_bottom.max = 100
 +	
 +	// Default fonts
 +	
 +	nickname.font.face = "Tahoma"
 +	nickname.font.size = 13
 +	nickname.font.bold = true
 +	nickname.font.color = RGB(0,0,0)
 +	
 +	protocol.font.face = "Tahoma"
 +	protocol.font.size = 8
 +	protocol.font.color = RGB(0,0,0)
 +	
 +	email.font.face = "Tahoma"
 +	email.font.size = 8
 +	email.font.color = RGB(0,0,0)
 +	
 +	status_name.font.face = "Tahoma"
 +	status_name.font.size = 8
 +	status_name.font.color = RGB(0,0,0)
 +	
 +	status_msg.font.face = "Tahoma"
 +	status_msg.font.size = 8
 +	status_msg.font.italic = true
 +	status_msg.font.color = RGB(150,150,150)
 +	
 +	listening.font.face = "Tahoma"
 +	listening.font.size = 8
 +	listening.font.italic = true
 +	listening.font.color = RGB(150,150,150)
 +}
 +	
 +function valign_center(top)
 +{
 +	var height = 0
 +	for(var i = 1; i < arguments.length; i++)
 +		height = Math.max(height, arguments[i].height)
 +	for(var i = 1; i < arguments.length; i++)
 +		arguments[i].top = top + (height - arguments[i].height)/2
 +	return top + height
 +}
 +
 +// Resize a field, keeping its aspect ratio
 +function resize(field, maxWidth, maxHeight, allowGrow)
 +{
 +	if (allowGrow == null)
 +		allowGrow = true
 +	
 +	var factor = Math.min(maxWidth / field.width, maxHeight / field.height)
 +	if (!allowGrow && factor >= 1)
 +		return
 +	
 +	field.width *= factor
 +	field.height *= factor
 +}
 +
 +function draw()
 +{
 +	// Default texts 
 +	if (nickname.enabled && nickname.text == "")
 +		nickname.text = "<no nickname>"
 +	if (status_msg.enabled && status_msg.text == "")
 +		status_msg.text = "<no status message>"
 +	if (listening.enabled && listening.text == "")
 +		listening.text = "<nothing playing>"
 +	
 +	if (info.protocol.locked)
 +		status_name.text += " (locked)"
 +	
 +	
 +	// ToolTips
 +	nickname.toolTip = nickname.text
 +	protocol.toolTip = protocol.text
 +	status_icon.toolTip = status_name.toolTip = status_name.text
 +	status_msg.toolTip = status_msg.text
 +	listening_icon.toolTip = listening.toolTip = listening.text
 +	next_proto.toolTip = "Show next protocol"
 +	prev_proto.toolTip = "Show previous protocol"
 +	email_icon.toolTip = email.toolTip = "Unread Email Count: " + email.text
 +	
 +	
 +	// Borders
 +	window.borders.left = opts.border_left
 +	window.borders.top = opts.border_top
 +	window.borders.right = opts.border_right
 +	window.borders.bottom = opts.border_bottom
 +	
 +	
 +	// Visible
 +	nickname.visible = true
 +	prev_proto.visible = next_proto.visible = opts.show_protocol_cycle && !IsEmpty(next_proto, prev_proto)
 +	avatar.visible = opts.show_avatar && avatar.enabled && !IsEmpty(avatar)
 +	protocol.visible = opts.show_protocol && protocol.enabled
 +	status_icon.visible = status_name.visible = opts.show_status && status_name.enabled
 +	status_msg.visible = opts.show_status_msg && !IsEmpty(status_msg)
 +	listening_icon.visible = listening.visible = opts.show_listening && !IsEmpty(listening_icon, listening)
 +	email_icon.visible = email.visible = opts.show_email && email.enabled && !IsEmpty(email_icon, email) && email.text > 0
 +	
 +	
 +	// Space to draw the frame around
 +	var BORDER_SPACE = 2
 +	nickname.borders = BORDER_SPACE
 +	protocol.borders = BORDER_SPACE
 +	status_icon.borders = BORDER_SPACE
 +	status_name.borders = BORDER_SPACE
 +	status_msg.borders = BORDER_SPACE
 +	listening_icon.borders = BORDER_SPACE
 +	listening.borders = BORDER_SPACE
 +	email_icon.borders = BORDER_SPACE
 +	email.borders = BORDER_SPACE
 +	
 +	
 +	if (avatar.visible)
 +	{
 +		if (opts.avatar_use_fixed_size)
 +			resize(avatar, opts.avatar_fixed_size, opts.avatar_fixed_size, opts.avatar_allow_grow)
 +		else
 +			resize(avatar, window.width/2.5, window.height - (!info.resize_frame && prev_proto.visible ? prev_proto.height : 0), opts.avatar_allow_grow)
 +	}
 +	
 +	if (!info.resize_frame && prev_proto.visible)
 +	{
 +		prev_proto.left = 0
 +		prev_proto.bottom = window.height
 +		
 +		next_proto.right = window.width
 +		next_proto.bottom = window.height
 +	}
 +
 +	var avatar_bottom = avatar.bottom
 +	if (opts.show_avatar && opts.avatar_use_fixed_size)
 +		avatar_bottom = opts.avatar_fixed_size
 +	
 +	var top = 0
 +	
 +	if (opts.align_right)
 +	{
 +		// Align
 +		nickname.hAlign = RIGHT
 +		protocol.hAlign = RIGHT
 +		status_name.hAlign = RIGHT
 +		status_msg.hAlign = RIGHT
 +		listening.hAlign = RIGHT
 +		
 +		
 +		var right = window.right
 +		
 +		function updateTopRight(val)
 +		{
 +			top = val
 +			if (opts.use_under_avatar && top > avatar_bottom)
 +				right = window.right
 +		}
 +		
 +		if (avatar.visible)
 +		{
 +			avatar.right = window.right
 +			avatar.top = 0
 +			
 +			right = avatar.left - 6
 +		}
 +		
 +		if (opts.show_avatar && opts.avatar_use_fixed_size)
 +			right = window.right - opts.avatar_fixed_size - 6
 +		
 +		nickname.right = right
 +		nickname.top = top
 +		
 +		updateTopRight(nickname.bottom)	
 +		
 +		if (protocol.visible)
 +		{
 +			protocol.right = right
 +			protocol.top = top
 +			
 +			if (email.visible)
 +			{
 +				email_icon.right = protocol.left - 10
 +				email.right = email_icon.left
 +				
 +				var bottom = valign_center(top, protocol, email_icon, email)
 +				updateTopRight(bottom)
 +			}
 +			else
 +				updateTopRight(protocol.bottom)
 +		} 
 +		else if (email.visible)
 +		{
 +			email_icon.borders.left = 0
 +			email_icon.right = right
 +			
 +			email.right = email_icon.left
 +			
 +			var bottom = valign_center(top, email_icon, email)
 +			updateTopRight(bottom)
 +		}
 +		
 +		if (status_name.visible)
 +		{
 +			status_icon.right = right
 +			status_name.right = status_icon.left
 +			
 +			var bottom = valign_center(top, status_icon, status_name)	
 +			updateTopRight(bottom)
 +		}
 +			
 +		if (status_msg.visible)
 +		{
 +			status_msg.right = right
 +			status_msg.top = top
 +			
 +			updateTopRight(status_msg.bottom)
 +		}
 +		
 +		if (listening.visible)
 +		{
 +			listening_icon.borders.left = 0
 +			listening_icon.right = right
 +			
 +			listening.right = listening_icon.left
 +			
 +			var bottom = valign_center(top, listening_icon, listening)
 +			updateTopRight(bottom)
 +		}
 +	}
 +	else
 +	{
 +		var left = 0
 +		
 +		function updateTopLeft(val)
 +		{
 +			top = val
 +			if (opts.use_under_avatar && top > avatar_bottom)
 +				left = 0
 +		}
 +		
 +		if (avatar.visible)
 +		{
 +			avatar.left = 0
 +			avatar.top = 0
 +			
 +			left = avatar.right + 6
 +		}
 +		
 +		if (opts.show_avatar && opts.avatar_use_fixed_size)
 +			left = opts.avatar_fixed_size + 6
 +		
 +		nickname.left = left
 +		nickname.top = top
 +		
 +		updateTopLeft(nickname.bottom)	
 +		
 +		if (protocol.visible)
 +		{
 +			protocol.left = left
 +			protocol.top = top
 +			
 +			if (email.visible)
 +			{
 +				email_icon.left = protocol.right + 10
 +				email.left = email_icon.right
 +				
 +				var bottom = valign_center(top, protocol, email_icon, email)
 +				updateTopLeft(bottom)
 +			}
 +			else
 +				updateTopLeft(protocol.bottom)
 +		}
 +		else if (email.visible)
 +		{
 +			email_icon.borders.right = 0
 +			email_icon.left = left
 +			
 +			email.left = email_icon.right
 +			
 +			var bottom = valign_center(top, email_icon, email)
 +			updateTopLeft(bottom)
 +		}
 +		
 +		if (status_name.visible)
 +		{
 +			status_icon.left = left
 +			status_name.left = status_icon.right
 +			
 +			var bottom = valign_center(top, status_icon, status_name)	
 +			updateTopLeft(bottom)
 +		}
 +			
 +		if (status_msg.visible)
 +		{
 +			status_msg.left = left
 +			status_msg.top = top
 +			
 +			updateTopLeft(status_msg.bottom)
 +		}
 +		
 +		if (listening.visible)
 +		{
 +			listening_icon.borders.right = 0
 +			listening_icon.left = left
 +			
 +			listening.borders.left = 0
 +			listening.left = listening_icon.right
 +			
 +			var bottom = valign_center(top, listening_icon, listening)
 +			updateTopLeft(bottom)
 +		}
 +	}
 +	
 +	if (info.resize_frame)
 +	{
 +		if (prev_proto.visible)
 +		{
 +			top = Math.max(avatar.bottom, top)
 +			
 +			prev_proto.left = 0
 +			prev_proto.top = top
 +			
 +			next_proto.right = window.width
 +			next_proto.top = top
 +		}
 +	}
 +}
\ No newline at end of file diff --git a/plugins/MyDetails/Docs/Skins/Pidgin/MyDetails.msk b/plugins/MyDetails/Docs/Skins/Pidgin/MyDetails.msk new file mode 100644 index 0000000000..89295899f8 --- /dev/null +++ b/plugins/MyDetails/Docs/Skins/Pidgin/MyDetails.msk @@ -0,0 +1,59 @@ +function configure()
 +{
 +	// Default fonts
 +	
 +	status_msg.font.face = "Tahoma"
 +	status_msg.font.size = 8
 +	status_msg.font.color = RGB(0,0,0)
 +}
 +
 +function draw()
 +{
 +	if (status_msg.text == "")
 +		status_msg.text = status_name.text
 +
 +	// ToolTips
 +	status_icon.toolTip = protocol.text + " : " + status_name.text
 +	if (info.protocol.locked)
 +		status_icon.toolTip += " (locked)"
 +	if (email.text > 0)
 +		status_icon.toolTip += " [" + email.text + " emails]"
 +	
 +	status_msg.toolTip = status_msg.text	
 +	
 +	// Borders
 +	window.borders = 10
 +	
 +	// Visible
 +	status_msg.visible = true
 +	avatar.visible = true
 +	status_icon.visible = true
 +	
 +	status_name.visible = false
 +	protocol.visible = false
 +	nickname.visible = false
 +	prev_proto.visible = next_proto.visible = false
 +	listening_icon.visible = listening.visible = false
 +	email_icon.visible = email.visible = false
 +		
 +	// Space to draw the frame around
 +	var BORDER_SPACE = 2
 +	status_icon.borders = BORDER_SPACE
 +	status_msg.borders = BORDER_SPACE
 +	status_name.borders = BORDER_SPACE
 +	
 +	// Positions
 +	var HEIGHT = 45
 +	
 +	avatar.right = window.right
 +	avatar.top = 0
 +	avatar.width = HEIGHT
 +	avatar.height = HEIGHT
 +	
 +	status_icon.left = 0
 +	status_icon.top = (HEIGHT - status_icon.height) / 2
 +
 +	status_msg.left = status_icon.right + 5
 +	status_msg.top = (HEIGHT - status_msg.height) / 2
 +	status_msg.right = avatar.left - 5
 +}
 diff --git a/plugins/MyDetails/Docs/langpack_MyDetails.txt b/plugins/MyDetails/Docs/langpack_MyDetails.txt new file mode 100644 index 0000000000..01c61de1b4 --- /dev/null +++ b/plugins/MyDetails/Docs/langpack_MyDetails.txt @@ -0,0 +1,85 @@ +; My Details
 +; Author: Pescuma
 +; http://forums.miranda-im.org/showthread.php?t=5643
 +
 +[My Details]
 +
 +; Group in options
 +[Customize]
 +
 +; Options
 +
 +[ General ]
 +[Cycle through protocols every:]
 +[seconds]
 +[RTL]
 +[Auto-resize frame]
 +[Replace Smileys]
 +[Align text to right]
 +[Use contact lest smileys]
 +[Resize Smileys]
 +[Global on avatar]
 +[Global on nickname]
 +[Global on status]
 +[Global on status message]
 +
 +[ Frame Options ]
 +[Top:]
 +[Bottom:]
 +[Left:]
 +[Right:]
 +[Background Color:]
 +
 +[ Avatar ]
 +[Custom size:]
 +[pixels]
 +[Allow it to grow]
 +[Draw border on avatar]
 +[Border Color:]
 +[Round corners of avatars]
 +[Custom corner size:]
 +[Use free space (under avatar) to other texts]
 +
 +[ Protocol ]
 +[Show protocol name]
 +[Show protocol cycle button]
 +
 +
 +; Default values
 +[<no nickname>]
 +[<no status name>]
 +
 +
 +; Without multiwindows
 +[Show My Details]
 +[Hide My Details]
 +
 +
 +; Menus
 +[Set My Avatar...]
 +[Set My Nickname...]
 +[Set My Status Message...]
 +[Set My Avatar for %s...]
 +[Set My Nickname for %s...]
 +[Set My Status Message for %s...]
 +[Show next protocol]
 +[Show previous protocol]
 +[Cycle through protocols]
 +[Don't cycle through protocols]
 +
 +
 +; Dialogs
 +[Set My Nickname]
 +[Set My Nickname for %s]
 +[Nickname:]
 +
 +[Set My Status Message for All Status]
 +[Set My Status Message for %s]
 +[Status Message:]
 +
 +[OK]
 +[Cancel]
 +
 +; Clist Modern BAckground
 +[Main Window/Backgrnd]
 +[MyDetails/Backgrnd]
 diff --git a/plugins/MyDetails/Docs/mydetails.gif b/plugins/MyDetails/Docs/mydetails.gif Binary files differnew file mode 100644 index 0000000000..8e4d04e583 --- /dev/null +++ b/plugins/MyDetails/Docs/mydetails.gif diff --git a/plugins/MyDetails/Docs/mydetails_changelog.txt b/plugins/MyDetails/Docs/mydetails_changelog.txt new file mode 100644 index 0000000000..011a1c63b3 --- /dev/null +++ b/plugins/MyDetails/Docs/mydetails_changelog.txt @@ -0,0 +1,228 @@ +My Details
 +
 +Changelog:
 +
 +. 0.0.2.6
 +  + Added support for clist modern skin engine
 +  + Added pidgin style skin
 +  * Fix for last shown protocol
 +  * Updated updater to use googlecode
 +
 +. 0.0.2.5
 +  + Use account name and ordering
 +  * Better handling status messages
 +  * Fix for jabber status names
 +  * Bug fixes
 +
 +. 0.0.2.3
 +  * Moved background color to font service settings
 +  + Better simple away support
 +
 +. 0.0.2.2
 +  * Fix for email count
 +  * Better handling of hover
 +  * Better handling of small sizes
 +  * If fixed avatar size is set, use it even if no avatar present
 +  + If windows uses RTL, it is selected by default
 +
 +. 0.0.2.1
 +  + Show lock icon over status
 +  + Show unread mail count
 +  * Resize frame is working again
 +  * Still work in progress
 +
 +. 0.0.2.0
 +  + Now uses skins plugin to position elements (work in progress)
 +
 +. 0.0.1.11
 +  * Fix for arrows: always draw then at right side
 +
 +. 0.0.1.10
 +  + Added arrows to change protocols (Drugwash patch)
 +  * Use icolib to show icons (uses listening to icon from contact list)
 +
 +. 0.0.1.9
 +  + Created 2 services: MyDetails/HideFrame and MyDetails/ShowFrame
 +  * MyDetails/ShowHideMyDetails changed to work with frames too (it toggles the frame)
 +
 +. 0.0.1.8
 +  * Fix for crash when using main menu options
 +
 +. 0.0.1.7
 +  * Fix for crash when no protocol found
 +  + Added 2 keys to allow themes to show/hide frame: MyDetails\ForceHideFrame and MyDetails\ForceShowFrame (BYTE). Both are deleted after use.
 +
 +. 0.0.1.6
 +  + Added uid for 0.8
 +
 +. 0.0.1.5:
 +  + Added option to set status message per protocol
 +
 +. 0.0.1.4
 +  * Fixed crash on protocol connection
 +  + Support for new version of ersatz
 +
 +. 0.0.1.3
 +  + Support for ersatz plugin by TioDuke. When it is finished, status message will be shown correctly always :)
 +
 +. 0.0.1.2
 +  + Added listening to info
 +
 +. 0.0.1.1
 +  * Fix for crash on exit (thanks ghazan)
 +  - Removed clist modern mod support
 +
 +. 0.0.1.0
 +  * Fix in call to NAS service
 +  + Ready to FL
 +
 +. 0.0.0.42
 +  * Fixed code to open only one dialog
 +  + CTRL-Enter on status message dialog
 +
 +. 0.0.0.41
 +  + Added support to new NAS services
 +  + Open only one dialog (for dialogs that t handles - does not include NAS / avs)
 +  * Bigger buffer for status messages
 +  + First release build (dll is 200k smaller)
 +
 +. 0.0.0.40
 +  * Changed text [Top: ] to [Top:]
 +  + Added langpack_MyDetails.txt
 +
 +. 0.0.0.39
 +  * Reverted to show menus on key up
 +  + Using miranda lists now. This version only works with newer versions of miranda
 +  * Fixed call to NAS with parsed variables
 +
 +. 0.0.0.38
 +  * Fix for international languages
 +  + Translateble options dialog
 +  + Show some menus on key down (but it still not work as desired, i'll have to figure it)
 +
 +. 0.0.0.37
 +  * Bugfix in status menu
 +  + Better support for updater
 +
 +. 0.0.0.36
 +  + Change to better support NAS
 +  + Change to know when info changed (may flick a little less the screen and the tooltip, but may be losing changes)
 +
 +. 0.0.0.35
 +  + Try to discover the default nick
 +  + Global on avatar
 +  * Fixed order of fields in options dialog
 +
 +. 0.0.0.34
 +  * Fixed issue with mTooltip
 +  + Changed tooltip timeout to 10h (is it long enougth? :P )
 +
 +. 0.0.0.33
 +  + Added timer to refresh status messages. It isnt in options dialog, but can be changed at DB, in key MyDetails\RefreshStatusMessageTimer (0 disables it, default to 12 s)
 +  * Fixed input box in set my nickname
 +
 +. 0.0.0.32
 +  * Fix for crash on startup
 +  * Fix for drawing function
 +
 +. 0.0.0.31
 +  * Fix for status message with NAS
 +
 +. 0.0.0.30
 +  * Try to fix bug when setting name (Again)
 +  * Fix for multi line in status message and nickname
 +  + Setting to call global functions on left click
 +  + Calling service to get max nickname length from protocol (no proto support it right now)
 +
 +. 0.0.0.29
 +  * Fix in status message code
 +
 +. 0.0.0.28
 +  + Multiline popup
 +  + More options in context menu
 +  * Try to fix bug when setting name
 +
 +. 0.0.0.27
 +  + Better support for core away system (it set the message in the DB, inside SRAway module)
 +
 +. 0.0.0.26
 +  + Added tooltips
 +  + Added background collor
 +  + Added XStatus support
 +  + Added in the zip: avatar service (unicode and non-unicode) and folder service
 +
 +. 0.0.0.25
 +  + Added support to set avatars (needs modified version of avatar service - is inside zip)
 +  + Added in the zip: avatar service and folder service
 +
 +. 0.0.0.23
 +  * Bugfix in new status menu code
 +
 +. 0.0.0.22
 +  + Using clist status menus when possible (this should add support to all away system always)
 +  + Show global status menu on right click
 +  * Fixed space in status
 +
 +. 0.0.0.21
 +  * Bugfixes
 +
 +. 0.0.0.20
 +  + Compatibility with KeepStatus -> code is too ugly :'(
 +  + Show status messages only for supported statuses
 +  + Show SimpleAway dialog only to supported protocols
 +
 +. 0.0.0.19
 +  + Better support to SimpleAway
 +  + Set what protocol to show by clicking in proto name
 +  * Bug fixes
 +
 +. 0.0.0.18
 +  + Set status message after status change (should work with gadu-gadu, but it isn't the best solution at all)
 +
 +. 0.0.0.17
 +  + Popups with more actions
 +  + Option to grow avatar
 +  + An attempt to set status messages withou NAS
 +
 +. 0.0.0.16
 +  * Fixed leak of GDI objects
 +  * Fixed resizing of avatar
 +
 +. 0.0.0.15
 +  * Bug fixes
 +
 +. 0.0.0.14
 +  + Resize frame
 +  + Use space bellow avatar
 +
 +. 0.0.0.13
 +  - Change to try to get more updates from status message changes
 +  * Fix in avatar refresh
 +
 +. 0.0.0.12
 +  * Updater works
 +  * Fix drawing protocol name
 +
 +. 0.0.0.11
 +  * Fixed bug on drawing status name
 +  + Added custom avatar size
 +  + Will not cicle when changing status
 +
 +. 0.0.0.9
 +  * Fixed crash on Set My Nickname from status menu
 +  + Added cache to data (should draw faster, but have to see if the data shown is correct)
 +  + Added visual things
 +  + Option to set status
 +  - Changed to set things with left click of mouse
 +
 +. 0.0.0.7
 +  * Fix in NAS fetching code (again)
 +
 +. 0.0.0.6
 +  * Fix in NAS fetching code
 +  + RTL
 +  + Smileys
 +
 +. 0.0.0.5
 +  + Added option dialog
 +  + Added option to not cicle throught protocols
\ No newline at end of file diff --git a/plugins/MyDetails/Docs/mydetails_readme.txt b/plugins/MyDetails/Docs/mydetails_readme.txt new file mode 100644 index 0000000000..c9e58d0136 --- /dev/null +++ b/plugins/MyDetails/Docs/mydetails_readme.txt @@ -0,0 +1,41 @@ +My Details plugin
 +-----------------
 +
 +What it does:
 +- Show your current configuration, per protocol, for avatar, nickname, status and away message
 +- It shows each protocol at a time, cicling throught then
 +- Allows to set nickname (per protocol or for all protocols) and away messages (per protocol or for all protocols - need NewAwaySystem, SimpleAway or core module)
 +
 +Some comments:
 +1. SimpleAway does not show a dialog to set a message for all protocols. Someones it does not show the dialog (I requested it in the thread http://forums.miranda-im.org/showthread.php?p=47157).
 +2. For core away system, only some protocols works (probabily the same as SimpleAway). But for the ones that it works, the message in the frame is the old message. I know, it sucks... But if you use ersatz plugin this problem doesn't happen: http://pescuma.mirandaim.ru/miranda/ersatz.zip
 +
 +To request support to other away system: If someone wants to use another away system, please request in its thread to add support for 2 services:
 +1. Get current status message for a protocol, given its name
 +2. Set current status message for a protocol, given its name and the message
 +
 +
 +To use skin engine of clist modern: the following glyphs are used:
 +- MyDetails,ID=Background : background of frame
 +- MyDetails,ID=MouseOver : base mouse over background (for all fields)
 +- MyDetails,ID=MouseOverNick : base mouse over background for nick (drawn over the base one)
 +- MyDetails,ID=MouseOverProto : base mouse over background for protocol (drawn over the base one)
 +- MyDetails,ID=MouseOverStatus : base mouse over status name/icon for nick (drawn over the base one)
 +- MyDetails,ID=MouseOverStatusMsg : base mouse over background for status message (drawn over the base one)
 +- MyDetails,ID=MouseOverListening : base mouse over background for listening info (drawn over the base one)
 +
 +To report bugs/make suggestions, go to the forum thread: http://forums.miranda-im.org/showthread.php?t=5643
 +
 +Dependencies:
 +- If you want integration with clist, an frame enabled clist, such as clist_modern or clist_nicer+
 +- Away systens supported: Core, NewAwaySystem or SimpleAway
 +
 +Todo:
 +- Global page
 +- Add custom presets
 +- Resize on mouse hover
 +- clist_modern_layered integration -> try this: http://forums.miranda-im.org/showthread.php?t=6597
 +- New drawing code (please, do not request things like order of items or spacing, it is in TODO list, but will take time to be made)
 +- Options to XStatus setup
 +- Icons instead of ... on mouse over
 +- Options to show/hide itens
 diff --git a/plugins/MyDetails/Docs/mydetails_version.txt b/plugins/MyDetails/Docs/mydetails_version.txt new file mode 100644 index 0000000000..e078af1e48 --- /dev/null +++ b/plugins/MyDetails/Docs/mydetails_version.txt @@ -0,0 +1 @@ +My Details 0.0.2.6
\ No newline at end of file diff --git a/plugins/MyDetails/commons.h b/plugins/MyDetails/commons.h new file mode 100644 index 0000000000..ca1849c826 --- /dev/null +++ b/plugins/MyDetails/commons.h @@ -0,0 +1,148 @@ +/* 
 +Copyright (C) 2005 Ricardo Pescuma Domenecci
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt.  If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA.  
 +*/
 +
 +
 +#ifndef __COMMONS_H__
 +# define __COMMONS_H__
 +
 +
 +#define _WIN32_WINNT 0x0501
 +#include <windows.h>
 +#include <win2k.h>
 +#include <commctrl.h>
 +#include <stdio.h>
 +#include <vector>
 +
 +#define MIRANDA_VER 0x800
 +#include <newpluginapi.h>
 +#include <m_clist.h>
 +#include <m_skin.h>
 +#include <m_system.h>
 +#include <m_protocols.h>
 +#include <m_protosvc.h>
 +#include <m_database.h>
 +#include <m_utils.h>
 +#include <m_langpack.h>
 +#include <m_awaymsg.h>
 +#include <m_contacts.h>
 +#include <m_options.h>
 +#include <m_clui.h>
 +#include <m_clc.h>
 +#include <m_proto_listeningto.h>
 +#include <m_listeningto.h>
 +
 +#include <m_NewAwaySys.h>
 +#include <m_updater.h>
 +#include <m_fontservice.h>
 +#include <m_variables.h>
 +#include <m_avatars.h>
 +#include <m_statusplugins.h>
 +#include <m_ersatz.h>
 +#include <m_icq.h>
 +#include <m_icolib.h>
 +#include "m_cluiframes.h"
 +#include "m_simpleaway.h"
 +
 +#include <richedit.h>
 +#include <m_smileyadd.h>
 +
 +#include <io.h>
 +
 +#include "../skins/m_skins_cpp.h"
 +
 +#include "resource.h"
 +
 +
 +#define MODULE_NAME "MyDetails"
 +
 +#define SETTING_FRAME_VISIBLE "FrameVisible"
 +#define SETTING_DEFAULT_NICK "DefaultNick"
 +
 +
 +extern HINSTANCE hInst;
 +extern PLUGINLINK *pluginLink;
 +
 +extern long nickname_dialog_open;
 +extern long status_msg_dialog_open;
 +
 +extern SkinDialog *dialog;
 +
 +
 +#include "m_mydetails.h"
 +#include "data.h"
 +#include "options.h"
 +#include "frame.h"
 +#include "../utils/mir_smileys.h"
 +#include "../utils/mir_memory.h"
 +#include "../utils/mir_options.h"
 +#include "../utils/mir_icons.h"
 +#include "../utils/tstring.h"
 +
 +
 +#define PS_SETMYAVATAR "/SetMyAvatar"
 +#define PS_GETMYAVATAR "/GetMyAvatar"
 +#define PS_GETMYAVATARMAXSIZE "/GetMyAvatarMaxSize"
 +#define PS_GETUNREADEMAILCOUNT "/GetUnreadEmailCount"
 +
 +#define PS_SETMYNICKNAME "/SetNickname"
 +
 +#define PS_GETMYNICKNAMEMAXLENGTH "/GetMyNicknameMaxLength"
 +
 +#define WAYD_UNICODE 1        // return Unicode texts
 +#if defined( _UNICODE )
 +	#define WAYD_TCHAR WAYD_UNICODE
 +#else
 +	#define WAYD_TCHAR 0
 +#endif
 +
 +// Get the max length that a WAYD message can have
 +// wParam=(WPARAM)0
 +// lParam=(LPARAM)0
 +// Returns the max length
 +#define PS_GET_MY_WAYD_MAXLENGTH "/GetMyWAYDMaxLength"
 +
 +// Get the WAYD message for the user
 +// wParam=(WPARAM)WAYD_xxx
 +// lParam=(LPARAM)0
 +// Returns the text or NULL if there is none. Remember to mir_free the return value.
 +#define PS_GET_MY_WAYD "/GetMyWAYD"
 +
 +// Sets the WAYD message for the user
 +// wParam=(WPARAM)WAYD_xxx
 +// lParam=(LPARAM)(WCHAR * or char *)The text to set
 +// Returns 0 on success, nonzero on failure
 +#define PS_SET_MY_WAYD "/SetMyWAYD"
 +
 +#define MAX_REGS(_A_) ( sizeof(_A_) / sizeof(_A_[0]) )
 +
 +
 +// See if a protocol service exists
 +__inline static int ProtoServiceExists(const char *szModule,const char *szService)
 +{
 +	char str[MAXMODULELABELLENGTH];
 +	strcpy(str,szModule);
 +	strcat(str,szService);
 +	return ServiceExists(str);
 +}
 +
 +
 +
 +
 +
 +#endif // __COMMONS_H__
 diff --git a/plugins/MyDetails/data.cpp b/plugins/MyDetails/data.cpp new file mode 100644 index 0000000000..eccd72e0e7 --- /dev/null +++ b/plugins/MyDetails/data.cpp @@ -0,0 +1,1063 @@ +/* 
 +Copyright (C) 2005 Ricardo Pescuma Domenecci
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt.  If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA.  
 +*/
 +
 +
 +#include "commons.h"
 +#include "data.h"
 +#include <algorithm>
 +
 +
 +static char *StatusModeToDbSetting(int status,const char *suffix);
 +
 +
 +static bool IsValid(const char *proto)
 +{
 +	if (proto == NULL || proto[0] == 0)
 +		return false;
 +
 +	int caps = CallProtoService(proto, PS_GETCAPS, PFLAGNUM_1, 0);
 +	return (caps & PF1_IM) == PF1_IM && strcmp(proto, "MetaContacts") != 0;
 +}
 +
 +static bool AccOrderComp(PROTOACCOUNT *p1, PROTOACCOUNT *p2)
 +{
 +	return p1->iOrder < p2->iOrder;
 +}
 +
 +static void GetAccounts(std::vector<PROTOACCOUNT *> *result)
 +{
 +	int count;
 +	PROTOACCOUNT **protos;
 +	ProtoEnumAccounts(&count, &protos);
 +	
 +	for (int i = 0; i < count; i++)
 +	{
 +		if (protos[i]->type != PROTOTYPE_PROTOCOL)
 +			continue;
 +		
 +		if (!IsAccountEnabled(protos[i]))
 +			continue;
 +		
 +		if (!IsValid(protos[i]->szModuleName))
 +			continue;
 +		
 +		result->push_back(protos[i]);
 +	}
 +	
 +	std::sort(result->begin(), result->begin(), AccOrderComp);
 +}
 +
 +
 +void GetProtocols(std::vector<Protocol> *result)
 +{
 +	std::vector<PROTOACCOUNT *> accs;
 +	GetAccounts(&accs);
 +
 +	unsigned int accsSize = accs.size();
 +	for (unsigned int i = 0; i < accsSize ; ++i)
 +		result->push_back(Protocol(accs[i]->szModuleName));
 +}
 +
 +
 +int GetProtocolIndexByName(const char *moduleName)
 +{
 +	std::vector<PROTOACCOUNT *> protos;
 +	GetAccounts(&protos);
 +
 +	int protosSize = (int) protos.size();
 +	for(int i = 0; i < protosSize; ++i)
 +	{
 +		if (strcmp(protos[i]->szModuleName, moduleName) == 0)
 +			return i;
 +	}
 +
 +	return -1;
 +}
 +
 +
 +int GetNumProtocols()
 +{
 +	std::vector<PROTOACCOUNT *> protos;
 +	GetAccounts(&protos);
 +	return protos.size();
 +}
 +
 +
 +struct ProtoCache
 +{
 +	Protocol *proto;
 +	int index;
 +
 +	void Free()
 +	{
 +		delete proto;
 +		proto = NULL;
 +		index = -1;
 +	}
 +};
 +
 +static ProtoCache current = { NULL, -1 };
 +
 +
 +void SetCurrentProtocol(int index)
 +{
 +	current.Free();
 +	
 +	int protosSize = GetNumProtocols();
 +	if (protosSize > 0)
 +		current.index = (index % protosSize + protosSize) % protosSize;
 +
 +	DBWriteContactSettingWord(NULL, "MyDetails", "ProtocolNumber", current.index);
 +}
 +
 +Protocol * GetCurrentProtocol(bool createIfDontExist)
 +{
 +	if (createIfDontExist && current.index >= 0 && current.proto == NULL)
 +	{
 +		std::vector<PROTOACCOUNT *> protos;
 +		GetAccounts(&protos);
 +
 +		int protosSize = protos.size();
 +		if (current.index >= protosSize)
 +		{
 +			current.index = -1;
 +			return NULL;
 +		}
 +
 +		current.proto = new Protocol(protos[current.index]->szModuleName);
 +	}
 +	
 +	return current.proto;	
 +}
 +
 +int GetCurrentProtocolIndex()
 +{
 +	return current.index;
 +}
 +
 +
 +Protocol GetProtocolByIndex(int index)
 +{
 +	std::vector<PROTOACCOUNT *> protos;
 +	GetAccounts(&protos);
 +	int protosSize = protos.size();
 +	
 +	if (protosSize < 1)
 +		return Protocol(NULL);
 +	
 +	index = (index % protosSize + protosSize) % protosSize;
 +	return Protocol(protos[index]->szModuleName);
 +}
 +
 +
 +Protocol GetProtocolByName(const char *moduleName)
 +{
 +	std::vector<PROTOACCOUNT *> protos;
 +	GetAccounts(&protos);
 +	
 +	int protosSize = (int) protos.size();
 +	for(int i = 0; i < protosSize; ++i)
 +	{
 +		if (strcmp(protos[i]->szModuleName, moduleName) == 0)
 +			return Protocol(protos[i]->szModuleName);
 +	}
 +	
 +	return Protocol(NULL);
 +}
 +
 +
 +ProtocolArray *protocols = NULL;
 +
 +
 +void InitProtocolData()
 +{
 +	protocols = new ProtocolArray();
 +}
 +
 +
 +void DeInitProtocolData()
 +{
 +	current.Free();
 +
 +	delete protocols;
 +	protocols = NULL;
 +}
 +
 +
 +// Protocol Class ///////////////////////////////////////////////////////////////////////////////////////////
 +
 +
 +Protocol::Protocol(const char *aName)
 +{
 +	if (aName)
 +		name = aName;
 +
 +	avatar_bmp = NULL;
 +	status = 0;
 +	custom_status = 0;
 +	locked = false;
 +	emails = 0;
 +	
 +	// Initial value
 +	UpdateAll();
 +}
 +
 +Protocol::~Protocol()
 +{
 +}
 +
 +
 +bool Protocol::IsValid()
 +{
 +	return !name.empty();
 +}
 +
 +
 +Protocol::operator bool ()
 +{
 +	return IsValid();
 +}
 +
 +
 +void Protocol::UpdateAll()
 +{
 +	status_initialized = false;
 +	status_message_initialized = false;
 +	nickname_initialized = false;
 +	avatar_initialized = false;
 +	locked_initialized = false;
 +	emails_initialized = false;
 +	listening_to_initialized = false;
 +}
 +
 +
 +int Protocol::Call(const char *service, WPARAM wParam, LPARAM lParam)
 +{
 +	return CallProtoService(name.c_str(), service, wParam, lParam);
 +}
 +
 +
 +bool Protocol::CanCall(const char *service)
 +{
 +	return ProtoServiceExists(name.c_str(), service) != 0;
 +}
 +
 +
 +std::string Protocol::GetDBSettingString(const char *key, const char *def)
 +{
 +	std::string result = def;
 +
 +	DBVARIANT dbv;
 +	if (!DBGetContactSettingTString(0, name.c_str(), key, &dbv))
 +	{
 +		if (dbv.ptszVal != NULL && dbv.ptszVal[0] != 0)
 +			result = dbv.ptszVal;
 +		
 +		DBFreeVariant(&dbv);
 +	}
 +
 +	return result;
 +}
 +
 +
 +const char * Protocol::GetName()
 +{
 +	return name.c_str();
 +}
 +
 +
 +const char * Protocol::GetDescription()
 +{
 +	if (description.empty())
 +	{
 +		PROTOACCOUNT *acc = ProtoGetAccount(name.c_str());
 +
 +		if (acc == NULL || acc->tszAccountName == NULL || acc->tszAccountName[0] == 0)
 +		{
 +			char tmp[1024];
 +			Call(PS_GETNAME, sizeof(tmp), (LPARAM) tmp);
 +			description = tmp;
 +		}
 +		else
 +		{
 +			if (mir_is_unicode())
 +			{
 +				char *tmp = mir_u2a((const wchar_t *) acc->tszAccountName);
 +				description = tmp;
 +				mir_free(tmp);
 +			}
 +			else
 +			{
 +				description = acc->tszAccountName;
 +			}
 +		}
 +	}
 +
 +	return description.c_str();
 +}
 +
 +void Protocol::UpdateStatus()
 +{
 +	status_initialized = true;
 +
 +	status = Call(PS_GETSTATUS);
 +
 +	if (status > ID_STATUS_OFFLINE && CanCall(PS_ICQ_GETCUSTOMSTATUS))
 +	{
 +		char *name_key = NULL;
 +		char *message_key = NULL;
 +
 +		custom_status = Call(PS_ICQ_GETCUSTOMSTATUS, (WPARAM) &name_key, (LPARAM) &message_key);
 +
 +		// Fix fo jabber, that returns 0xbaadf00d here
 +		if (custom_status < 0)
 +			custom_status = 0;
 +
 +		custom_status_name_key = (name_key ? name_key : "");
 +		custom_status_message_key = (message_key ? message_key : "");
 +	}
 +	else
 +	{
 +		custom_status = 0;
 +		custom_status_name_key = "";
 +		custom_status_message_key = "";
 +	}
 +
 +	if (custom_status == 0)
 +	{
 +		status_name = (char *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, status, GCMDF_TCHAR);
 +	}
 +	else
 +	{
 +		status_name = "";
 +
 +		if (!custom_status_name_key.empty())
 +			status_name = GetDBSettingString(custom_status_name_key.c_str());
 +
 +		if (!custom_status_message_key.empty())
 +		{
 +			std::string tmp = GetDBSettingString(custom_status_message_key.c_str());
 +			if (!tmp.empty())
 +			{
 +				status_name += ": ";
 +				status_name += tmp;
 +			}
 +		}
 +	}
 +	
 +	if (status_name.empty())
 +		status_name = TranslateTS("<no status name>");
 +}
 +
 +const char * Protocol::GetStatusName()
 +{
 +	if (!status_initialized)
 +		UpdateStatus();
 +
 +	return status_name.c_str();
 +}
 +
 +const char * Protocol::GetCustomStatusNameKey()
 +{
 +	if (!status_initialized)
 +		UpdateStatus();
 +	
 +	return custom_status_name_key.c_str();
 +}
 +
 +const char * Protocol::GetCustomStatusMessageKey()
 +{
 +	if (!status_initialized)
 +		UpdateStatus();
 +	
 +	return custom_status_message_key.c_str();
 +}
 +
 +int Protocol::GetStatus()
 +{
 +	if (!status_initialized)
 +		UpdateStatus();
 +	
 +	return status;
 +}
 +
 +int Protocol::GetCustomStatus()
 +{
 +	if (!status_initialized)
 +		UpdateStatus();
 +	
 +	return custom_status;
 +}
 +
 +
 +void Protocol::SetStatus(int aStatus)
 +{
 +	char status_msg[256];
 +
 +	if (ServiceExists(MS_CS_SETSTATUSEX))
 +	{
 +		// :'(
 +
 +		// BEGIN From commomstatus.cpp (KeepStatus)
 +		int i, count, pCount;
 +		PROTOCOLDESCRIPTOR **protos;
 +
 +		pCount = 0;
 +		CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&count,(LPARAM)&protos);
 +		for(i=0;i<count;i++) {
 +			if(protos[i]->type!=PROTOTYPE_PROTOCOL || CallProtoService(protos[i]->szName,PS_GETCAPS,PFLAGNUM_2,0)==0) continue;
 +			pCount += 1;
 +		}
 +		// END From commomstatus.cpp (KeepStatus)
 +
 +
 +		PROTOCOLSETTINGEX **pse = (PROTOCOLSETTINGEX **) mir_alloc0(pCount * sizeof(PROTOCOLSETTINGEX *));
 +
 +		for(i = 0; i < pCount; i++)
 +		{
 +			pse[i] = (PROTOCOLSETTINGEX *) mir_alloc0(sizeof(PROTOCOLSETTINGEX));
 +			pse[i]->szName = "";
 +		}
 +
 +		pse[0]->cbSize = sizeof(PROTOCOLSETTINGEX);
 +		pse[0]->status = aStatus;
 +		pse[0]->szName = (char *) name.c_str();
 +
 +		GetStatusMsg(aStatus, status_msg, sizeof(status_msg));
 +		pse[0]->szMsg = status_msg;
 +
 +		CallService(MS_CS_SETSTATUSEX, (WPARAM) &pse, 0);
 +
 +		for(i = 0; i < pCount; i++)
 +			mir_free(pse[i]);
 +		mir_free(pse);
 +	}
 +	else
 +	{
 +		Call(PS_SETSTATUS, aStatus);
 +
 +		if (CanSetStatusMsg(aStatus))
 +		{
 +			char status_msg[MS_MYDETAILS_GETMYSTATUSMESSAGE_BUFFER_SIZE];
 +			GetStatusMsg(aStatus, status_msg, sizeof(status_msg));
 +			SetStatusMsg(aStatus, status_msg);
 +		}
 +	}
 +}
 +
 +
 +bool Protocol::CanGetStatusMsg()
 +{
 +	return CanGetStatusMsg(GetStatus());
 +}
 +
 +bool Protocol::CanGetStatusMsg(int aStatus)
 +{
 +	return (Call(PS_GETCAPS, PFLAGNUM_1) & PF1_MODEMSGSEND) != 0 
 +			&& (Call(PS_GETCAPS, (WPARAM)PFLAGNUM_3) & Proto_Status2Flag(aStatus));
 +}
 +
 +
 +bool Protocol::CanSetStatusMsg()
 +{
 +	return CanSetStatusMsg(GetStatus()) // <- Simple away handled by this one
 +			|| ServiceExists(MS_NAS_INVOKESTATUSWINDOW);
 +
 +}
 +
 +bool Protocol::CanSetStatusMsg(int aStatus)
 +{
 +	return CanGetStatusMsg(aStatus);
 +}
 +
 +void Protocol::GetStatusMsg(int aStatus, char *msg, size_t msg_size)
 +{
 +	if (!CanGetStatusMsg())
 +	{
 +		lstrcpyn(msg, "", msg_size);
 +		return;
 +	}
 +
 +	bool isCurrentStatus = (aStatus == GetStatus());
 +
 +	if (isCurrentStatus && CanCall(PS_GETMYAWAYMSG))
 +	{
 +		char *tmp = (char *) Call(PS_GETMYAWAYMSG);
 +		lstrcpyn(msg, tmp == NULL ? "" : tmp, msg_size);
 +	}
 +	else if (isCurrentStatus && ServiceExists(MS_SA_ISSARUNNING) && CallService(MS_SA_ISSARUNNING, 0, 0)) 
 +	{
 +		char *tmp = (char *) CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) ID_STATUS_CURRENT, (LPARAM) name.c_str());
 +
 +		if (tmp != NULL)
 +		{
 +			lstrcpyn(msg, tmp, msg_size);
 +			mir_free(tmp);
 +		}
 +		else lstrcpyn(msg, "", msg_size);
 +		
 +	}
 +	else if (ServiceExists(MS_NAS_GETSTATE))
 +	{
 +		NAS_PROTOINFO pi;
 +
 +		ZeroMemory(&pi, sizeof(pi));
 +		pi.cbSize = sizeof(NAS_PROTOINFO);
 +		pi.szProto = (char *) name.c_str();
 +		pi.status = (isCurrentStatus ? 0 : aStatus);
 +		pi.szMsg = NULL;
 +
 +		if (CallService(MS_NAS_GETSTATE, (WPARAM) &pi, 1) == 0)
 +		{
 +			if (pi.szMsg == NULL)
 +			{
 +				pi.szProto = NULL;
 +
 +				if (CallService(MS_NAS_GETSTATE, (WPARAM) &pi, 1) == 0)
 +				{
 +					if (pi.szMsg != NULL)
 +					{
 +						lstrcpyn(msg, pi.szMsg, msg_size);
 +						mir_free(pi.szMsg);
 +					}
 +					else lstrcpyn(msg, "", msg_size);
 +				}
 +				else lstrcpyn(msg, "", msg_size);
 +			}
 +			else // if (pi.szMsg != NULL)
 +			{
 +				lstrcpyn(msg, pi.szMsg, msg_size);
 +				mir_free(pi.szMsg);
 +			}
 +		}
 +		else lstrcpyn(msg, "", msg_size);
 +
 +		if (ServiceExists(MS_VARS_FORMATSTRING))
 +		{
 +			char *tmp = variables_parse(msg, NULL, NULL);
 +			lstrcpyn(msg, tmp, msg_size);
 +			variables_free(tmp);
 +		}
 +	}
 +	// TODO: Remove when removing old NAS services support
 +	else if (ServiceExists("NewAwaySystem/GetState"))
 +	{
 +		NAS_PROTOINFO pi, *pii;
 +
 +		ZeroMemory(&pi, sizeof(pi));
 +		pi.cbSize = sizeof(NAS_PROTOINFO);
 +		pi.szProto = (char *) name.c_str();
 +		pi.status = (isCurrentStatus ? 0 : aStatus);
 +		pi.szMsg = NULL;
 +
 +		pii = π
 +
 +		if (CallService("NewAwaySystem/GetState", (WPARAM) &pii, 1) == 0)
 +		{
 +			if (pi.szMsg == NULL)
 +			{
 +				pi.szProto = NULL;
 +
 +				if (CallService("NewAwaySystem/GetState", (WPARAM) &pii, 1) == 0)
 +				{
 +					if (pi.szMsg != NULL)
 +					{
 +						lstrcpyn(msg, pi.szMsg, msg_size);
 +						mir_free(pi.szMsg);
 +					}
 +					else lstrcpyn(msg, "", msg_size);
 +				}
 +				else lstrcpyn(msg, "", msg_size);
 +			}
 +			else // if (pi.szMsg != NULL)
 +			{
 +				lstrcpyn(msg, pi.szMsg, msg_size);
 +				mir_free(pi.szMsg);
 +			}
 +		}
 +		else lstrcpyn(msg, "", msg_size);
 +
 +		if (ServiceExists(MS_VARS_FORMATSTRING))
 +		{
 +			char *tmp = variables_parse(msg, NULL, NULL);
 +			lstrcpyn(msg, tmp, msg_size);
 +			variables_free(tmp);
 +		}
 +	}
 +	else if (ServiceExists(MS_AWAYMSG_GETSTATUSMSG))
 +	{
 +		char *tmp = (char *) CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM)aStatus, 0);
 +
 +		if (tmp != NULL)
 +		{
 +			lstrcpyn(msg, tmp, msg_size);
 +			mir_free(tmp);
 +		}
 +		else lstrcpyn(msg, "", msg_size);
 +	}
 +}
 +
 +void Protocol::UpdateStatusMsg()
 +{
 +	status_message_initialized = true;
 +
 +	TCHAR tmp[1024];
 +	GetStatusMsg(GetStatus(), tmp, sizeof(tmp));
 +
 +	status_message = tmp;
 +}
 +
 +const char * Protocol::GetStatusMsg()
 +{
 +	if (!status_message_initialized)
 +		UpdateStatusMsg();
 +
 +	return status_message.c_str();
 +}
 +
 +void Protocol::SetStatusMsg(const char *message)
 +{
 +	SetStatusMsg(GetStatus(), message);
 +}
 +
 +void Protocol::SetStatusMsg(int aStatus, const char *message)
 +{
 +	if (!CanSetStatusMsg(aStatus))
 +		return;
 +
 +	if (ServiceExists(MS_NAS_SETSTATE))
 +	{
 +		NAS_PROTOINFO pi = {0}, *pii;
 +
 +		pi.cbSize = sizeof(pi);
 +		pi.szProto = (char *) name.c_str();
 +		pi.szMsg = mir_strdup(message);
 +		pi.status = aStatus;
 +
 +		pii = π
 +
 +		CallService(MS_NAS_SETSTATE, (WPARAM) &pii, 1);
 +	}
 +	else
 +	{
 +		Call(PS_SETAWAYMSG, (WPARAM) aStatus, (LPARAM) message);
 +	}
 +}
 +
 +bool Protocol::HasAvatar()
 +{
 +	if (!avatar_initialized)
 +		UpdateAvatar();
 +
 +	return avatar_bmp != NULL;
 +}
 +
 +bool Protocol::CanGetAvatar()
 +{
 +	int caps = Call(PS_GETCAPS, PFLAGNUM_4);
 +
 +	if ((caps & PF4_AVATARS) == 0)
 +		return false;
 +
 +	if (!ServiceExists(MS_AV_GETMYAVATAR))
 +		return false;
 +
 +	return true;
 +}
 +
 +void Protocol::UpdateAvatar()
 +{
 +	avatar_initialized = true;
 +	avatar_file = "";
 +	avatar_bmp = NULL;
 +	
 +	// See if can get one
 +	if (!CanGetAvatar())
 +		return;
 +
 +	// Get HBITMAP from cache
 +	AVATARCACHEENTRY *ace = (avatarCacheEntry *) CallService(MS_AV_GETMYAVATAR, 0, (LPARAM) name.c_str());
 +	if (ace != NULL)
 +	{
 +		avatar_file = ace->szFilename;
 +		avatar_bmp = ace->hbmPic;
 +	}
 +}
 +
 +const char * Protocol::GetAvatarFile()
 +{
 +	if (!avatar_initialized)
 +		UpdateAvatar();
 +
 +	return avatar_file.c_str();
 +}
 +
 +HBITMAP Protocol::GetAvatarImage()
 +{
 +	if (!avatar_initialized)
 +		UpdateAvatar();
 +	
 +	return avatar_bmp;
 +}
 +
 +
 +bool Protocol::CanGetNick()
 +{
 +	return ServiceExists(MS_CONTACT_GETCONTACTINFO) != FALSE;
 +}
 +
 +int Protocol::GetNickMaxLength()
 +{
 +	if (CanCall(PS_GETMYNICKNAMEMAXLENGTH))
 +	{
 +		int ret = Call(PS_GETMYNICKNAMEMAXLENGTH);
 +		if (ret <= 0)
 +			ret = MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE;
 +		return ret;
 +	}
 +	else
 +		return MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE;
 +}
 +
 +void Protocol::UpdateNick()
 +{
 +	nickname_initialized = true;
 +	nickname = "";
 +
 +	// See if can get one
 +	if (!CanGetNick())
 +		return;
 +
 +	// Get it
 +	CONTACTINFO ci;
 +    ZeroMemory(&ci, sizeof(ci));
 +    ci.cbSize = sizeof(ci);
 +    ci.hContact = NULL;
 +    ci.szProto = (char *) name.c_str();
 +    ci.dwFlag = CNF_DISPLAY;
 +
 +#ifdef UNICODE
 +	ci.dwFlag |= CNF_UNICODE;
 +#endif
 +
 +    if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) 
 +	{
 +        // CNF_DISPLAY always returns a string type
 +        nickname = ci.pszVal;
 +		mir_free(ci.pszVal);
 +    }
 +}
 +
 +const char * Protocol::GetNick()
 +{
 +	if (!nickname_initialized)
 +		UpdateNick();
 +
 +	return nickname.c_str();
 +}
 +
 +
 +bool Protocol::CanSetNick()
 +{
 +	return CanCall(PS_SETMYNICKNAME) != 0;
 +}
 +
 +
 +void Protocol::SetNick(const char *nick)
 +{
 +	// See if can get one
 +	if (!CanSetNick())
 +		return;
 +
 +	if (nick == NULL)
 +		return;
 +
 +	// Get it
 +	Call(PS_SETMYNICKNAME, NULL, (LPARAM) nick);
 +}
 +
 +
 +bool Protocol::CanSetAvatar()
 +{
 +	return ServiceExists(MS_AV_SETMYAVATAR) != FALSE && ServiceExists(MS_AV_CANSETMYAVATAR) != FALSE && 
 +			CallService(MS_AV_CANSETMYAVATAR, (WPARAM) name.c_str(), 0);
 +}
 +
 +void Protocol::SetAvatar(const char *file_name)
 +{
 +	if (!CanSetAvatar())
 +		return;
 +
 +	CallService(MS_AV_SETMYAVATAR, (WPARAM) name.c_str(), (LPARAM) file_name);
 +}
 +
 +bool Protocol::CanGetListeningTo()
 +{
 +	return CanCall(PS_SET_LISTENINGTO) != 0;
 +}
 +
 +bool Protocol::CanSetListeningTo()
 +{
 +	return CanGetListeningTo() && ServiceExists(MS_LISTENINGTO_ENABLE);
 +}
 +
 +bool Protocol::ListeningToEnabled()
 +{
 +	return CanSetListeningTo() && CallService(MS_LISTENINGTO_ENABLED, (WPARAM) name.c_str(), 0) != 0;
 +}
 +
 +void Protocol::UpdateListeningTo()
 +{
 +	listening_to_initialized = true;
 +	listening_to = "";
 +
 +	if (!CanGetListeningTo())
 +		return;
 +
 +	listening_to = GetDBSettingString("ListeningTo");
 +}
 +
 +const char * Protocol::GetListeningTo()
 +{
 +	if (!listening_to_initialized)
 +		UpdateListeningTo();
 +
 +	return listening_to.c_str();
 +}
 +
 +void Protocol::UpdateLocked()
 +{
 +	locked_initialized = true;
 +
 +	locked = (DBGetContactSettingByte(NULL, name.c_str(), "LockMainStatus", 0) != 0);
 +}
 +
 +bool Protocol::IsLocked()
 +{
 +	if (!locked_initialized)
 +		UpdateLocked();
 +
 +	return locked;
 +}
 +
 +bool Protocol::CanGetEmailCount()
 +{
 +	return CanCall(PS_GETUNREADEMAILCOUNT) != 0 
 +		&& GetStatus() > ID_STATUS_OFFLINE;
 +}
 +
 +void Protocol::UpdateEmailCount()
 +{
 +	emails_initialized = true;
 +	
 +	if (!CanGetEmailCount())
 +		emails = 0;
 +	else
 +		emails = max(0, Call(PS_GETUNREADEMAILCOUNT));
 +}
 +
 +int Protocol::GetEmailCount()
 +{
 +	if (!emails_initialized)
 +		UpdateEmailCount();
 +
 +	return emails;
 +}
 +
 +
 +// ProtocolDataArray Class /////////////////////////////////////////////////////////////////////////////
 +
 +
 +ProtocolArray::ProtocolArray()
 +{
 +	GetDefaultNick();
 +	GetDefaultAvatar();
 +}
 +
 +int ProtocolArray::GetGlobalStatus()
 +{
 +	int status = CallService(MS_CLIST_GETSTATUSMODE, 0, 0);
 +	if (status == ID_STATUS_CONNECTING)
 +		status = ID_STATUS_OFFLINE;
 +
 +	return status;
 +}
 +
 +bool ProtocolArray::CanSetAvatars()
 +{
 +	return ServiceExists(MS_AV_SETMYAVATAR) != FALSE;
 +}
 +
 +void ProtocolArray::SetAvatars(const char *file_name)
 +{
 +	if (!CanSetAvatars())
 +		return;
 +
 +	CallService(MS_AV_SETMYAVATAR, NULL, (WPARAM) file_name);
 +}
 +
 +
 +void ProtocolArray::SetNicks(const char *nick)
 +{
 +	if (nick == NULL || nick[0] == '\0')
 +		return;
 +
 +	lstrcpyn(default_nick, nick, sizeof(default_nick));
 +
 +	DBWriteContactSettingString(0, MODULE_NAME, SETTING_DEFAULT_NICK, nick);
 +
 +	std::vector<Protocol> protos;
 +	GetProtocols(&protos);
 +
 +	unsigned int protosSize = protos.size();
 +	for (int i = 0; i < protosSize; ++i)
 +		protos[i].SetNick(default_nick);
 +}
 +
 +
 +void ProtocolArray::SetStatus(int aStatus)
 +{
 +	CallService(MS_CLIST_SETSTATUSMODE, aStatus, 0);
 +}
 +
 +void ProtocolArray::SetStatusMsgs(const char *message)
 +{
 +	for (int i = ID_STATUS_OFFLINE ; i <= ID_STATUS_IDLE; i++)
 +	{
 +		SetStatusMsgs(i, message);
 +	}
 +}
 +
 +void ProtocolArray::SetStatusMsgs(int status, const char *message)
 +{
 +	DBWriteContactSettingString(NULL,"SRAway",StatusModeToDbSetting(status,"Msg"),message);
 +	if (!DBGetContactSettingByte(NULL,"SRAway",StatusModeToDbSetting(status,"UsePrev"),0))
 +	{
 +		// Save default also
 +		DBWriteContactSettingString(NULL,"SRAway",StatusModeToDbSetting(status,"Default"),message);
 +	}
 +	
 +	std::vector<Protocol> protos;
 +	GetProtocols(&protos);
 +	
 +	unsigned int protosSize = protos.size();
 +	for (int i = 0; i < protosSize; ++i)
 +	{
 +		if (protos[i].GetStatus() == status)
 +			protos[i].SetStatusMsg(status, message);
 +	}
 +}
 +
 +
 +void ProtocolArray::GetDefaultNick()
 +{
 +	DBVARIANT dbv;
 +
 +	if (!DBGetContactSettingTString(0, MODULE_NAME, SETTING_DEFAULT_NICK, &dbv))
 +	{
 +		lstrcpyn(default_nick, dbv.pszVal, sizeof(default_nick));
 +		DBFreeVariant(&dbv);
 +	}
 +	else
 +	{
 +		default_nick[0] = '\0';
 +	}
 +}
 +
 +void ProtocolArray::GetDefaultAvatar()
 +{
 +	DBVARIANT dbv;
 +
 +	if (!DBGetContactSettingTString(0, "ContactPhoto", "File", &dbv))
 +	{
 +		lstrcpyn(default_avatar_file, dbv.pszVal, sizeof(default_avatar_file));
 +		DBFreeVariant(&dbv);
 +	}
 +	else
 +	{
 +		default_avatar_file[0] = '\0';
 +	}
 +}
 +
 +char * ProtocolArray::GetDefaultStatusMsg()
 +{
 +	return GetDefaultStatusMsg(CallService(MS_CLIST_GETSTATUSMODE, 0, 0));
 +}
 +
 +char * ProtocolArray::GetDefaultStatusMsg(int status)
 +{
 +	default_status_message[0] = '\0';
 +
 +	if (ServiceExists(MS_AWAYMSG_GETSTATUSMSG))
 +	{
 +		if (status == ID_STATUS_CONNECTING)
 +		{
 +			status = ID_STATUS_OFFLINE;
 +		}
 +
 +		char *tmp = (char *) CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM)status, 0);
 +
 +		if (tmp != NULL)
 +		{
 +			lstrcpyn(default_status_message, tmp, sizeof(default_status_message));
 +			mir_free(tmp);
 +		}
 +	}
 +
 +	return default_status_message;
 +}
 +
 +bool ProtocolArray::CanSetListeningTo()
 +{
 +	return ServiceExists(MS_LISTENINGTO_ENABLE) != 0;
 +}
 +
 +bool ProtocolArray::ListeningToEnabled()
 +{
 +	return CanSetListeningTo() && CallService(MS_LISTENINGTO_ENABLED, 0, 0) != 0;
 +}
 +
 +
 +//////////////////////////////////////////////////////////////////////////////////////////////////////
 +// Helper functions
 +
 +static char *StatusModeToDbSetting(int status,const char *suffix)
 +{
 +    char *prefix;
 +	static char str[64];
 +
 +	switch(status) {
 +		case ID_STATUS_AWAY: prefix="Away";	break;
 +		case ID_STATUS_NA: prefix="Na";	break;
 +		case ID_STATUS_DND: prefix="Dnd"; break;
 +		case ID_STATUS_OCCUPIED: prefix="Occupied"; break;
 +		case ID_STATUS_FREECHAT: prefix="FreeChat"; break;
 +		case ID_STATUS_ONLINE: prefix="On"; break;
 +		case ID_STATUS_OFFLINE: prefix="Off"; break;
 +		case ID_STATUS_INVISIBLE: prefix="Inv"; break;
 +		case ID_STATUS_ONTHEPHONE: prefix="Otp"; break;
 +		case ID_STATUS_OUTTOLUNCH: prefix="Otl"; break;
 +		case ID_STATUS_IDLE: prefix="Idl"; break;
 +		default: return NULL;
 +	}
 +	lstrcpyA(str,prefix); lstrcatA(str,suffix);
 +	return str;
 +}
 +
 +
 diff --git a/plugins/MyDetails/data.h b/plugins/MyDetails/data.h new file mode 100644 index 0000000000..9c458b50dd --- /dev/null +++ b/plugins/MyDetails/data.h @@ -0,0 +1,183 @@ +/* 
 +Copyright (C) 2005 Ricardo Pescuma Domenecci
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt.  If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA.  
 +*/
 +
 +
 +#ifndef __DATA_H__
 +# define __DATA_H__
 +
 +
 +//#include "protocol_config.h"
 +
 +class Protocol
 +{
 +	// Attributes ////////////
 +	std::string name;
 +	
 +	std::string description;
 +
 +	bool avatar_initialized;
 +	std::string avatar_file;
 +	HBITMAP avatar_bmp;
 +
 +	bool status_message_initialized;
 +	std::string status_message;
 +
 +	bool nickname_initialized;
 +	std::string nickname;
 +
 +	bool locked_initialized;
 +	bool locked;
 +
 +	bool emails_initialized;
 +	int emails;
 +
 +	bool listening_to_initialized;
 +	std::string listening_to;
 +
 +	bool status_initialized;
 +	std::string status_name;
 +	std::string custom_status_name_key;
 +	std::string custom_status_message_key;
 +	int status;
 +	int custom_status;
 +
 +public:	
 +	Protocol(const char *name);
 +	~Protocol();
 +
 +	bool IsValid();
 +	operator bool ();
 +
 +	void UpdateAll();
 +
 +	const char * GetName();
 +	const char * GetDescription();
 +
 +	const char * GetStatusName();
 +	const char * GetCustomStatusNameKey();
 +	const char * GetCustomStatusMessageKey();
 +	int GetStatus();
 +	int GetCustomStatus();
 +	void SetStatus(int aStatus);
 +
 +	bool HasAvatar();
 +	bool CanGetAvatar();
 +	const char * GetAvatarFile();
 +	HBITMAP GetAvatarImage();
 +
 +	bool CanSetAvatar();
 +	void SetAvatar(const TCHAR *file_name);
 +
 +	bool CanGetNick();
 +	const char * GetNick();
 +	int GetNickMaxLength();
 +	bool CanSetNick();
 +	void SetNick(const TCHAR *nick);
 +
 +	bool CanGetListeningTo();
 +	bool CanSetListeningTo();
 +	bool ListeningToEnabled();
 +	const char * GetListeningTo();
 +
 +	bool CanGetStatusMsg();
 +	bool CanGetStatusMsg(int aStatus);
 +	void GetStatusMsg(int aStatus, TCHAR *msg, size_t msg_size);
 +	const char * GetStatusMsg();
 +
 +	bool CanSetStatusMsg();
 +	bool CanSetStatusMsg(int aStatus);
 +	void SetStatusMsg(const TCHAR *message);
 +	void SetStatusMsg(int aStatus, const TCHAR *message);
 +
 +	bool IsLocked();
 +
 +	bool CanGetEmailCount();
 +	int GetEmailCount();
 +
 +	int Call(const char *service, WPARAM wParam = 0, LPARAM lParam = 0);
 +	bool CanCall(const char *service);
 +
 +	std::string GetDBSettingString(const char *key, const char *def = "");
 +
 +private:
 +	void UpdateStatus();
 +	void UpdateAvatar();
 +	void UpdateNick();
 +	void UpdateListeningTo();
 +	void UpdateStatusMsg();
 +	void UpdateLocked();
 +	void UpdateEmailCount();
 +};
 +
 +
 +
 +class ProtocolArray
 +{
 +public:
 +	TCHAR default_nick[256];
 +	TCHAR default_avatar_file[256];
 +	TCHAR default_status_message[256];
 +
 +	// Methods ///////////////
 +
 +	ProtocolArray();
 +
 +	bool CanSetAvatars();
 +	void SetAvatars(const TCHAR *file);
 +
 +	void SetNicks(const TCHAR *nick);
 +
 +	void SetStatus(int aStatus);
 +
 +	void SetStatusMsgs(const TCHAR *message);
 +	void SetStatusMsgs(int status, const TCHAR *message);
 +
 +	int GetGlobalStatus();
 +
 +	void GetDefaultNick();	// Copy to cache
 +	void GetDefaultAvatar();	// Copy to cache
 +	TCHAR * GetDefaultStatusMsg();	// Copy to cache
 +	TCHAR * GetDefaultStatusMsg(int status);
 +
 +	bool CanSetListeningTo();
 +	bool ListeningToEnabled();
 +};
 +
 +extern ProtocolArray *protocols;
 +
 +
 +void SetCurrentProtocol(int index);
 +Protocol * GetCurrentProtocol(bool createIfDontExist = true);
 +int GetCurrentProtocolIndex();
 +
 +void GetProtocols(std::vector<Protocol> *result);
 +int GetProtocolIndexByName(const char *moduleName);
 +int GetNumProtocols();
 +Protocol GetProtocolByIndex(int index);
 +Protocol GetProtocolByName(const char *proto);
 +
 +void InitProtocolData();
 +void DeInitProtocolData();
 +
 +
 +
 +
 +
 +
 +#endif // __DATA_H__
 diff --git a/plugins/MyDetails/frame.cpp b/plugins/MyDetails/frame.cpp new file mode 100644 index 0000000000..d5b609a4e9 --- /dev/null +++ b/plugins/MyDetails/frame.cpp @@ -0,0 +1,2428 @@ +/* 
 +Copyright (C) 2005 Ricardo Pescuma Domenecci
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt.  If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA.  
 +*/
 +
 +
 +#include "commons.h"
 +#include "frame.h"
 +#include "wingdi.h"
 +#include "winuser.h"
 +#include <m_skin_eng.h>
 +
 +
 +// Prototypes /////////////////////////////////////////////////////////////////////////////////////
 +
 +
 +#define WINDOW_NAME_PREFIX "mydetails_window"
 +#define WINDOW_CLASS_NAME "MyDetailsFrame"
 +#define CONTAINER_CLASS_NAME "MyDetailsFrameContainer"
 +
 +#define ID_FRAME_TIMER			1011
 +#define ID_RECALC_TIMER			1012
 +#define ID_STATUSMESSAGE_TIMER	1013
 +
 +#define RECALC_TIME				500
 +
 +#define IDC_HAND				MAKEINTRESOURCE(32649)
 +
 +
 +// Messages
 +#define MWM_REFRESH				(WM_USER+10)
 +#define MWM_REFRESH_DATA        (WM_USER+18)
 +
 +
 +HWND hwnd_frame = NULL;
 +HWND hwnd_container = NULL;
 +
 +int frame_id = -1;
 +
 +HANDLE hMenuShowHideFrame = 0;
 +
 +int CreateFrame();
 +void FixMainMenu();
 +void UpdateFrameData();
 +void RedrawFrame();
 +
 +
 +// used when no multiwindow functionality available
 +BOOL MyDetailsFrameVisible();
 +void SetMyDetailsFrameVisible(BOOL visible);
 +int ShowHideMenuFunc(WPARAM wParam, LPARAM lParam);
 +int ShowFrameFunc(WPARAM wParam, LPARAM lParam);
 +int HideFrameFunc(WPARAM wParam, LPARAM lParam);
 +int ShowHideFrameFunc(WPARAM wParam, LPARAM lParam);
 +
 +
 +
 +LRESULT CALLBACK FrameContainerWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
 +LRESULT CALLBACK FrameWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
 +void SetCycleTime();
 +void SetCycleTime(HWND hwnd);
 +void SetStatusMessageRefreshTime();
 +void SetStatusMessageRefreshTime(HWND hwnd);
 +int SettingsChangedHook(WPARAM wParam, LPARAM lParam);
 +int AvatarChangedHook(WPARAM wParam, LPARAM lParam);
 +int ProtoAckHook(WPARAM wParam, LPARAM lParam);
 +int SmileyAddOptionsChangedHook(WPARAM wParam,LPARAM lParam);
 +int ListeningtoEnableStateChangedHook(WPARAM wParam,LPARAM lParam);
 +int AccListChanged(WPARAM wParam, LPARAM lParam);
 +
 +
 +void ExternalRect(RECT &ret, const RECT r1, const RECT r2);
 +bool InsideRect(const POINT &p, const RECT &r);
 +
 +
 +int operator==(const RECT& left, const RECT& right)
 +{
 +	return left.left == right.left && left.right == right.right
 +			&& left.top == right.top && left.bottom == right.bottom;
 +}
 +
 +class ToolTipArea
 +{
 +public:
 +	ToolTipArea() : hwndTT(0), hwndParent(0) { memset(&rc, 0, sizeof(rc)); }
 +	~ToolTipArea() { removeTooltip(); }
 +
 +	void createTooltip(HWND hwnd, const RECT &rc, const TCHAR *text)
 +	{
 +		if (text == NULL || text[0] == 0)
 +		{
 +			removeTooltip();
 +			return;
 +		}
 +
 +		this->text = text;
 +
 +		if (this->rc == rc && hwndParent == hwnd && hwndTT != NULL)
 +			return;
 +
 +		removeTooltip();
 +
 +		this->rc = rc;
 +		this->hwndParent = hwnd;
 +		this->hwndTT = CreateTooltip(this->hwndParent, this->rc);
 +	}
 +
 +	void removeTooltip()
 +	{
 +		if (hwndTT == NULL)
 +			return;
 +
 +		DestroyWindow(hwndTT);
 +		hwndTT = NULL;
 +		hwndParent = NULL;
 +	}
 +
 +	const TCHAR * getTextFor(HWND hwndFrom)
 +	{
 +		if (hwndTT == NULL || hwndTT != hwndFrom)
 +			return NULL;
 +		return text.c_str();
 +	}
 +
 +
 +private:
 +	
 +	HWND hwndTT;
 +	RECT rc;
 +	HWND hwndParent;
 +	std::tstring text;
 +
 +	HWND CreateTooltip(HWND hwnd, RECT &rect)
 +	{
 +			  // struct specifying control classes to register
 +		INITCOMMONCONTROLSEX iccex; 
 +		HWND hwndTT;                 // handle to the ToolTip control
 +			  // struct specifying info about tool in ToolTip control
 +		TOOLINFO ti;
 +		unsigned int uid = 0;       // for ti initialization
 +
 +		// Load the ToolTip class from the DLL.
 +		iccex.dwSize = sizeof(iccex);
 +		iccex.dwICC  = ICC_BAR_CLASSES;
 +
 +		if(!InitCommonControlsEx(&iccex))
 +		   return NULL;
 +
 +		/* CREATE A TOOLTIP WINDOW */
 +		hwndTT = CreateWindowEx(WS_EX_TOPMOST,
 +			TOOLTIPS_CLASS,
 +			NULL,
 +			WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,		
 +			CW_USEDEFAULT,
 +			CW_USEDEFAULT,
 +			CW_USEDEFAULT,
 +			CW_USEDEFAULT,
 +			hwnd,
 +			NULL,
 +			hInst,
 +			NULL
 +			);
 +
 +		/* Gives problem with mToolTip
 +		SetWindowPos(hwndTT,
 +			HWND_TOPMOST,
 +			0,
 +			0,
 +			0,
 +			0,
 +			SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
 +		*/
 +
 +		/* INITIALIZE MEMBERS OF THE TOOLINFO STRUCTURE */
 +		ti.cbSize = sizeof(TOOLINFO);
 +		ti.uFlags = TTF_SUBCLASS;
 +		ti.hwnd = hwnd;
 +		ti.hinst = hInst;
 +		ti.uId = uid;
 +		ti.lpszText = LPSTR_TEXTCALLBACK;
 +			// ToolTip control will cover the whole window
 +		ti.rect.left = rect.left;    
 +		ti.rect.top = rect.top;
 +		ti.rect.right = rect.right;
 +		ti.rect.bottom = rect.bottom;
 +
 +		/* SEND AN ADDTOOL MESSAGE TO THE TOOLTIP CONTROL WINDOW */
 +		SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);	
 +		SendMessage(hwndTT, TTM_SETDELAYTIME, (WPARAM) (DWORD) TTDT_AUTOPOP, (LPARAM) MAKELONG(24 * 60 * 60 * 1000, 0));	
 +
 +		return hwndTT;
 +	} 
 +};
 +
 +
 +struct SimpleItem
 +{
 +	RECT rc;
 +	bool draw;
 +	bool mouseOver;
 +	ToolTipArea tt;
 +	bool alignRight;
 +
 +	SimpleItem() : draw(FALSE), mouseOver(FALSE), alignRight(FALSE)
 +	{ 
 +		memset(&rc, 0, sizeof(rc)); 
 +	}
 +	virtual ~SimpleItem() {}
 +
 +	virtual void hide()
 +	{
 +		draw = false;
 +		mouseOver = false;
 +		tt.removeTooltip();
 +	}
 +
 +	virtual void update(HWND hwnd, SkinFieldState *item)
 +	{
 +		draw = item->isVisible();
 +		alignRight = ( item->getHorizontalAlign() == SKN_HALIGN_RIGHT );
 +
 +		if (draw)
 +		{
 +			rc = item->getRect();
 +			tt.createTooltip(hwnd, rc, item->getToolTip());
 +		}
 +		else
 +		{
 +			tt.removeTooltip();
 +		}
 +	}
 +
 +	virtual bool hitTest(const POINT &p)
 +	{
 +		return draw && InsideRect(p, rc);
 +	}
 +
 +	virtual const TCHAR * getToolTipFor(HWND hwndFrom)
 +	{
 +		return tt.getTextFor(hwndFrom);
 +	}
 +
 +	bool setMouseOver(POINT *mousePos)
 +	{
 +		bool over = (mousePos != NULL && hitTest(*mousePos));
 +
 +		if (mouseOver == over)
 +			return FALSE; 
 +
 +		mouseOver = over;
 +		return TRUE; 
 +	}
 +
 +};
 +
 +struct IconAndItem : public SimpleItem
 +{
 +	RECT rcIcon;
 +	RECT rcItem;
 +	BOOL drawIcon;
 +	BOOL drawItem;
 +	ToolTipArea ttIcon;
 +
 +	IconAndItem() : drawIcon(FALSE), drawItem(FALSE) 
 +	{ 
 +		memset(&rcIcon, 0, sizeof(rcIcon)); 
 +		memset(&rcItem, 0, sizeof(rcItem)); 
 +	}
 +	virtual ~IconAndItem() {}
 +	
 +	virtual void hide()
 +	{
 +		SimpleItem::hide();
 +		drawIcon = FALSE;
 +		drawItem = FALSE;
 +	}
 +
 +	virtual void update(HWND hwnd, SkinIconFieldState *icon, SkinTextFieldState *item)
 +	{
 +		drawIcon = icon->isVisible();
 +		drawItem = item->isVisible();
 +		alignRight = ( item->getHorizontalAlign() == SKN_HALIGN_RIGHT );
 +
 +		draw = drawIcon || drawItem;
 +		if (draw)
 +		{
 +			if (drawIcon)
 +				rcIcon = icon->getRect();
 +			if (drawItem)
 +				rcItem = item->getRect();
 +			
 +			if (drawIcon && drawItem)
 +				ExternalRect(rc, rcIcon, rcItem);
 +			else if (drawIcon)
 +				rc = rcIcon;
 +			else // if (drawItem)
 +				rc = rcItem;
 +		}
 +
 +		if (drawItem)
 +			tt.createTooltip(hwnd, rcItem, item->getToolTip());
 +		else
 +			tt.removeTooltip();
 +
 +		if (drawIcon)
 +			ttIcon.createTooltip(hwnd, rcIcon, icon->getToolTip());
 +		else
 +			ttIcon.removeTooltip();
 +	}
 +
 +	virtual const TCHAR * getToolTipFor(HWND hwndFrom)
 +	{
 +		const TCHAR * ret = tt.getTextFor(hwndFrom);
 +
 +		if (ret == NULL)
 +			ret = ttIcon.getTextFor(hwndFrom);
 +
 +		return ret;
 +	}
 +};
 +
 +
 +struct MyDetailsFrameData
 +{
 +	std::vector<SimpleItem*> items;
 +	SimpleItem proto;
 +	SimpleItem proto_cycle_next;
 +	SimpleItem proto_cycle_prev;
 +	SimpleItem avatar;
 +	SimpleItem nick;
 +	IconAndItem status;
 +	SimpleItem away_msg;
 +	IconAndItem listening_to;
 +	IconAndItem email;
 +
 +	bool showing_menu;
 +
 +	bool tracking_exit;
 +
 +	MyDetailsFrameData() 
 +		: showing_menu(false)
 +		, tracking_exit(false)
 +	{
 +		items.push_back(&proto);
 +		items.push_back(&proto_cycle_next);
 +		items.push_back(&proto_cycle_prev);
 +		items.push_back(&avatar);
 +		items.push_back(&nick);
 +		items.push_back(&status);
 +		items.push_back(&away_msg);
 +		items.push_back(&listening_to);
 +		items.push_back(&email);
 +	}
 +};
 +
 +
 +
 +// Functions //////////////////////////////////////////////////////////////////////////////////////
 +
 +void InitFrames()
 +{
 +	InitContactListSmileys();
 +
 +	CreateFrame();
 +
 +	HookEvent(ME_DB_CONTACT_SETTINGCHANGED, SettingsChangedHook);
 +	HookEvent(ME_AV_MYAVATARCHANGED, AvatarChangedHook);
 +	HookEvent(ME_PROTO_ACK, ProtoAckHook);
 +	HookEvent(ME_SMILEYADD_OPTIONSCHANGED,SmileyAddOptionsChangedHook);
 +	HookEvent(ME_LISTENINGTO_ENABLE_STATE_CHANGED,ListeningtoEnableStateChangedHook);
 +	HookEvent(ME_PROTO_ACCLISTCHANGED, AccListChanged);
 +}
 +
 +
 +void DeInitFrames()
 +{
 +	if(ServiceExists(MS_CLIST_FRAMES_REMOVEFRAME) && frame_id != -1) 
 +	{
 +		CallService(MS_CLIST_FRAMES_REMOVEFRAME, (WPARAM)frame_id, 0);
 +	}
 +
 +	if (hwnd_frame != NULL) DestroyWindow(hwnd_frame);
 +	if (hwnd_container != NULL) DestroyWindow(hwnd_container);
 +}
 +
 +int SmileyAddOptionsChangedHook(WPARAM wParam,LPARAM lParam)
 +{
 +	UpdateFrameData();
 +	return 0;
 +}
 +
 +int SkinEngineDrawCallback(HWND hWnd, HDC hDC, RECT * rcPaint, HRGN rgn, DWORD dFlags, void * CallBackData);
 +
 +int CreateFrame() 
 +{
 +	WNDCLASS wndclass;
 +	wndclass.style         = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; //CS_PARENTDC | CS_HREDRAW | CS_VREDRAW;
 +	wndclass.lpfnWndProc   = FrameWindowProc;
 +	wndclass.cbClsExtra    = 0;
 +	wndclass.cbWndExtra    = 0;
 +	wndclass.hInstance     = hInst;
 +	wndclass.hIcon         = NULL;
 +	wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
 +	wndclass.hbrBackground = 0; //(HBRUSH)(COLOR_3DFACE+1);
 +	wndclass.lpszMenuName  = NULL;
 +	wndclass.lpszClassName = WINDOW_CLASS_NAME;
 +	RegisterClass(&wndclass);
 +
 +	if (ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) 
 +	{
 +		hwnd_frame = CreateWindow(WINDOW_CLASS_NAME, Translate("My Details"), 
 +				WS_CHILD | WS_VISIBLE, 
 +				0,0,10,10, (HWND)CallService(MS_CLUI_GETHWND, 0, 0), NULL, hInst, NULL);
 +
 +		CLISTFrame Frame = {0};
 +		
 +		Frame.cbSize = sizeof(Frame);
 +		Frame.name = "My Details";
 +		Frame.TBname = Translate("My Details");
 +		Frame.hWnd = hwnd_frame;
 +		Frame.align = alTop;
 +		Frame.Flags = F_VISIBLE | F_SHOWTB | F_SHOWTBTIP | F_NOBORDER | F_NO_SUBCONTAINER;
 +		Frame.height = 100;
 +
 +		frame_id = CallService(MS_CLIST_FRAMES_ADDFRAME, (WPARAM)&Frame, 0);
 +
 +		if (ServiceExists(MS_SKINENG_REGISTERPAINTSUB)) 
 +		{
 +			CallService(MS_BACKGROUNDCONFIG_REGISTER,(WPARAM)"My Details Background/MyDetails", 0);
 +			CallService(MS_SKINENG_REGISTERPAINTSUB, (WPARAM) Frame.hWnd, (LPARAM) SkinEngineDrawCallback);
 +		}
 +		
 +		if (DBGetContactSettingByte(NULL, "MyDetails", "ForceHideFrame", 0))
 +		{
 +			int flags = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, frame_id), 0);
 +			if(flags & F_VISIBLE) 
 +				CallService(MS_CLIST_FRAMES_SHFRAME, frame_id, 0);
 +
 +			DBDeleteContactSetting(NULL, "MyDetails", "ForceHideFrame");
 +		}
 +
 +		if (DBGetContactSettingByte(NULL, "MyDetails", "ForceShowFrame", 0))
 +		{	
 +			int flags = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, frame_id), 0);
 +			if(!(flags & F_VISIBLE)) 
 +				CallService(MS_CLIST_FRAMES_SHFRAME, frame_id, 0);
 +
 +			DBDeleteContactSetting(NULL, "MyDetails", "ForceShowFrame");
 +		}
 +	}
 +	else 
 +	{
 +		wndclass.style         = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;//CS_HREDRAW | CS_VREDRAW;
 +		wndclass.lpfnWndProc   = FrameContainerWindowProc;
 +		wndclass.cbClsExtra    = 0;
 +		wndclass.cbWndExtra    = 0;
 +		wndclass.hInstance     = hInst;
 +		wndclass.hIcon         = NULL;
 +		wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
 +		wndclass.hbrBackground = 0; //(HBRUSH)(COLOR_3DFACE+1);
 +		wndclass.lpszMenuName  = NULL;
 +		wndclass.lpszClassName = CONTAINER_CLASS_NAME;
 +		RegisterClass(&wndclass);
 +
 +		hwnd_container = CreateWindowEx(WS_EX_TOOLWINDOW, CONTAINER_CLASS_NAME, Translate("My Details"), 
 +			(WS_THICKFRAME | WS_CAPTION | WS_SYSMENU) & ~WS_VISIBLE,
 +			0,0,200,130, (HWND)CallService(MS_CLUI_GETHWND, 0, 0), NULL, hInst, NULL);
 +	
 +		hwnd_frame = CreateWindow(WINDOW_CLASS_NAME, Translate("My Details"), 
 +			WS_CHILD | WS_VISIBLE,
 +			0,0,10,10, hwnd_container, NULL, hInst, NULL);
 +
 +		SetWindowLong(hwnd_container, GWL_USERDATA, (LONG)hwnd_frame);
 +		SendMessage(hwnd_container, WM_SIZE, 0, 0);
 +
 +		// Create menu item
 +
 +		CLISTMENUITEM menu = {0};
 +
 +		menu.cbSize=sizeof(menu);
 +		menu.flags = CMIM_ALL;
 +		menu.popupPosition = -0x7FFFFFFF;
 +		menu.pszPopupName = Translate("My Details");
 +		menu.position = 1; // 500010000
 +		menu.hIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
 +		menu.pszName = Translate("Show My Details");
 +		menu.pszService= MODULE_NAME "/ShowHideMyDetails";
 +		hMenuShowHideFrame = (HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&menu);
 +
 +		if(DBGetContactSettingByte(0, MODULE_NAME, SETTING_FRAME_VISIBLE, 1) == 1) 
 +		{
 +			ShowWindow(hwnd_container, SW_SHOW);
 +			FixMainMenu();
 +		}
 +	}
 +
 +	CreateServiceFunction(MS_MYDETAILS_SHOWFRAME, ShowFrameFunc);
 +	CreateServiceFunction(MS_MYDETAILS_HIDEFRAME, HideFrameFunc);
 +	CreateServiceFunction(MS_MYDETAILS_SHOWHIDEFRAME, ShowHideFrameFunc);
 +
 +	return 0;
 +}
 +
 +
 +BOOL FrameIsFloating() 
 +{
 +	if (frame_id == -1) 
 +	{
 +		return true; // no frames, always floating
 +	}
 +	
 +	return (CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLOATING, frame_id), 0) != 0);
 +}
 +
 +
 +LRESULT CALLBACK FrameContainerWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
 +	switch(msg) 
 +	{
 +		case WM_SHOWWINDOW:
 +		{
 +			if ((BOOL)wParam)
 +				Utils_RestoreWindowPosition(hwnd, 0, MODULE_NAME, WINDOW_NAME_PREFIX);
 +			else
 +				Utils_SaveWindowPosition(hwnd, 0, MODULE_NAME, WINDOW_NAME_PREFIX);
 +			break;
 +		}
 +
 +		case WM_ERASEBKGND:
 +		{
 +			HWND child = (HWND)GetWindowLong(hwnd, GWL_USERDATA);
 +
 +			SendMessage(child, WM_ERASEBKGND, wParam, lParam);
 +			break;
 +		}
 +
 +		case WM_SIZE:
 +		{
 +			HWND child = (HWND)GetWindowLong(hwnd, GWL_USERDATA);
 +			RECT r;
 +			GetClientRect(hwnd, &r);
 +
 +			SetWindowPos(child, 0, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER | SWP_NOACTIVATE);
 +			InvalidateRect(child, NULL, TRUE);
 +
 +			return TRUE;
 +		}
 +
 +		case WM_CLOSE:
 +		{
 +			DBWriteContactSettingByte(0, MODULE_NAME, SETTING_FRAME_VISIBLE, 0);
 +			ShowWindow(hwnd, SW_HIDE);
 +			FixMainMenu();
 +			return TRUE;
 +		}
 +	}
 +
 +	return DefWindowProc(hwnd, msg, wParam, lParam);
 +}
 +
 +
 +
 +BOOL ScreenToClient(HWND hWnd, LPRECT lpRect)
 +{
 +	BOOL ret;
 +
 +	POINT pt;
 +
 +	pt.x = lpRect->left;
 +	pt.y = lpRect->top;
 +
 +	ret = ScreenToClient(hWnd, &pt);
 +
 +	if (!ret) return ret;
 +
 +	lpRect->left = pt.x;
 +	lpRect->top = pt.y;
 +
 +
 +	pt.x = lpRect->right;
 +	pt.y = lpRect->bottom;
 +
 +	ret = ScreenToClient(hWnd, &pt);
 +
 +	lpRect->right = pt.x;
 +	lpRect->bottom = pt.y;
 +
 +	return ret;
 +}
 +
 +
 +BOOL MoveWindow(HWND hWnd, const RECT &rect, BOOL bRepaint)
 +{
 +	return MoveWindow(hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, bRepaint);
 +}
 +
 +
 +RECT GetInnerRect(const RECT &rc, const RECT &clipping)
 +{
 +	RECT rc_ret = rc;
 +
 +	rc_ret.left = max(rc.left, clipping.left);
 +	rc_ret.top = max(rc.top, clipping.top);
 +	rc_ret.right = min(rc.right, clipping.right);
 +	rc_ret.bottom = min(rc.bottom, clipping.bottom);
 +
 +	return rc_ret;
 +}
 +
 +
 +
 +
 +
 +void ExternalRect(RECT &ret, const RECT r1, const RECT r2)
 +{
 +	ret.left = min(r1.left, r2.left);
 +	ret.right = max(r1.right, r2.right);
 +	ret.top = min(r1.top, r2.top);
 +	ret.bottom = max(r1.bottom, r2.bottom);
 +}
 +
 +
 +HBITMAP CreateBitmap32(int cx, int cy)
 +{
 +   BITMAPINFO RGB32BitsBITMAPINFO; 
 +    UINT * ptPixels;
 +    HBITMAP DirectBitmap;
 +
 +    ZeroMemory(&RGB32BitsBITMAPINFO,sizeof(BITMAPINFO));
 +    RGB32BitsBITMAPINFO.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
 +    RGB32BitsBITMAPINFO.bmiHeader.biWidth=cx;//bm.bmWidth;
 +    RGB32BitsBITMAPINFO.bmiHeader.biHeight=cy;//bm.bmHeight;
 +    RGB32BitsBITMAPINFO.bmiHeader.biPlanes=1;
 +    RGB32BitsBITMAPINFO.bmiHeader.biBitCount=32;
 +
 +    DirectBitmap = CreateDIBSection(NULL, 
 +                                       (BITMAPINFO *)&RGB32BitsBITMAPINFO, 
 +                                       DIB_RGB_COLORS,
 +                                       (void **)&ptPixels, 
 +                                       NULL, 0);
 +    return DirectBitmap;
 +}
 +
 +
 +BOOL UseLayeredMode()
 +{
 +	return isLayeredEnabled() && !FrameIsFloating();
 +}
 +
 +
 +void EraseBackground(HWND hwnd, HDC hdc)
 +{
 +	RECT r;
 +	GetClientRect(hwnd, &r);
 +
 +	if (isSkinEngineEnabled())
 +	{
 +		if (FrameIsFloating())
 +		{
 +			HBRUSH hB = CreateSolidBrush(opts.bkg_color);
 +			FillRect(hdc, &r, hB);
 +			DeleteObject(hB);
 +		}
 +		else
 +		{
 +			SkinDrawWindowBack(hwnd, hdc, &r, "Main,ID=Background");
 +		}
 +
 +		SkinDrawGlyph(hdc, &r, &r,"MyDetails,ID=Background");
 +	}
 +	else
 +	{
 +		HBRUSH hB = CreateSolidBrush(opts.bkg_color);
 +		FillRect(hdc, &r, hB);
 +		DeleteObject(hB);
 +	}
 +}
 +
 +static int Width(const RECT &rc)
 +{
 +	return rc.right - rc.left;
 +}
 +
 +static int Height(const RECT &rc)
 +{
 +	return rc.bottom - rc.top;
 +}
 +
 +static HICON CreateOverlayedIcon(HICON icon, HICON overlay)
 +{
 +	HIMAGELIST il = ImageList_Create(
 +				GetSystemMetrics(SM_CXICON),
 +				GetSystemMetrics(SM_CYICON),
 +				ILC_COLOR32|ILC_MASK, 2, 2);
 +	ImageList_AddIcon(il, icon);
 +	ImageList_AddIcon(il, overlay);
 +	HIMAGELIST newImage = ImageList_Merge(il,0,il,1,0,0);
 +	ImageList_Destroy(il);
 +	HICON hIcon = ImageList_GetIcon(newImage, 0, 0);
 +	ImageList_Destroy(newImage);
 +	return hIcon; // the result should be destroyed by DestroyIcon()
 +}
 +
 +void Draw(HDC hdc, SkinIconFieldState &state)
 +{
 +	if (!state.isVisible())
 +		return;
 +
 +	RECT rc = state.getInsideRect();
 +	HRGN rgn = CreateRectRgnIndirect(&rc);
 +	SelectClipRgn(hdc, rgn);
 +
 +	rc = state.getInsideRect(true);
 +
 +	skin_DrawIconEx(hdc, rc.left, rc.top, state.getIcon(), Width(rc), Height(rc), 0, NULL, DI_NORMAL);
 +
 +	SelectClipRgn(hdc, NULL);
 +	DeleteObject(rgn);
 +}
 +
 +void Draw(HDC hdc, SkinTextFieldState &state, BOOL replace_smileys = FALSE, const char *protocol = NULL)
 +{
 +	if (!state.isVisible())
 +		return;
 +
 +	RECT rc = state.getInsideRect();
 +	HRGN rgn = CreateRectRgnIndirect(&rc);
 +	SelectClipRgn(hdc, rgn);
 +
 +	HGDIOBJ oldFont = SelectObject(hdc, state.getFont());
 +	COLORREF oldColor = SetTextColor(hdc, state.getFontColor());
 +
 +	UINT uFormat = DT_NOPREFIX | DT_END_ELLIPSIS | (opts.draw_text_rtl ? DT_RTLREADING : 0);
 +
 +	switch(state.getHorizontalAlign())
 +	{
 +		case SKN_HALIGN_RIGHT:
 +			uFormat |= DT_RIGHT;
 +			break;
 +		case SKN_HALIGN_CENTER:
 +			uFormat |= DT_CENTER;
 +			break;
 +		case SKN_HALIGN_LEFT:
 +			uFormat |= DT_LEFT;
 +			break;
 +	}
 +
 +	if (replace_smileys && opts.replace_smileys)
 +	{
 +		uFormat |= DT_SINGLELINE;
 +
 +		// Draw only first line of text
 +		char *tmp = strdup(state.getText());
 +		char *pos = strchr(tmp, '\r');
 +		if (pos != NULL) 
 +			pos[0] = '\0';
 +		pos = strchr(tmp, '\n');
 +		if (pos != NULL) 
 +			pos[0] = '\0';
 +
 +		Smileys_DrawText(hdc, tmp, -1, &rc, uFormat | (opts.resize_smileys ? DT_RESIZE_SMILEYS : 0), 
 +			opts.use_contact_list_smileys ? "clist" : protocol, NULL);
 +	}
 +	else
 +	{
 +		skin_DrawText(hdc, state.getText(), -1, &rc, uFormat);
 +	}
 +
 +
 +	SelectObject(hdc, oldFont);
 +	SetTextColor(hdc, oldColor);
 +
 +	SelectClipRgn(hdc, NULL);
 +	DeleteObject(rgn);			
 +}
 +
 +
 +void DrawMouseOver(HDC hdc, RECT *lprc, const char *place)
 +{
 +	if (isSkinEngineEnabled())
 +	{
 +		SkinDrawGlyph(hdc, lprc, lprc, "MyDetails,ID=MouseOver");
 +
 +		char glyph[1024];
 +		mir_snprintf(glyph, MAX_REGS(glyph), "MyDetails,ID=MouseOver%s", place);
 +		SkinDrawGlyph(hdc, lprc, lprc, glyph);
 +	}
 +	else
 +	{
 +		FrameRect(hdc, lprc, (HBRUSH) GetStockObject(GRAY_BRUSH));
 +	}
 +}
 +
 +
 +void Draw(HWND hwnd, HDC hdc_orig)
 +{
 +	MyDetailsFrameData *data = (MyDetailsFrameData *) GetWindowLong(hwnd, GWL_USERDATA);
 +
 +	Protocol *proto = GetCurrentProtocol();
 +	if (proto == NULL)
 +	{
 +		EraseBackground(hwnd, hdc_orig);
 +		return;
 +	}
 +
 +	if (ServiceExists(MS_CLIST_FRAMES_SETFRAMEOPTIONS) && frame_id != -1)
 +	{
 +		int flags = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, frame_id), 0);
 +		if(flags & F_UNCOLLAPSED) 
 +		{
 +			RECT rf;
 +			GetClientRect(hwnd, &rf);
 +
 +			if (rf.bottom - rf.top != 0)
 +			{
 +				if (FrameIsFloating()) 
 +				{
 +					HWND parent = GetParent(hwnd);
 +
 +					if (parent != NULL)
 +					{
 +						RECT rp_client, rp_window, r_window;
 +						GetClientRect(parent, &rp_client);
 +						GetWindowRect(parent, &rp_window);
 +						GetWindowRect(hwnd, &r_window);
 +						int diff = (rp_window.bottom - rp_window.top) - (rp_client.bottom - rp_client.top);
 +						if(ServiceExists(MS_CLIST_FRAMES_ADDFRAME))
 +							diff += (r_window.top - rp_window.top);
 +
 +						SetWindowPos(parent, 0, 0, 0, rp_window.right - rp_window.left, diff, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
 +					}
 +				}
 +			}
 +
 +			for (size_t i = 0; i < data->items.size(); ++i)
 +				data->items[i]->hide();
 +
 +			return;
 +		}
 +	}
 +
 +
 +	RECT r_full;
 +	GetClientRect(hwnd, &r_full);
 +
 +	HDC hdc;
 +	HBITMAP hBmp;
 +	BOOL useLayeredMode = UseLayeredMode();
 +	if (useLayeredMode)
 +	{
 +		hdc = hdc_orig;
 +		hBmp = NULL;
 +	}
 +	else
 +	{
 +		hdc = CreateCompatibleDC(hdc_orig);
 +		hBmp = CreateBitmap32(Width(r_full), Height(r_full));
 +		SelectObject(hdc, hBmp);
 +	}
 +
 +	int old_bk_mode = SetBkMode(hdc, TRANSPARENT);
 +	HFONT old_font = (HFONT) GetCurrentObject(hdc, OBJ_FONT);
 +	COLORREF old_color = GetTextColor(hdc);
 +	SetStretchBltMode(hdc, HALFTONE);
 +
 +
 +	HICON hStatusIcon;
 +	bool freeStatusIcon = false;
 +	if (proto->GetCustomStatus() != 0 && proto->CanCall(PS_ICQ_GETCUSTOMSTATUSICON))
 +		hStatusIcon = (HICON) proto->Call(PS_ICQ_GETCUSTOMSTATUSICON, proto->GetCustomStatus(), LR_SHARED);
 +	else
 +		hStatusIcon = LoadSkinnedProtoIcon(proto->GetName(), proto->GetStatus());
 +
 +	if (proto->IsLocked())
 +	{
 +		HICON hLockOverlay = LoadSkinnedIcon(SKINICON_OTHER_STATUS_LOCKED);
 +		if (hLockOverlay != NULL)
 +		{
 +			freeStatusIcon = true;
 +			hStatusIcon = CreateOverlayedIcon(hStatusIcon, hLockOverlay);
 +		}
 +	}
 +
 +
 +	HICON hListeningIcon = IcoLib_LoadIcon("LISTENING_TO_ICON");
 +	HICON hEmailIcon = IcoLib_LoadIcon("MYDETAILS_EMAIL");
 +	HICON hNextIcon = IcoLib_LoadIcon("MYDETAILS_NEXT_PROTOCOL");
 +	HICON hPrevIcon = IcoLib_LoadIcon("MYDETAILS_PREV_PROTOCOL");
 +
 +	{
 +		dialog->setInfoBool("resize_frame", opts.resize_frame);
 +		dialog->setInfoBool("protocol.locked", proto->IsLocked());
 +
 +
 +		if (opts.resize_frame)
 +			dialog->setSize(Width(r_full), 0x1FFFFFFF);
 +		else
 +			dialog->setSize(Width(r_full), Height(r_full));
 +
 +
 +
 +		SkinImageField avatar = dialog->getImageField("avatar");
 +		if (proto->CanGetAvatar() && proto->GetAvatarImage() != NULL)
 +		{
 +			avatar.setEnabled(TRUE);
 +			avatar.setImage(proto->GetAvatarImage());
 +		}
 +		else
 +		{
 +			avatar.setEnabled(FALSE);
 +			avatar.setImage(NULL);
 +		}
 +
 +		SkinTextField nickname = dialog->getTextField("nickname");
 +		nickname.setText(proto->GetNick());
 +
 +		SkinTextField protocol = dialog->getTextField("protocol");
 +		protocol.setText(proto->GetDescription());
 +
 +		SkinIconField status_icon = dialog->getIconField("status_icon");
 +		status_icon.setIcon(hStatusIcon);
 +
 +		SkinTextField status_name = dialog->getTextField("status_name");
 +		status_name.setText(proto->GetStatusName());
 +
 +		SkinTextField status_msg = dialog->getTextField("status_msg");
 +		if (proto->CanGetStatusMsg()) 
 +		{
 +			status_msg.setEnabled(TRUE);
 +			status_msg.setText(proto->GetStatusMsg());
 +		}
 +		else
 +		{
 +			status_msg.setEnabled(FALSE);
 +			status_msg.setText(_T(""));
 +		}
 +
 +		SkinIconField listening_icon = dialog->getIconField("listening_icon");
 +		SkinTextField listening = dialog->getTextField("listening");
 +		if (proto->ListeningToEnabled() && proto->GetStatus() > ID_STATUS_OFFLINE 
 +				&& proto->GetListeningTo()[0] != 0) 
 +		{
 +			listening_icon.setEnabled(TRUE);
 +			listening.setEnabled(TRUE);
 +			listening_icon.setIcon(hListeningIcon);
 +			listening.setText(proto->GetListeningTo());
 +		}
 +		else
 +		{
 +			listening_icon.setEnabled(FALSE);
 +			listening.setEnabled(FALSE);
 +			listening_icon.setIcon(NULL);
 +			listening.setText(_T(""));
 +		}
 +
 +		SkinIconField email_icon = dialog->getIconField("email_icon");
 +		SkinTextField email = dialog->getTextField("email");
 +		if (proto->CanGetEmailCount())
 +		{
 +			email_icon.setEnabled(TRUE);
 +			email.setEnabled(TRUE);
 +			email_icon.setIcon(hEmailIcon);
 +
 +			TCHAR tmp[64];
 +			_sntprintf(tmp, MAX_REGS(tmp), _T("%d"), proto->GetEmailCount());
 +			email.setText(tmp);
 +		}
 +		else
 +		{
 +			email_icon.setEnabled(FALSE);
 +			email.setEnabled(FALSE);
 +			email_icon.setIcon(NULL);
 +			email.setText(_T(""));
 +		}
 +
 +		SkinIconField next_proto = dialog->getIconField("next_proto");
 +		SkinIconField prev_proto = dialog->getIconField("prev_proto");
 +		prev_proto.setIcon(hPrevIcon);
 +		next_proto.setIcon(hNextIcon);
 +	}
 +
 +	SkinDialogState state = dialog->run();
 +	SkinImageFieldState avatar = state.getImageField("avatar");
 +	SkinTextFieldState nickname = state.getTextField("nickname");
 +	SkinTextFieldState protocol = state.getTextField("protocol");
 +	SkinIconFieldState status_icon = state.getIconField("status_icon");
 +	SkinTextFieldState status_name = state.getTextField("status_name");
 +	SkinTextFieldState status_msg = state.getTextField("status_msg");
 +	SkinIconFieldState listening_icon = state.getIconField("listening_icon");
 +	SkinTextFieldState listening = state.getTextField("listening");
 +	SkinIconFieldState email_icon = state.getIconField("email_icon");
 +	SkinTextFieldState email = state.getTextField("email");
 +	SkinIconFieldState next_proto = state.getIconField("next_proto");
 +	SkinIconFieldState prev_proto = state.getIconField("prev_proto");
 +		
 +
 +	{
 +		data->proto.update(hwnd, &protocol);
 +		data->proto_cycle_next.update(hwnd, &next_proto);
 +		data->proto_cycle_prev.update(hwnd, &prev_proto);
 +		data->avatar.update(hwnd, &avatar);
 +		data->nick.update(hwnd, &nickname);
 +		data->status.update(hwnd, &status_icon, &status_name);
 +		data->away_msg.update(hwnd, &status_msg);
 +		data->listening_to.update(hwnd, &listening_icon, &listening);
 +		data->email.update(hwnd, &email_icon, &email);
 +
 +		
 +		POINT p = {0};
 +		GetCursorPos(&p);
 +		ScreenToClient(hwnd, &p);
 +
 +		for(size_t i = 0; i < data->items.size(); ++i)
 +			data->items[i]->setMouseOver(&p);
 +	}
 +
 +	// Erase
 +	EraseBackground(hwnd, hdc);
 +
 +	// Draw items
 +
 +	UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_END_ELLIPSIS 
 +					| (opts.draw_text_rtl ? DT_RTLREADING : 0);
 +
 +	// Image
 +	if (avatar.isVisible() && proto->CanGetAvatar() && proto->GetAvatarImage() != NULL)
 +	{
 +		RECT rc = avatar.getInsideRect();
 +		HRGN rgn = CreateRectRgnIndirect(&rc);
 +		SelectClipRgn(hdc, rgn);
 +
 +		rc = avatar.getInsideRect(true);
 +
 +		int width = Width(rc);
 +		int height = Height(rc);
 +
 +		int round_radius;
 +		if (opts.draw_avatar_round_corner)
 +		{
 +			if (opts.draw_avatar_use_custom_corner_size)
 +				round_radius = opts.draw_avatar_custom_corner_size;
 +			else
 +				round_radius = min(width, height) / 6;
 +		}
 +		else
 +		{
 +			round_radius = 0;
 +		}
 +
 +
 +		AVATARDRAWREQUEST adr = {0};
 +
 +		adr.cbSize = sizeof(AVATARDRAWREQUEST);
 +		adr.hTargetDC = hdc;
 +		adr.rcDraw = rc;
 +
 +		adr.dwFlags = AVDRQ_OWNPIC | AVDRQ_HIDEBORDERONTRANSPARENCY | 
 +			(opts.draw_avatar_border ? AVDRQ_DRAWBORDER : 0 ) |
 +			(opts.draw_avatar_round_corner ? AVDRQ_ROUNDEDCORNER : 0 );
 +
 +		if (useLayeredMode)
 +			adr.dwFlags |= AVDRQ_AERO;
 +
 +		adr.clrBorder =  opts.draw_avatar_border_color;
 +		adr.radius = round_radius;
 +		adr.alpha = 255;
 +		adr.szProto = (char *) proto->GetName();
 +
 +		CallService(MS_AV_DRAWAVATAR, 0, (LPARAM) &adr);
 +
 +		// Clipping rgn
 +		SelectClipRgn(hdc, NULL);
 +		DeleteObject(rgn);
 +	}
 +
 +	// Nick
 +	if (data->nick.draw && data->nick.mouseOver && proto->CanSetNick())
 +		DrawMouseOver(hdc, &nickname.getRect(), "Nick");
 +
 +	Draw(hdc, nickname, TRUE, proto->GetName());
 +
 +
 +	// Protocol
 +	if (data->proto.draw && data->proto.mouseOver)
 +		DrawMouseOver(hdc, &data->proto.rc, "Proto");
 +	
 +	Draw(hdc, protocol);
 +	
 +
 +	// Status
 +	if (data->status.draw && data->status.mouseOver)
 +		DrawMouseOver(hdc, &data->status.rc, "Status");
 +	
 +	Draw(hdc, status_icon);
 +	Draw(hdc, status_name);
 +
 +
 +	// Away message
 +	if (data->away_msg.draw && data->away_msg.mouseOver && proto->CanSetStatusMsg())
 +		DrawMouseOver(hdc, &data->away_msg.rc, "StatusMsg");
 +	
 +	Draw(hdc, status_msg, TRUE, proto->GetName());
 +
 +
 +	// Listening to
 +	Draw(hdc, listening_icon);
 +	Draw(hdc, listening);
 +	
 +	if (data->listening_to.draw && data->listening_to.mouseOver && protocols->CanSetListeningTo())
 +		DrawMouseOver(hdc, &data->listening_to.rc, "Listening");
 +	
 +
 +	// Unread email count
 +	Draw(hdc, email_icon);
 +	Draw(hdc, email);
 +
 +	// Protocol cycle icon
 +	Draw(hdc, next_proto);
 +	Draw(hdc, prev_proto);
 +
 +
 +	SelectObject(hdc, old_font);
 +	SetTextColor(hdc, old_color);
 +	SetBkMode(hdc, old_bk_mode);
 +
 +	if (!useLayeredMode)
 +	{
 +		BitBlt(hdc_orig, r_full.left, r_full.top, r_full.right - r_full.left, 
 +			r_full.bottom - r_full.top, hdc, r_full.left, r_full.top, SRCCOPY);
 +		DeleteDC(hdc);
 +		DeleteObject(hBmp);
 +	}
 +
 +	if (freeStatusIcon)
 +		DestroyIcon(hStatusIcon);
 +	IcoLib_ReleaseIcon(hListeningIcon);
 +	IcoLib_ReleaseIcon(hEmailIcon);
 +	IcoLib_ReleaseIcon(hPrevIcon);
 +	IcoLib_ReleaseIcon(hNextIcon);
 +
 +	if (opts.resize_frame && ServiceExists(MS_CLIST_FRAMES_SETFRAMEOPTIONS) && frame_id != -1)
 +	{
 +		RECT rf;
 +		GetClientRect(hwnd, &rf);
 +
 +		int currentSize = Height(r_full);
 +
 +		int expectedSize = 0;
 +		for(size_t i = 0; i < data->items.size(); ++i)
 +		{
 +			SimpleItem *item = data->items[i];
 +			if (!item->draw)
 +				continue;
 +
 +			expectedSize = max(expectedSize, item->rc.bottom);
 +		}
 +		expectedSize += state.getBorders().bottom;
 +
 +		if (expectedSize != currentSize)
 +		{
 +			if (FrameIsFloating()) 
 +			{
 +				HWND parent = GetParent(hwnd);
 +
 +				if (parent != NULL)
 +				{
 +					RECT rp_client, rp_window, r_window;
 +					GetClientRect(parent, &rp_client);
 +					GetWindowRect(parent, &rp_window);
 +					GetWindowRect(hwnd, &r_window);
 +					int diff = (rp_window.bottom - rp_window.top) - (rp_client.bottom - rp_client.top);
 +					if(ServiceExists(MS_CLIST_FRAMES_ADDFRAME))
 +						diff += (r_window.top - rp_window.top);
 +
 +					SetWindowPos(parent, 0, 0, 0, rp_window.right - rp_window.left, expectedSize + diff, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
 +				}
 +			}
 +			else if (IsWindowVisible(hwnd) && ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) 
 +			{
 +				int flags = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, frame_id), 0);
 +				if(flags & F_VISIBLE) 
 +				{
 +					CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_HEIGHT, frame_id), (LPARAM) expectedSize);
 +					CallService(MS_CLIST_FRAMES_UPDATEFRAME, (WPARAM)frame_id, (LPARAM)(FU_TBREDRAW | FU_FMREDRAW | FU_FMPOS));
 +				}
 +			}
 +		}
 +	}
 +}
 +
 +int SkinEngineDrawCallback(HWND hWnd, HDC hDC, RECT * rcPaint, HRGN rgn, DWORD dFlags, void * CallBackData)
 +{
 +	Draw(hWnd, hDC);
 +	return 0;
 +}
 +
 +bool InsideRect(const POINT &p, const RECT &r)
 +{
 +	return p.x >= r.left && p.x < r.right && p.y >= r.top && p.y < r.bottom;
 +}
 +
 +int ShowPopupMenu(HWND hwnd, HMENU submenu, SimpleItem &item)
 +{
 +	POINT p;
 +	if (item.alignRight)
 +		p.x = item.rc.right;
 +	else
 +		p.x = item.rc.left;
 +	p.y =  item.rc.bottom+1;
 +	ClientToScreen(hwnd, &p);
 +	
 +	return TrackPopupMenu(submenu, TPM_TOPALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD
 +			| (item.alignRight ? TPM_RIGHTALIGN : TPM_LEFTALIGN), p.x, p.y, 0, hwnd, NULL);
 +}
 +
 +
 +void ShowGlobalStatusMenu(HWND hwnd, MyDetailsFrameData *data, Protocol *proto, POINT &p)
 +{
 +	HMENU submenu = (HMENU) CallService(MS_CLIST_MENUGETSTATUS,0,0);
 +	
 +	int ret = ShowPopupMenu(hwnd, submenu, data->status);
 +	if(ret)
 +		CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(ret),MPCF_MAINMENU),(LPARAM)NULL);
 +}
 +
 +void ShowProtocolStatusMenu(HWND hwnd, MyDetailsFrameData *data, Protocol *proto, POINT &p)
 +{
 +	HMENU menu = (HMENU) CallService(MS_CLIST_MENUGETSTATUS,0,0);
 +	HMENU submenu = NULL;
 +
 +	if (menu != NULL)
 +	{
 +		// Find the correct menu item
 +		int count = GetMenuItemCount(menu);
 +		for (int i = 0 ; i < count && submenu == NULL; i++)
 +		{
 +			MENUITEMINFO mii = {0};
 +
 +			mii.cbSize = sizeof(mii);
 +
 +			if(!IsWinVer98Plus()) 
 +			{
 +				mii.fMask = MIIM_TYPE;
 +			}
 +			else 
 +			{
 +				mii.fMask = MIIM_STRING;
 +			}
 +
 +			GetMenuItemInfo(menu, i, TRUE, &mii);
 +
 +			if (mii.cch != 0)
 +			{
 +				mii.cch++;
 +				mii.dwTypeData = (char *)malloc(sizeof(char) * mii.cch);
 +				GetMenuItemInfo(menu, i, TRUE, &mii);
 +
 +				if (strcmp(mii.dwTypeData, proto->GetDescription()) == 0)
 +				{
 +					submenu = GetSubMenu(menu, i);
 +				}
 +
 +				free(mii.dwTypeData);
 +			}
 +		}
 +
 +		if (submenu == NULL && GetNumProtocols() == 1)
 +		{
 +			submenu = menu;
 +		}
 +	}
 +
 +	if (submenu != NULL)
 +	{
 +		int ret = ShowPopupMenu(hwnd, submenu, data->status);
 +		if(ret)
 +			CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(ret),MPCF_MAINMENU),(LPARAM)NULL);
 +	}
 +	else
 +	{
 +		// Well, lets do it by hand
 +		static int statusModePf2List[]={0xFFFFFFFF,PF2_ONLINE,PF2_SHORTAWAY,PF2_LONGAWAY,PF2_LIGHTDND,PF2_HEAVYDND,PF2_FREECHAT,PF2_INVISIBLE,PF2_ONTHEPHONE,PF2_OUTTOLUNCH};
 +
 +		menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
 +		submenu = GetSubMenu(menu, 0);
 +		CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)submenu,0);
 +
 +		DWORD flags = proto->Call(PS_GETCAPS, PFLAGNUM_2);
 +		for ( int i = GetMenuItemCount(submenu) -1  ; i >= 0 ; i-- )
 +		{
 +			if (!(flags & statusModePf2List[i]))
 +			{
 +				// Hide menu
 +				RemoveMenu(submenu, i, MF_BYPOSITION);
 +			}
 +		}
 +
 +		int ret = ShowPopupMenu(hwnd, submenu, data->status);
 +		DestroyMenu(menu);
 +
 +		if(ret) 
 +			proto->SetStatus(ret);
 +	}
 +}
 +
 +void ShowListeningToMenu(HWND hwnd, MyDetailsFrameData *data, Protocol *proto, POINT &p)
 +{
 +	HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
 +	HMENU submenu = GetSubMenu(menu, 5);
 +	CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)submenu,0);
 +
 +	// Add this proto to menu
 +	char tmp[128];
 +	mir_snprintf(tmp, sizeof(tmp), Translate("Enable Listening To for %s"), proto->GetDescription());
 +
 +	MENUITEMINFO mii = {0};
 +	mii.cbSize = sizeof(mii);
 +	mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
 +	mii.fType = MFT_STRING;
 +	mii.fState = proto->ListeningToEnabled() ? MFS_CHECKED : 0;
 +	mii.dwTypeData = tmp;
 +	mii.cch = strlen(tmp);
 +	mii.wID = 1;
 +
 +	if (!proto->CanSetListeningTo())
 +	{
 +		mii.fState |= MFS_DISABLED;
 +	}
 +
 +	InsertMenuItem(submenu, 0, TRUE, &mii);
 +
 +	ZeroMemory(&mii, sizeof(mii));
 +	mii.cbSize = sizeof(mii);
 +	mii.fMask = MIIM_STATE;
 +	mii.fState = protocols->ListeningToEnabled() ? MFS_CHECKED : 0;
 +
 +	if (!protocols->CanSetListeningTo())
 +	{
 +		mii.fState |= MFS_DISABLED;
 +	}
 +
 +	SetMenuItemInfo(submenu, ID_LISTENINGTOPOPUP_SENDLISTENINGTO, FALSE, &mii);
 +	
 +	int ret = ShowPopupMenu(hwnd, submenu, data->listening_to);
 +
 +	DestroyMenu(menu);
 +
 +	switch(ret)
 +	{
 +		case 1:
 +		{
 +			CallService(MS_LISTENINGTO_ENABLE, (LPARAM) proto->GetName(), !proto->ListeningToEnabled());
 +			break;
 +		}
 +		case ID_LISTENINGTOPOPUP_SENDLISTENINGTO:
 +		{
 +			CallService(MS_LISTENINGTO_ENABLE, 0, !protocols->ListeningToEnabled());
 +			break;
 +		}
 +	}
 +
 +}
 +
 +
 +LRESULT CALLBACK FrameWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
 +{
 +	switch(msg) 
 +	{
 +		case WM_CREATE: 
 +		{
 +			MyDetailsFrameData *data = new MyDetailsFrameData();
 +			SetWindowLong(hwnd, GWL_USERDATA, (LONG) data);
 +
 +			SetCurrentProtocol(DBGetContactSettingWord(NULL, "MyDetails", "ProtocolNumber", 0));
 +
 +			SetCycleTime(hwnd);
 +
 +			SetStatusMessageRefreshTime(hwnd);
 +
 +			return TRUE;
 +		}
 +
 +
 +		case WM_ERASEBKGND:
 +		{
 +			//EraseBackground(hwnd, (HDC)wParam); 
 +			//Draw(hwnd, (HDC)wParam); 
 +			return TRUE;
 +		}
 +
 +		/*
 +		case WM_PRINTCLIENT:
 +		{
 +			Draw(hwnd, (HDC)wParam);
 +			return TRUE;
 +		}
 +		*/
 +
 +		case WM_PAINT:
 +		{
 +			if (UseLayeredMode())
 +			{
 +				CallService(MS_SKINENG_INVALIDATEFRAMEIMAGE, (WPARAM) hwnd, 0);
 +				ValidateRect(hwnd, NULL);
 +			}
 +			else
 +			{
 +				RECT r;
 +				if(GetUpdateRect(hwnd, &r, FALSE)) 
 +				{
 +					PAINTSTRUCT ps;
 +					
 +					HDC hdc = BeginPaint(hwnd, &ps);
 +					Draw(hwnd, hdc);
 +					EndPaint(hwnd, &ps);
 +				}
 +			}
 +			
 +			return TRUE;
 +		}
 +
 +		case WM_SIZE:
 +		{
 +			//InvalidateRect(hwnd, NULL, FALSE);
 +			MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
 +			RedrawFrame();
 +			break;
 +		}
 +
 +		case WM_TIMER:
 +		{
 +			MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
 +
 +			if (wParam == ID_FRAME_TIMER)
 +			{
 +				if (!data->showing_menu)
 +					CallService(MS_MYDETAILS_SHOWNEXTPROTOCOL, 0, 0);
 +			}
 +			else if (wParam == ID_RECALC_TIMER)
 +			{
 +				KillTimer(hwnd, ID_RECALC_TIMER);
 +
 +				PostMessage(hwnd, MWM_REFRESH_DATA, 0, 0);
 +			}
 +			else if (wParam == ID_STATUSMESSAGE_TIMER)
 +			{
 +				SetStatusMessageRefreshTime(hwnd);
 +
 +				PostMessage(hwnd, MWM_REFRESH_DATA, 0, 0);
 +			}
 +
 +			return TRUE;
 +		}
 +
 +		case WM_LBUTTONUP:
 +		{
 +			MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
 +			Protocol *proto = GetCurrentProtocol();
 +			if (proto == NULL)
 +				break;
 +
 +			POINT p;
 +			p.x = LOWORD(lParam); 
 +			p.y = HIWORD(lParam); 
 +
 +			// In proto cycle button?
 +			if (data->proto_cycle_next.hitTest(p))
 +			{
 +				CallService(MS_MYDETAILS_SHOWNEXTPROTOCOL, 0, 0);
 +			}
 +			else if (data->proto_cycle_prev.hitTest(p))
 +			{
 +				CallService(MS_MYDETAILS_SHOWPREVIOUSPROTOCOL, 0, 0);
 +			}
 +			// In image?
 +			else if (data->avatar.hitTest(p) && proto->CanSetAvatar())
 +			{
 +				if (opts.global_on_avatar)
 +					CallService(MS_MYDETAILS_SETMYAVATARUI, 0, 0);
 +				else
 +					CallService(MS_MYDETAILS_SETMYAVATARUI, 0, (LPARAM) proto->GetName());
 +			}
 +			// In nick?
 +			else if (data->nick.hitTest(p) && proto->CanSetNick())
 +			{
 +				if (opts.global_on_nickname)
 +					CallService(MS_MYDETAILS_SETMYNICKNAMEUI, 0, 0);
 +				else
 +					CallService(MS_MYDETAILS_SETMYNICKNAMEUI, 0, (LPARAM) proto->GetName());
 +			}
 +			// In status message?
 +			else if (data->away_msg.hitTest(p) && proto->CanSetStatusMsg())
 +			{
 +				if (opts.global_on_status_message)
 +					CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, 0, 0);
 +				else
 +					CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, 0, (LPARAM) proto->GetName());
 +			}
 +			// In status?
 +			else if (data->status.hitTest(p))
 +			{
 +				data->showing_menu = true;
 +
 +				if (opts.global_on_status)
 +					ShowGlobalStatusMenu(hwnd, data, proto, p);
 +				else
 +					ShowProtocolStatusMenu(hwnd, data, proto, p);
 +
 +				data->showing_menu = false;
 +			}
 +			// In listening to?
 +			else if (data->listening_to.hitTest(p) && protocols->CanSetListeningTo())
 +			{
 +				ShowListeningToMenu(hwnd, data, proto, p);
 +			}
 +			// In protocol?
 +			else if (data->proto.hitTest(p))
 +			{
 +				data->showing_menu = true;
 +
 +				HMENU menu = CreatePopupMenu();
 +
 +				std::vector<Protocol> protos;
 +				GetProtocols(&protos);
 +
 +				int current = GetCurrentProtocolIndex();
 +				
 +				int protosSize = (int) protos.size();
 +				for (int i = protosSize - 1 ; i >= 0 ; i--)
 +				{
 +					Protocol &proto = protos[i];
 +
 +					MENUITEMINFO mii = {0};
 +					mii.cbSize = sizeof(mii);
 +					mii.fMask = MIIM_ID | MIIM_TYPE;
 +					mii.fType = MFT_STRING;
 +					mii.dwTypeData = (char *) proto.GetDescription();
 +					mii.cch = strlen(mii.dwTypeData);
 +					mii.wID = i + 1;
 +
 +					if (i == current)
 +					{
 +						mii.fMask |= MIIM_STATE;
 +						mii.fState = MFS_DISABLED;
 +					}
 +
 +					InsertMenuItem(menu, 0, TRUE, &mii);
 +				}
 +				
 +				int ret = ShowPopupMenu(hwnd, menu, data->proto);
 +
 +				DestroyMenu(menu);
 +
 +				if (ret != 0)
 +					PluginCommand_ShowProtocol(NULL, (WPARAM) GetProtocolByIndex(ret - 1).GetName());
 +
 +				data->showing_menu = false;
 +			}
 +
 +			break;
 +		}
 +
 +		case WM_MEASUREITEM:
 +		{
 +			return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam);
 +		}
 +		case WM_DRAWITEM:
 +		{
 +			return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam);
 +		}
 +
 +		case WM_CONTEXTMENU:
 +		{
 +			MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
 +			Protocol *proto = GetCurrentProtocol();
 +			if (proto == NULL)
 +				break;
 +
 +			POINT p;
 +			p.x = LOWORD(lParam); 
 +			p.y = HIWORD(lParam); 
 +
 +			ScreenToClient(hwnd, &p);
 +
 +			data->showing_menu = true;
 +
 +			// In proto cycle button?
 +			if (data->proto_cycle_next.hitTest(p))
 +			{
 +				CallService(MS_MYDETAILS_SHOWPREVIOUSPROTOCOL, 0, 0);
 +			}
 +			else if (data->proto_cycle_prev.hitTest(p))
 +			{
 +				CallService(MS_MYDETAILS_SHOWNEXTPROTOCOL, 0, 0);
 +			}
 +			// In image?
 +			else if (data->avatar.hitTest(p))
 +			{
 +				HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
 +				HMENU submenu = GetSubMenu(menu, 4);
 +				CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)submenu,0);
 +
 +				// Add this proto to menu
 +				char tmp[128];
 +				mir_snprintf(tmp, sizeof(tmp), Translate("Set My Avatar for %s..."), proto->GetDescription());
 +
 +				MENUITEMINFO mii = {0};
 +				mii.cbSize = sizeof(mii);
 +				mii.fMask = MIIM_ID | MIIM_TYPE;
 +				mii.fType = MFT_STRING;
 +				mii.dwTypeData = tmp;
 +				mii.cch = strlen(tmp);
 +				mii.wID = 1;
 +
 +				if (!proto->CanSetAvatar())
 +				{
 +					mii.fMask |= MIIM_STATE;
 +					mii.fState = MFS_DISABLED;
 +				}
 +
 +				InsertMenuItem(submenu, 0, TRUE, &mii);
 +				
 +				ClientToScreen(hwnd, &p);
 +	
 +				int ret = TrackPopupMenu(submenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD, p.x, p.y, 0, hwnd, NULL);
 +				DestroyMenu(menu);
 +
 +				switch(ret)
 +				{
 +					case 1:
 +					{
 +						CallService(MS_MYDETAILS_SETMYAVATARUI, 0, (LPARAM) proto->GetName());
 +						break;
 +					}
 +					case ID_AVATARPOPUP_SETMYAVATAR:
 +					{
 +						CallService(MS_MYDETAILS_SETMYAVATARUI, 0, 0);
 +						break;
 +					}
 +				}
 +			}
 +			// In nick?
 +			else if (data->nick.hitTest(p))
 +			{
 +				HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
 +				HMENU submenu = GetSubMenu(menu, 2);
 +				CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)submenu,0);
 +
 +				// Add this proto to menu
 +				char tmp[128];
 +				mir_snprintf(tmp, sizeof(tmp), Translate("Set My Nickname for %s..."), proto->GetDescription());
 +
 +				MENUITEMINFO mii = {0};
 +				mii.cbSize = sizeof(mii);
 +				mii.fMask = MIIM_ID | MIIM_TYPE;
 +				mii.fType = MFT_STRING;
 +				mii.dwTypeData = tmp;
 +				mii.cch = strlen(tmp);
 +				mii.wID = 1;
 +
 +				if (!proto->CanSetNick())
 +				{
 +					mii.fMask |= MIIM_STATE;
 +					mii.fState = MFS_DISABLED;
 +				}
 +
 +				InsertMenuItem(submenu, 0, TRUE, &mii);
 +				
 +				ClientToScreen(hwnd, &p);
 +	
 +				int ret = TrackPopupMenu(submenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD, p.x, p.y, 0, hwnd, NULL);
 +				DestroyMenu(menu);
 +
 +				switch(ret)
 +				{
 +					case 1:
 +					{
 +						CallService(MS_MYDETAILS_SETMYNICKNAMEUI, 0, (LPARAM) proto->GetName());
 +						break;
 +					}
 +					case ID_NICKPOPUP_SETMYNICKNAME:
 +					{
 +						CallService(MS_MYDETAILS_SETMYNICKNAMEUI, 0, 0);
 +						break;
 +					}
 +				}
 +			}
 +			// In status message?
 +			else if (data->away_msg.hitTest(p))
 +			{
 +				char tmp[128];
 +
 +				HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
 +				HMENU submenu = GetSubMenu(menu, 3);
 +				CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)submenu,0);
 +
 +				// Add this proto to menu
 +				mir_snprintf(tmp, sizeof(tmp), Translate("Set My Status Message for %s..."), 
 +							 proto->GetDescription());
 +
 +				MENUITEMINFO mii = {0};
 +				mii.cbSize = sizeof(mii);
 +				mii.fMask = MIIM_ID | MIIM_TYPE;
 +				mii.fType = MFT_STRING;
 +				mii.dwTypeData = tmp;
 +				mii.cch = strlen(tmp);
 +				mii.wID = 1;
 +
 +				if (!proto->CanSetStatusMsg())
 +				{
 +					mii.fMask |= MIIM_STATE;
 +					mii.fState = MFS_DISABLED;
 +				}
 +
 +				InsertMenuItem(submenu, 0, TRUE, &mii);
 +				
 +				{
 +					// Add this to menu
 +					mir_snprintf(tmp, sizeof(tmp), Translate("Set My Status Message for %s..."), 
 +								 CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, proto->GetStatus(), 0));
 +
 +					MENUITEMINFO mii = {0};
 +					mii.cbSize = sizeof(mii);
 +					mii.fMask = MIIM_ID | MIIM_TYPE;
 +					mii.fType = MFT_STRING;
 +					mii.dwTypeData = tmp;
 +					mii.cch = strlen(tmp);
 +					mii.wID = 2;
 +
 +					if (proto->GetStatus() == ID_STATUS_OFFLINE)
 +					{
 +						mii.fMask |= MIIM_STATE;
 +						mii.fState = MFS_DISABLED;
 +					}
 +
 +					InsertMenuItem(submenu, 0, TRUE, &mii);
 +				}
 +				
 +				ClientToScreen(hwnd, &p);
 +	
 +				int ret = TrackPopupMenu(submenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD, p.x, p.y, 0, hwnd, NULL);
 +				DestroyMenu(menu);
 +
 +				switch(ret)
 +				{
 +					case 1:
 +					{
 +						CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, 0, (LPARAM) proto->GetName());
 +						break;
 +					}
 +					case 2:
 +					{
 +						CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, (WPARAM) proto->GetStatus(), 0);
 +						break;
 +					}
 +					case ID_STATUSMESSAGEPOPUP_SETMYSTATUSMESSAGE:
 +					{
 +						CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, 0, 0);
 +						break;
 +					}
 +				}
 +			}
 +			// In status?
 +			else if (data->status.hitTest(p))
 +			{
 +				if (opts.global_on_status)
 +					ShowProtocolStatusMenu(hwnd, data, proto, p);
 +				else
 +					ShowGlobalStatusMenu(hwnd, data, proto, p);
 +			}
 +			// In listening to?
 +			else if (data->listening_to.hitTest(p) && protocols->CanSetListeningTo())
 +			{
 +				ShowListeningToMenu(hwnd, data, proto, p);
 +			}
 +			// In protocol?
 +			else if (data->proto.hitTest(p))
 +			{
 +			}
 +			// Default context menu
 +			else 
 +			{
 +				HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
 +				HMENU submenu = GetSubMenu(menu, 1);
 +				CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)submenu,0);
 +
 +				if (opts.cycle_through_protocols)
 +					RemoveMenu(submenu, ID_CYCLE_THROUGH_PROTOS, MF_BYCOMMAND);
 +				else
 +					RemoveMenu(submenu, ID_DONT_CYCLE_THROUGH_PROTOS, MF_BYCOMMAND);
 +
 +				// Add this proto to menu
 +				char tmp[128];
 +				MENUITEMINFO mii = {0};
 +
 +				mir_snprintf(tmp, sizeof(tmp), Translate("Enable Listening To for %s"), proto->GetDescription());
 +
 +				ZeroMemory(&mii, sizeof(mii));
 +				mii.cbSize = sizeof(mii);
 +				mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
 +				mii.fType = MFT_STRING;
 +				mii.fState = proto->ListeningToEnabled() ? MFS_CHECKED : 0;
 +				mii.dwTypeData = tmp;
 +				mii.cch = strlen(tmp);
 +				mii.wID = 5;
 +
 +				if (!proto->CanSetListeningTo())
 +				{
 +					mii.fState |= MFS_DISABLED;
 +				}
 +
 +				InsertMenuItem(submenu, 0, TRUE, &mii);
 +
 +				// Add this to menu
 +				mir_snprintf(tmp, sizeof(tmp), Translate("Set My Status Message for %s..."), 
 +							 CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, proto->GetStatus(), 0));
 +
 +				ZeroMemory(&mii, sizeof(mii));
 +				mii.cbSize = sizeof(mii);
 +				mii.fMask = MIIM_ID | MIIM_TYPE;
 +				mii.fType = MFT_STRING;
 +				mii.dwTypeData = tmp;
 +				mii.cch = strlen(tmp);
 +				mii.wID = 4;
 +
 +				if (proto->GetStatus() == ID_STATUS_OFFLINE)
 +				{
 +					mii.fMask |= MIIM_STATE;
 +					mii.fState = MFS_DISABLED;
 +				}
 +
 +				InsertMenuItem(submenu, 0, TRUE, &mii);
 +
 +				// Add this proto to menu
 +				mir_snprintf(tmp, sizeof(tmp), Translate("Set My Status Message for %s..."), proto->GetDescription());
 +
 +				ZeroMemory(&mii, sizeof(mii));
 +				mii.cbSize = sizeof(mii);
 +				mii.fMask = MIIM_ID | MIIM_TYPE;
 +				mii.fType = MFT_STRING;
 +				mii.dwTypeData = tmp;
 +				mii.cch = strlen(tmp);
 +				mii.wID = 3;
 +
 +				if (!proto->CanSetStatusMsg())
 +				{
 +					mii.fMask |= MIIM_STATE;
 +					mii.fState = MFS_DISABLED;
 +				}
 +
 +				InsertMenuItem(submenu, 0, TRUE, &mii);
 +
 +				mir_snprintf(tmp, sizeof(tmp), Translate("Set My Nickname for %s..."), proto->GetDescription());
 +
 +				ZeroMemory(&mii, sizeof(mii));
 +				mii.cbSize = sizeof(mii);
 +				mii.fMask = MIIM_ID | MIIM_TYPE;
 +				mii.fType = MFT_STRING;
 +				mii.dwTypeData = tmp;
 +				mii.cch = strlen(tmp);
 +				mii.wID = 2;
 +
 +				if (!proto->CanSetNick())
 +				{
 +					mii.fMask |= MIIM_STATE;
 +					mii.fState = MFS_DISABLED;
 +				}
 +
 +				InsertMenuItem(submenu, 0, TRUE, &mii);
 +
 +				mir_snprintf(tmp, sizeof(tmp), Translate("Set My Avatar for %s..."), proto->GetDescription());
 +
 +				ZeroMemory(&mii, sizeof(mii));
 +				mii.cbSize = sizeof(mii);
 +				mii.fMask = MIIM_ID | MIIM_TYPE;
 +				mii.fType = MFT_STRING;
 +				mii.dwTypeData = tmp;
 +				mii.cch = strlen(tmp);
 +				mii.wID = 1;
 +
 +				if (!proto->CanSetAvatar())
 +				{
 +					mii.fMask |= MIIM_STATE;
 +					mii.fState = MFS_DISABLED;
 +				}
 +
 +				InsertMenuItem(submenu, 0, TRUE, &mii);
 +
 +				ZeroMemory(&mii, sizeof(mii));
 +				mii.cbSize = sizeof(mii);
 +				mii.fMask = MIIM_STATE;
 +				mii.fState = protocols->ListeningToEnabled() ? MFS_CHECKED : 0;
 +
 +				if (!protocols->CanSetListeningTo())
 +				{
 +					mii.fState |= MFS_DISABLED;
 +				}
 +
 +				SetMenuItemInfo(submenu, ID_CONTEXTPOPUP_ENABLELISTENINGTO, FALSE, &mii);
 +
 +				ClientToScreen(hwnd, &p);
 +	
 +				int ret = TrackPopupMenu(submenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD, p.x, p.y, 0, hwnd, NULL);
 +				DestroyMenu(menu);
 +
 +				switch(ret)
 +				{
 +					case 1:
 +					{
 +						CallService(MS_MYDETAILS_SETMYAVATARUI, 0, (LPARAM) proto->GetName());
 +						break;
 +					}
 +					case ID_AVATARPOPUP_SETMYAVATAR:
 +					{
 +						CallService(MS_MYDETAILS_SETMYAVATARUI, 0, 0);
 +						break;
 +					}
 +					case 2:
 +					{
 +						CallService(MS_MYDETAILS_SETMYNICKNAMEUI, 0, (LPARAM) proto->GetName());
 +						break;
 +					}
 +					case ID_NICKPOPUP_SETMYNICKNAME:
 +					{
 +						CallService(MS_MYDETAILS_SETMYNICKNAMEUI, 0, 0);
 +						break;
 +					}
 +					case 3:
 +					{
 +						CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, 0, (LPARAM) proto->GetName());
 +						break;
 +					}
 +					case 4:
 +					{
 +						CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, (WPARAM) proto->GetStatus(), 0);
 +						break;
 +					}
 +					case ID_STATUSMESSAGEPOPUP_SETMYSTATUSMESSAGE:
 +					{
 +						CallService(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, 0, 0);
 +						break;
 +					}
 +					case 5:
 +					{
 +						CallService(MS_LISTENINGTO_ENABLE, (LPARAM) proto->GetName(), !proto->ListeningToEnabled());
 +						break;
 +					}
 +					case ID_CONTEXTPOPUP_ENABLELISTENINGTO:
 +					{
 +						CallService(MS_LISTENINGTO_ENABLE, 0, !protocols->ListeningToEnabled());
 +						break;
 +					}
 +					case ID_SHOW_NEXT_PROTO:
 +					{
 +						CallService(MS_MYDETAILS_SHOWNEXTPROTOCOL, 0, 0);
 +						break;
 +					}
 +					case ID_SHOW_PREV_PROTO:
 +					{
 +						CallService(MS_MYDETAILS_SHOWPREVIOUSPROTOCOL, 0, 0);
 +						break;
 +					}
 +					case ID_CYCLE_THROUGH_PROTOS:
 +					{
 +						CallService(MS_MYDETAILS_CYCLE_THROUGH_PROTOCOLS, TRUE, 0);
 +						break;
 +					}
 +					case ID_DONT_CYCLE_THROUGH_PROTOS:
 +					{
 +						CallService(MS_MYDETAILS_CYCLE_THROUGH_PROTOCOLS, FALSE, 0);
 +						break;
 +					}
 +				}
 +			}
 +
 +			data->showing_menu = false;
 +
 +
 +			break;
 +		}
 +
 +		case WM_NCMOUSELEAVE:
 +		case WM_MOUSELEAVE:
 +		{
 +			MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
 +			data->tracking_exit = false;
 +		}
 +		case WM_NCMOUSEMOVE:
 +		{
 +			MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
 +
 +			bool changed = false;
 +			for(size_t i = 0; i < data->items.size(); ++i)
 +				changed = changed || data->items[i]->setMouseOver(NULL);
 +
 +			if (changed)
 +				InvalidateRect(hwnd, NULL, FALSE);
 +
 +			break;
 +		}
 +
 +		case WM_MOUSEMOVE:
 +		{
 +			MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
 +			Protocol *proto = GetCurrentProtocol();
 +			if (proto == NULL)
 +				break;
 +
 +			if (!data->tracking_exit)
 +			{
 +				TRACKMOUSEEVENT tme;
 +				tme.cbSize = sizeof(TRACKMOUSEEVENT);
 +				tme.dwFlags = TME_LEAVE;
 +				tme.hwndTrack = hwnd;
 +				tme.dwHoverTime = HOVER_DEFAULT;
 +				TrackMouseEvent(&tme);
 +
 +				data->tracking_exit = true;
 +			}
 +
 +			POINT p;
 +			p.x = LOWORD(lParam); 
 +			p.y = HIWORD(lParam); 
 +
 +			bool changed = false;
 +			for(size_t i = 0; i < data->items.size(); ++i)
 +				changed = changed || data->items[i]->setMouseOver(&p);
 +
 +			if (changed)
 +				InvalidateRect(hwnd, NULL, FALSE);
 +
 +			break;
 +		}
 +
 +		case WM_NOTIFY:
 +		{
 +			LPNMHDR lpnmhdr = (LPNMHDR) lParam;
 +
 +			int i = (int) lpnmhdr->code;
 +
 +			switch (lpnmhdr->code) {
 +				case TTN_GETDISPINFO:
 +				{
 +					MyDetailsFrameData *data = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
 +
 +					LPNMTTDISPINFO lpttd = (LPNMTTDISPINFO) lpnmhdr;
 +					SendMessage(lpnmhdr->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 300);
 +					
 +					for(int i = 0; i < data->items.size(); i++)
 +					{
 +						lpttd->lpszText = (char *) data->items[i]->getToolTipFor(lpnmhdr->hwndFrom);
 +						if (lpttd->lpszText != NULL)
 +							break;
 +					}
 +
 +					return 0;
 +				}
 +			}
 +
 +			break;
 +		}
 +
 +		case WM_DESTROY:
 +		{
 +			KillTimer(hwnd, ID_FRAME_TIMER);
 +
 +			MyDetailsFrameData *tmp = (MyDetailsFrameData *)GetWindowLong(hwnd, GWL_USERDATA);
 +			if (tmp != NULL) delete tmp;
 +
 +			break;
 +		}
 +
 +		// Custom Messages //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 +
 +		case MWM_REFRESH:
 +		{
 +			KillTimer(hwnd, ID_RECALC_TIMER);
 +			SetTimer(hwnd, ID_RECALC_TIMER, RECALC_TIME, NULL);
 +			break;
 +		}
 +
 +		case MWM_REFRESH_DATA:
 +		{
 +			Protocol *proto = GetCurrentProtocol(false);
 +			if (proto)
 +			{
 +				proto->UpdateAll();
 +				RedrawFrame();
 +			}
 +			break;
 +		}
 +	}
 +
 +	return DefWindowProc(hwnd, msg, wParam, lParam);
 +}
 +
 +
 +int ShowHideFrameFunc(WPARAM wParam, LPARAM lParam) 
 +{
 +	if (ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) 
 +	{
 +		CallService(MS_CLIST_FRAMES_SHFRAME, frame_id, 0);
 +	}
 +	else
 +	{
 +		if (MyDetailsFrameVisible())
 +		{
 +			SendMessage(hwnd_container, WM_CLOSE, 0, 0);
 +		}
 +		else 
 +		{
 +			ShowWindow(hwnd_container, SW_SHOW);
 +			DBWriteContactSettingByte(0, MODULE_NAME, SETTING_FRAME_VISIBLE, 1);
 +		}
 +
 +		FixMainMenu();
 +	}
 +	return 0;
 +}
 +
 +
 +int ShowFrameFunc(WPARAM wParam, LPARAM lParam)
 +{
 +	if (ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) 
 +	{
 +		int flags = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, frame_id), 0);
 +		if(!(flags & F_VISIBLE)) 
 +			CallService(MS_CLIST_FRAMES_SHFRAME, frame_id, 0);
 +	}
 +	else
 +	{
 +		if (!MyDetailsFrameVisible())
 +		{
 +			ShowWindow(hwnd_container, SW_SHOW);
 +			DBWriteContactSettingByte(0, MODULE_NAME, SETTING_FRAME_VISIBLE, 1);
 +
 +			FixMainMenu();
 +		}
 +
 +	}
 +	return 0;
 +}
 +
 +
 +int HideFrameFunc(WPARAM wParam, LPARAM lParam)
 +{
 +	if (ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) 
 +	{
 +		int flags = CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLAGS, frame_id), 0);
 +		if (flags & F_VISIBLE) 
 +			CallService(MS_CLIST_FRAMES_SHFRAME, frame_id, 0);
 +	}
 +	else
 +	{
 +		if (MyDetailsFrameVisible())
 +		{
 +			SendMessage(hwnd_container, WM_CLOSE, 0, 0);
 +
 +			FixMainMenu();
 +		}
 +	}
 +	return 0;
 +}
 +
 +
 +void FixMainMenu() 
 +{
 +	CLISTMENUITEM mi = {0};
 +	mi.cbSize = sizeof(CLISTMENUITEM);
 +	mi.flags = CMIM_NAME;
 +
 +	if(MyDetailsFrameVisible())
 +		mi.pszName = Translate("Hide My Details");
 +	else
 +		mi.pszName = Translate("Show My Details");
 +
 +	CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuShowHideFrame, (LPARAM)&mi);
 +}
 +
 +#include <math.h>
 +
 +void RedrawFrame() 
 +{
 +	if (frame_id == -1) 
 +	{
 +		InvalidateRect(hwnd_container, NULL, TRUE);
 +	}
 +	else
 +	{
 +		CallService(MS_CLIST_FRAMES_UPDATEFRAME, (WPARAM)frame_id, (LPARAM)FU_TBREDRAW | FU_FMREDRAW);
 +	}
 +}
 +
 +void UpdateFrameData() 
 +{
 +	if (hwnd_frame != NULL)
 +		PostMessage(hwnd_frame, MWM_REFRESH, 0, 0);
 +}
 +
 +// only used when no multiwindow functionality is available
 +BOOL MyDetailsFrameVisible() 
 +{
 +	return IsWindowVisible(hwnd_container) ? true : false;
 +}
 +
 +void SetMyDetailsFrameVisible(BOOL visible) 
 +{
 +	if (frame_id == -1 && hwnd_container != 0) 
 +	{
 +		ShowWindow(hwnd_container, visible ? SW_SHOW : SW_HIDE);
 +	}
 +}
 +
 +void SetCycleTime()
 +{
 +	if (hwnd_frame != NULL)
 +		SetCycleTime(hwnd_frame);
 +}
 +
 +void SetCycleTime(HWND hwnd)
 +{
 +	KillTimer(hwnd, ID_FRAME_TIMER);
 +
 +	if (opts.cycle_through_protocols)
 +		SetTimer(hwnd, ID_FRAME_TIMER, opts.seconds_to_show_protocol * 1000, 0);
 +}
 +
 +void SetStatusMessageRefreshTime()
 +{
 +	if (hwnd_frame != NULL)
 +		SetStatusMessageRefreshTime(hwnd_frame);
 +}
 +
 +void SetStatusMessageRefreshTime(HWND hwnd)
 +{
 +	KillTimer(hwnd, ID_STATUSMESSAGE_TIMER);
 +
 +	opts.refresh_status_message_timer = DBGetContactSettingWord(NULL, "MyDetails", "RefreshStatusMessageTimer",5);
 +	if (opts.refresh_status_message_timer > 0)
 +	{
 +		SetTimer(hwnd, ID_STATUSMESSAGE_TIMER, opts.refresh_status_message_timer * 1000, NULL);
 +	}
 +}
 +
 +int PluginCommand_ShowNextProtocol(WPARAM wParam,LPARAM lParam)
 +{
 +	if (hwnd_frame == NULL)
 +		return -1;
 +
 +	SetCurrentProtocol(GetCurrentProtocolIndex() + 1);
 +
 +	SetCycleTime();
 +
 +	RedrawFrame();
 +
 +	return 0;
 +}
 +
 +int PluginCommand_ShowPreviousProtocol(WPARAM wParam,LPARAM lParam)
 +{
 +	if (hwnd_frame == NULL)
 +		return -1;
 +
 +	SetCurrentProtocol(GetCurrentProtocolIndex() - 1);
 +
 +	SetCycleTime();
 +
 +	RedrawFrame();
 +
 +	return 0;
 +}
 +
 +int PluginCommand_ShowProtocol(WPARAM wParam,LPARAM lParam)
 +{
 +	char * proto = (char *)lParam;
 +
 +	if (proto == NULL)
 +		return -1;
 +
 +	int proto_num = GetProtocolIndexByName(proto);
 +	if (proto_num == -1)
 +		return -2;
 +
 +	if (hwnd_frame == NULL)
 +		return -3;
 +
 +	SetCurrentProtocol(proto_num);
 +
 +	SetCycleTime();
 +
 +	RedrawFrame();
 +
 +	return 0;
 +}
 +
 +int SettingsChangedHook(WPARAM wParam, LPARAM lParam) 
 +{
 +	if (hwnd_frame == NULL)
 +		return 0;
 +
 +	DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam;
 +
 +	if (wParam != NULL)
 +		return 0;
 +	
 +	if (strstr(cws->szModule,"Away"))
 +	{
 +		// Status message changed
 +		UpdateFrameData();
 +		return 0;
 +	}
 +	
 +	Protocol *proto = GetCurrentProtocol(false);
 +	if (proto == NULL || strcmp(proto->GetName(), cws->szModule) != 0)
 +		return 0;
 +
 +	if (!strcmp(cws->szSetting,"Status")
 +			|| !strcmp(cws->szSetting,"StatusMood")
 +			|| !strcmp(cws->szSetting,"XStatusName")
 +			|| !strcmp(cws->szSetting,"XStatusMsg")
 +			|| !strcmp(cws->szSetting,"XStatusId")
 +			|| ( proto->GetCustomStatus() != 0 && !strcmp(cws->szSetting, proto->GetCustomStatusNameKey()) )
 +			|| ( proto->GetCustomStatus() != 0 && !strcmp(cws->szSetting, proto->GetCustomStatusMessageKey()) ))
 +	{
 +		// Status changed
 +		UpdateFrameData();
 +	}
 +	else if(!strcmp(cws->szSetting,"MyHandle")
 +			|| !strcmp(cws->szSetting,"UIN") 
 +			|| !strcmp(cws->szSetting,"Nick") 
 +			|| !strcmp(cws->szSetting,"FirstName") 
 +			|| !strcmp(cws->szSetting,"e-mail") 
 +			|| !strcmp(cws->szSetting,"LastName") 
 +			|| !strcmp(cws->szSetting,"JID"))
 +	{
 +		// Name changed
 +		UpdateFrameData();
 +	}
 +	else if (strcmp(cws->szSetting,"ListeningTo") == 0)
 +	{
 +		UpdateFrameData();
 +	}
 +	else if (strcmp(cws->szSetting,"LockMainStatus") == 0)
 +	{
 +		UpdateFrameData();
 +	}
 +
 +	return 0;
 +}
 +
 +int AvatarChangedHook(WPARAM wParam, LPARAM lParam) 
 +{
 +	if (hwnd_frame == NULL)
 +		return 0;
 +
 +	Protocol *proto = GetCurrentProtocol(false);
 +	if (proto == NULL || strcmp(proto->GetName(), (const char *) wParam) != 0)
 +		return 0;
 +
 +	UpdateFrameData();
 +
 +	return 0;
 +}
 +
 +int ProtoAckHook(WPARAM wParam, LPARAM lParam)
 +{
 +	if (hwnd_frame == NULL)
 +		return 0;
 +
 +	ACKDATA *ack = (ACKDATA*) lParam;
 +	if (ack->hContact != NULL)
 +		return 0;
 +
 +	Protocol *proto = GetCurrentProtocol(false);
 +	if (proto == NULL || strcmp(proto->GetName(), ack->szModule) != 0)
 +		return 0;
 +
 +	if (ack->type == ACKTYPE_STATUS) 
 +	{
 +		UpdateFrameData();
 +	}
 +	else if (ack->type == ACKTYPE_AWAYMSG)
 +	{
 +		UpdateFrameData();
 +	}
 +	else if (ack->type == ACKTYPE_EMAIL)
 +	{
 +		UpdateFrameData();
 +	}
 +
 +	return 0;
 +}
 +
 +int ListeningtoEnableStateChangedHook(WPARAM wParam,LPARAM lParam)
 +{
 +	if (hwnd_frame == NULL)
 +		return 0;
 +
 +	Protocol *proto = GetCurrentProtocol(false);
 +	if (proto == NULL || strcmp(proto->GetName(), (const char *) wParam) != 0)
 +		return 0;
 +
 +	UpdateFrameData();
 +
 +	return 0;
 +}
 +
 +int AccListChanged(WPARAM wParam, LPARAM lParam)
 +{
 +	SetCurrentProtocol(0);
 +
 +	RedrawFrame();
 +
 +	return 0;
 +}
 diff --git a/plugins/MyDetails/frame.h b/plugins/MyDetails/frame.h new file mode 100644 index 0000000000..58aa800090 --- /dev/null +++ b/plugins/MyDetails/frame.h @@ -0,0 +1,38 @@ +/* 
 +Copyright (C) 2005 Ricardo Pescuma Domenecci
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt.  If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA.  
 +*/
 +
 +
 +#ifndef __FRAME_H__
 +# define __FRAME_H__
 +
 +
 +void InitFrames();
 +void DeInitFrames();
 +
 +void UpdateFrameData();
 +void RedrawFrame();
 +
 +void SetCycleTime();
 +
 +int PluginCommand_ShowNextProtocol(WPARAM wParam,LPARAM lParam);
 +int PluginCommand_ShowPreviousProtocol(WPARAM wParam,LPARAM lParam);
 +int PluginCommand_ShowProtocol(WPARAM wParam,LPARAM lParam);
 +
 +
 +#endif // __FRAME_H__
\ No newline at end of file diff --git a/plugins/MyDetails/mydetails.cpp b/plugins/MyDetails/mydetails.cpp new file mode 100644 index 0000000000..9351765f6c --- /dev/null +++ b/plugins/MyDetails/mydetails.cpp @@ -0,0 +1,992 @@ +/* 
 +Copyright (C) 2005 Ricardo Pescuma Domenecci
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt.  If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA.  
 +*/
 +
 +
 +#include "commons.h"
 +#include "mydetails.h"
 +
 +
 +// Prototypes /////////////////////////////////////////////////////////////////////////////////////
 +
 +
 +HINSTANCE hInst;
 +PLUGINLINK *pluginLink;
 +
 +PLUGININFOEX pluginInfo={
 +	sizeof(PLUGININFOEX),
 +	"My Details",
 +	PLUGIN_MAKE_VERSION(0,0,2,6),
 +	"Show and allows you to edit your details for all protocols.",
 +	"Ricardo Pescuma Domenecci, Drugwash",
 +	"",
 +	"© 2005-2010 Ricardo Pescuma Domenecci, Drugwash",
 +	"http://pescuma.org/miranda/mydetails",
 +	0,		//not transient
 +	0,		//doesn't replace anything built-in
 +	{ 0xa82baeb3, 0xa33c, 0x4036, { 0xb8, 0x37, 0x78, 0x3, 0xa5, 0xb6, 0xc2, 0xab } } // {A82BAEB3-A33C-4036-B837-7803A5B6C2AB}
 +};
 +
 +
 +struct MM_INTERFACE mmi;
 +struct UTF8_INTERFACE utfi;
 +struct SKIN_INTERFACE mski;
 +
 +
 +HANDLE hTTB = NULL;
 +
 +// Hooks
 +HANDLE hModulesLoadedHook = NULL;
 +HANDLE hPreShutdownHook = NULL;
 +HANDLE hColorChangedHook = NULL;
 +
 +long nickname_dialog_open;
 +HWND hwndSetNickname;
 +
 +long status_msg_dialog_open;
 +HWND hwndSetStatusMsg;
 +
 +SkinDialog *dialog;
 +
 +
 +// Hook called after init
 +static int MainInit(WPARAM wparam,LPARAM lparam);
 +static int MainUninit(WPARAM wParam, LPARAM lParam);
 +
 +
 +// Services
 +static int PluginCommand_SetMyNicknameUI(WPARAM wParam,LPARAM lParam);
 +static int PluginCommand_SetMyNickname(WPARAM wParam,LPARAM lParam);
 +static int PluginCommand_GetMyNickname(WPARAM wParam,LPARAM lParam);
 +static int PluginCommand_SetMyAvatarUI(WPARAM wParam,LPARAM lParam);
 +static int PluginCommand_SetMyAvatar(WPARAM wParam,LPARAM lParam);
 +static int PluginCommand_GetMyAvatar(WPARAM wParam,LPARAM lParam);
 +static int PluginCommand_SetMyStatusMessageUI(WPARAM wParam,LPARAM lParam);
 +static int PluginCommand_CicleThroughtProtocols(WPARAM wParam,LPARAM lParam);
 +
 +
 +
 +
 +// Functions //////////////////////////////////////////////////////////////////////////////////////
 +
 +
 +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
 +{
 +	hInst = hinstDLL;
 +	return TRUE;
 +}
 +
 +
 +extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) 
 +{
 +	pluginInfo.cbSize = sizeof(PLUGININFO);
 +	return (PLUGININFO*) &pluginInfo;
 +}
 +
 +
 +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
 +{
 +	pluginInfo.cbSize = sizeof(PLUGININFOEX);
 +	return &pluginInfo;
 +}
 +
 +
 +static const MUUID interfaces[] = { MIID_MDETAILS, MIID_LAST };
 +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
 +{
 +	return interfaces;
 +}
 +
 +
 +int __declspec(dllexport) Load(PLUGINLINK *link)
 +{
 +	// Copy data
 +	pluginLink = link;
 +
 +	// CHECK_VERSION("My Details")
 +
 +	mir_getMMI(&mmi);
 +	mir_getUTFI(&utfi);
 +
 +	init_list_interface();
 +
 +	// Hook event to load messages and show first one
 +	hModulesLoadedHook = HookEvent(ME_SYSTEM_MODULESLOADED, MainInit);
 +	hPreShutdownHook = HookEvent(ME_SYSTEM_PRESHUTDOWN, MainUninit);
 +
 +	nickname_dialog_open = 0;
 +	status_msg_dialog_open = 0;
 +
 +	// Options
 +	InitOptions();
 +
 +	// Register services
 +	CreateServiceFunction(MS_MYDETAILS_SETMYNICKNAME, PluginCommand_SetMyNickname);
 +	CreateServiceFunction(MS_MYDETAILS_SETMYNICKNAMEUI, PluginCommand_SetMyNicknameUI);
 +	CreateServiceFunction(MS_MYDETAILS_SETMYAVATAR, PluginCommand_SetMyAvatar);
 +	CreateServiceFunction(MS_MYDETAILS_SETMYAVATARUI, PluginCommand_SetMyAvatarUI);
 +	CreateServiceFunction(MS_MYDETAILS_GETMYNICKNAME, PluginCommand_GetMyNickname);
 +	CreateServiceFunction(MS_MYDETAILS_GETMYAVATAR, PluginCommand_GetMyAvatar);
 +	CreateServiceFunction(MS_MYDETAILS_SETMYSTATUSMESSAGEUI, PluginCommand_SetMyStatusMessageUI);
 +	CreateServiceFunction(MS_MYDETAILS_SHOWNEXTPROTOCOL, PluginCommand_ShowNextProtocol);
 +	CreateServiceFunction(MS_MYDETAILS_SHOWPREVIOUSPROTOCOL, PluginCommand_ShowPreviousProtocol);
 +	CreateServiceFunction(MS_MYDETAILS_SHOWPROTOCOL, PluginCommand_ShowProtocol);
 +	CreateServiceFunction(MS_MYDETAILS_CYCLE_THROUGH_PROTOCOLS, PluginCommand_CicleThroughtProtocols);
 +
 +	return 0;
 +}
 +
 +
 +int __declspec(dllexport) Unload(void)
 +{
 +	DestroyServiceFunction(MS_MYDETAILS_SETMYNICKNAME);
 +	DestroyServiceFunction(MS_MYDETAILS_SETMYNICKNAMEUI);
 +	DestroyServiceFunction(MS_MYDETAILS_SETMYAVATAR);
 +	DestroyServiceFunction(MS_MYDETAILS_SETMYAVATARUI);
 +	DestroyServiceFunction(MS_MYDETAILS_GETMYNICKNAME);
 +	DestroyServiceFunction(MS_MYDETAILS_GETMYAVATAR);
 +	DestroyServiceFunction(MS_MYDETAILS_SETMYSTATUSMESSAGEUI);
 +	DestroyServiceFunction(MS_MYDETAILS_SHOWNEXTPROTOCOL);
 +	DestroyServiceFunction(MS_MYDETAILS_SHOWPREVIOUSPROTOCOL);
 +	DestroyServiceFunction(MS_MYDETAILS_SHOWPROTOCOL);
 +	DestroyServiceFunction(MS_MYDETAILS_CYCLE_THROUGH_PROTOCOLS);
 +
 +	if (hModulesLoadedHook) UnhookEvent(hModulesLoadedHook);
 +
 +	DeInitProtocolData();
 +	DeInitOptions();
 +
 +	return 0;
 +}
 +
 +
 +static int Menu_SetMyAvatarUI(WPARAM wParam,LPARAM lParam)
 +{
 +	return PluginCommand_SetMyAvatarUI(0, 0);
 +}
 +static int Menu_SetMyNicknameUI(WPARAM wParam,LPARAM lParam)
 +{
 +	return PluginCommand_SetMyNicknameUI(0, 0);
 +}
 +static int Menu_SetMyStatusMessageUI(WPARAM wParam,LPARAM lParam)
 +{
 +	return PluginCommand_SetMyStatusMessageUI(0, 0);
 +}
 +
 +static void SkinChanged(void *param, SKINNED_DIALOG dlg)
 +{
 +	RedrawFrame();
 +}
 +
 +
 +static int ColorChanged(WPARAM wparam, LPARAM lparam)
 +{
 +	ColourID cid = {0};
 +	cid.cbSize = sizeof(ColourID);
 +	lstrcpynA(cid.group, "My Details", sizeof(cid.group));
 +	lstrcpynA(cid.name, "Background", sizeof(cid.name));
 +
 +	opts.bkg_color = (COLORREF) CallService(MS_COLOUR_GET, (WPARAM) &cid, 0);
 +
 +	RedrawFrame();
 +
 +	return 0;
 +}
 +
 +
 +// Hook called after init
 +static int MainInit(WPARAM wparam,LPARAM lparam) 
 +{	
 +	if ( mir_skins_getInterface(&mski) != 0 )
 +	{
 +		MessageBox(NULL, _T("MyDetails needs Skins plugin in order to work"), _T("MyDetails"), MB_OK | MB_ICONERROR);
 +		return 0;
 +	}
 +		
 +	if (CallService(MS_SKIN2_GETICON, 0, (LPARAM) "LISTENING_TO_ICON") == NULL) 
 +	{
 +		SKINICONDESC sid = {0};
 +		sid.cbSize = sizeof(SKINICONDESC);
 +		sid.ptszSection = "Contact List";
 +		sid.ptszDescription = "Listening to";
 +		sid.pszName = "LISTENING_TO_ICON";
 +		sid.hDefaultIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_LISTENINGTO));
 +		CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
 +	}
 +	
 +	{
 +		SKINICONDESC sid = {0};
 +		sid.cbSize = sizeof(SKINICONDESC);
 +		sid.ptszSection = "My Details";
 +		sid.ptszDescription = "Email";
 +		sid.pszName = "MYDETAILS_EMAIL";
 +		sid.hDefaultIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_EMAIL));
 +		CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
 +	}
 +
 +	{
 +		SKINICONDESC sid = {0};
 +		sid.cbSize = sizeof(SKINICONDESC);
 +		sid.ptszSection = "My Details";
 +		sid.ptszDescription = "Previous protocol";
 +		sid.pszName = "MYDETAILS_PREV_PROTOCOL";
 +		sid.hDefaultIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_LEFT_ARROW));
 +		CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
 +	}
 +	
 +	{
 +		SKINICONDESC sid = {0};
 +		sid.cbSize = sizeof(SKINICONDESC);
 +		sid.ptszSection = "My Details";
 +		sid.ptszDescription = "Next protocol";
 +		sid.pszName = "MYDETAILS_NEXT_PROTOCOL";
 +		sid.hDefaultIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_RIGHT_ARROW));
 +		CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
 +	}
 +
 +	{
 +		ColourID cid = {0};
 +		cid.cbSize = sizeof(ColourID);
 +		lstrcpynA(cid.group, "My Details", sizeof(cid.group));
 +		lstrcpynA(cid.name, "Background", sizeof(cid.name));
 +		lstrcpynA(cid.dbSettingsGroup, MODULE_NAME, sizeof(cid.dbSettingsGroup));
 +		lstrcpynA(cid.setting, "BackgroundColor", sizeof(cid.setting));
 +		cid.defcolour = GetSysColor(COLOR_BTNFACE);
 +
 +		CallService(MS_COLOUR_REGISTER, (WPARAM) &cid, 0);
 +
 +		ColorChanged(0,0);
 +
 +		hColorChangedHook = HookEvent(ME_COLOUR_RELOAD, ColorChanged);
 +	}
 +	
 +	dialog = new SkinDialog("MyDetails", "My Details", MODULE_NAME);
 +	if (!dialog->isValid())
 +	{
 +		MessageBox(NULL, _T("MyDetails could not create dialog. Check if default skin is installed"), _T("MyDetails"), MB_OK | MB_ICONERROR);
 +		return 0;
 +	}
 +
 +	dialog->addImageField("avatar", "Avatar");
 +	dialog->addTextField("nickname", "Nickname");
 +	dialog->addTextField("protocol", "Protocol");
 +	dialog->addIconField("email_icon", "Unread Email Count Icon");
 +	dialog->addTextField("email", "Unread Email Count");
 +	dialog->addIconField("status_icon", "Status Icon");
 +	dialog->addTextField("status_name", "Status");
 +	dialog->addTextField("status_msg", "Status Message");
 +	dialog->addIconField("listening_icon", "Listening To Icon");
 +	dialog->addTextField("listening", "Listening To");
 +	dialog->addIconField("next_proto", "Next Protocol");
 +	dialog->addIconField("prev_proto", "Previous Protocol");
 +	dialog->setSkinChangedCallback(SkinChanged, NULL);
 +	dialog->finishedConfiguring();
 +
 +
 +	InitProtocolData();
 +
 +	// Add options to menu
 +	CLISTMENUITEM mi;
 +
 +	if (protocols->CanSetAvatars())
 +	{
 +		ZeroMemory(&mi,sizeof(mi));
 +		mi.cbSize = sizeof(mi);
 +		mi.flags = 0;
 +		mi.popupPosition = 500050000;
 +		mi.pszPopupName = Translate("My Details");
 +		mi.position = 100001;
 +		mi.pszName = Translate("Set My Avatar...");
 +		CreateServiceFunction("MENU_" MS_MYDETAILS_SETMYAVATARUI, Menu_SetMyAvatarUI);
 +		mi.pszService = "MENU_" MS_MYDETAILS_SETMYAVATARUI;
 +
 +		CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
 +	}
 +
 +	ZeroMemory(&mi,sizeof(mi));
 +	mi.cbSize = sizeof(mi);
 +	mi.flags = 0;
 +	mi.popupPosition = 500050000;
 +	mi.pszPopupName = Translate("My Details");
 +	mi.position = 100002;
 +	mi.pszName = Translate("Set My Nickname...");
 +	CreateServiceFunction("MENU_" MS_MYDETAILS_SETMYNICKNAMEUI, Menu_SetMyNicknameUI);
 +	mi.pszService = "MENU_" MS_MYDETAILS_SETMYNICKNAMEUI;
 +
 +	CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
 +
 +	ZeroMemory(&mi,sizeof(mi));
 +	mi.cbSize = sizeof(mi);
 +	mi.flags = 0;
 +	mi.popupPosition = 500050000;
 +	mi.pszPopupName = Translate("My Details");
 +	mi.position = 100003;
 +	mi.pszName = Translate("Set My Status Message...");
 +	CreateServiceFunction("MENU_" MS_MYDETAILS_SETMYSTATUSMESSAGEUI, Menu_SetMyStatusMessageUI);
 +	mi.pszService = "MENU_" MS_MYDETAILS_SETMYSTATUSMESSAGEUI;
 +
 +	CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
 +
 +	// Set protocols to show frame
 +	ZeroMemory(&mi,sizeof(mi));
 +	mi.cbSize = sizeof(mi);
 +	mi.flags = 0;
 +	mi.popupPosition = 500050000;
 +	mi.pszPopupName = Translate("My Details");
 +	mi.position = 200001;
 +	mi.pszName = Translate("Show next protocol");
 +	mi.pszService = MS_MYDETAILS_SHOWNEXTPROTOCOL;
 +
 +	CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
 +
 +	InitFrames();
 +
 +    // updater plugin support
 +    if(ServiceExists(MS_UPDATE_REGISTER))
 +	{
 +		Update upd = {0};
 +		char szCurrentVersion[30];
 +
 +		upd.cbSize = sizeof(upd);
 +		upd.szComponentName = pluginInfo.shortName;
 +
 +		upd.szUpdateURL = UPDATER_AUTOREGISTER;
 +
 +		upd.szBetaVersionURL = "http://svn.berlios.de/svnroot/repos/mgoodies/trunk/mydetails/Docs/mydetails_version.txt";
 +		upd.szBetaChangelogURL = "http://svn.berlios.de/svnroot/repos/mgoodies/trunk/mydetails/Docs/mydetails_changelog.txt";
 +		upd.pbBetaVersionPrefix = (BYTE *)"My Details ";
 +		upd.cpbBetaVersionPrefix = strlen((char *)upd.pbBetaVersionPrefix);
 +		upd.szBetaUpdateURL = "http://pescuma.googlecode.com/files/mydetails.%VERSION%.zip";
 +
 +		upd.pbVersion = (BYTE *)CreateVersionStringPlugin((PLUGININFO*) &pluginInfo, szCurrentVersion);
 +		upd.cpbVersion = strlen((char *)upd.pbVersion);
 +
 +        CallService(MS_UPDATE_REGISTER, 0, (LPARAM)&upd);
 +	}
 +
 +    return 0;
 +}
 +
 +static int MainUninit(WPARAM wParam, LPARAM lParam) 
 +{
 +	DeInitFrames();
 +	
 +	delete dialog;
 +
 +	return 0;
 +}
 +
 +// Set nickname ///////////////////////////////////////////////////////////////////////////////////
 +
 +#define WMU_SETDATA (WM_USER+1)
 +
 +static BOOL CALLBACK DlgProcSetNickname(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 +{
 +	switch ( msg )
 +	{
 +		case WM_INITDIALOG:
 +		{
 +			TranslateDialogDefault(hwndDlg);
 +			SendMessage(GetDlgItem(hwndDlg, IDC_NICKNAME), EM_LIMITTEXT, 
 +					MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE - 1, 0);
 +
 +			return TRUE;
 +		}
 +
 +		case WMU_SETDATA:
 +		{
 +			int proto_num = (int)wParam;
 +
 +			SetWindowLong(hwndDlg, GWL_USERDATA, proto_num);
 +
 +			if (proto_num == -1)
 +			{
 +				SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_MIRANDA));
 +
 +				// All protos have the same nick?
 +				
 +				std::vector<Protocol> protos;
 +				GetProtocols(&protos);
 +
 +				int protosSize = protos.size();
 +				if (protosSize > 0)
 +				{
 +					std::string nick = protos[0].GetNick();
 +
 +					bool foundDefNick = true;
 +					for(int i = 1; i < protosSize; i++)
 +					{
 +						if (stricmp(protos[i].GetNick(), nick.c_str()) != 0)
 +						{
 +							foundDefNick = false;
 +							break;
 +						}
 +					}
 +
 +					if (foundDefNick)
 +					{
 +						if (stricmp(protocols->default_nick, nick.c_str()) != 0)
 +							lstrcpy(protocols->default_nick, nick.c_str());
 +					}
 +				}
 +
 +				SetDlgItemText(hwndDlg, IDC_NICKNAME, protocols->default_nick);
 +				SendDlgItemMessage(hwndDlg, IDC_NICKNAME, EM_LIMITTEXT, MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE, 0);
 +			}
 +			else
 +			{
 +				Protocol proto = GetProtocolByIndex(proto_num);
 +
 +				char tmp[128];
 +				mir_snprintf(tmp, sizeof(tmp), Translate("Set My Nickname for %s"), proto.GetDescription());
 +
 +				SendMessage(hwndDlg, WM_SETTEXT, 0, (LPARAM)tmp);
 +
 +				HICON hIcon = (HICON) proto.Call(PS_LOADICON, PLI_PROTOCOL);
 +				if (hIcon != NULL)
 +				{
 +					SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
 +					DestroyIcon(hIcon);
 +				}
 +
 +				SetDlgItemText(hwndDlg, IDC_NICKNAME, proto.GetNick());
 +				SendDlgItemMessage(hwndDlg, IDC_NICKNAME, EM_LIMITTEXT, 
 +						min(MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE, proto.GetNickMaxLength()), 0);
 +			}
 +
 +			return TRUE;
 +		}
 +
 +		case WM_COMMAND:
 +			switch(wParam)
 +			{
 +				case IDOK:
 +				{
 +					char tmp[MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE];
 +					GetDlgItemText(hwndDlg, IDC_NICKNAME, tmp, sizeof(tmp));
 +
 +					int proto_num = (int) GetWindowLong(hwndDlg, GWL_USERDATA);
 +					if (proto_num == -1)
 +					{
 +						protocols->SetNicks(tmp);
 +					}
 +					else
 +					{
 +						GetProtocolByIndex(proto_num).SetNick(tmp);
 +					}
 +
 +					DestroyWindow(hwndDlg);
 +					break;
 +				}
 +				case IDCANCEL:
 +				{
 + 					DestroyWindow(hwndDlg);
 +					break;
 +				}
 +			}
 +			break;
 +
 +		case WM_CLOSE:
 +			DestroyWindow(hwndDlg);
 +			break;
 +
 +		case WM_DESTROY:
 +			InterlockedExchange(&nickname_dialog_open, 0);
 +			break;
 +	}
 +	
 +	return FALSE;
 +}
 +
 +static int PluginCommand_SetMyNicknameUI(WPARAM wParam,LPARAM lParam)
 +{
 +	char * proto = (char *)lParam;
 +	int proto_num = -1;
 +
 +	if (proto != NULL)
 +	{
 +		proto_num = GetProtocolIndexByName(proto);
 +		if (proto_num == -1)
 +			return -1;
 +
 +		if (!GetProtocolByIndex(proto_num).CanSetNick())
 +			return -2;
 +	}
 +
 +	if (!nickname_dialog_open) 
 +	{
 +		InterlockedExchange(&nickname_dialog_open, 1);
 +
 +		hwndSetNickname = CreateDialog(hInst, MAKEINTRESOURCE( IDD_SETNICKNAME ), NULL, DlgProcSetNickname );
 +		
 +		SendMessage(hwndSetNickname, WMU_SETDATA, proto_num, 0);
 +	}
 +
 +	SetForegroundWindow( hwndSetNickname );
 +	SetFocus( hwndSetNickname );
 + 	ShowWindow( hwndSetNickname, SW_SHOW );
 +
 +	return 0;
 +}
 +
 +
 +static int PluginCommand_SetMyNickname(WPARAM wParam,LPARAM lParam)
 +{
 +	char * proto = (char *)wParam;
 +
 +	if (proto != NULL)
 +	{
 +		Protocol protocol = GetProtocolByName(proto);
 +		if (!protocol)
 +			return -1;
 +
 +		if (!protocol.CanSetNick())
 +			return -2;
 +
 +		protocol.SetNick((char *)lParam);
 +	}
 +	else
 +	{
 +		protocols->SetNicks((char *)lParam);
 +	}
 +
 +	return 0;
 +}
 +
 +
 +static int PluginCommand_GetMyNickname(WPARAM wParam,LPARAM lParam)
 +{
 +	char * ret = (char *)lParam;
 +	char * proto = (char *)wParam;
 +
 +	if (ret == NULL)
 +		return -1;
 +
 +	if (proto == NULL)
 +	{
 +		if (protocols->default_nick != NULL)
 +			lstrcpyn(ret, protocols->default_nick, MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE);
 +		else
 +			ret[0] = '\0';
 +	}
 +	else
 +	{
 +		Protocol protocol = GetProtocolByName(proto);
 +		if (!protocol)
 +			return -1;
 +		
 +		lstrcpyn(ret, protocol.GetNick(), MS_MYDETAILS_GETMYNICKNAME_BUFFER_SIZE);
 +	}
 +
 +	return 0;
 +}
 +
 +
 +// Set avatar /////////////////////////////////////////////////////////////////////////////////////
 +
 +static int PluginCommand_SetMyAvatarUI(WPARAM wParam,LPARAM lParam)
 +{
 +	char * proto = (char *)lParam;
 +	int proto_num = -1;
 +
 +	if (proto != NULL)
 +	{
 +		Protocol protocol = GetProtocolByName(proto);
 +		if (!protocol)
 +			return -1;
 +
 +		if (!protocol.CanSetAvatar())
 +			return -2;
 +
 +		protocol.SetAvatar(NULL);
 +	}
 +	else
 +	{
 +		protocols->SetAvatars(NULL);
 +	}
 +
 +	return 0;
 +}
 +
 +
 +static int PluginCommand_SetMyAvatar(WPARAM wParam,LPARAM lParam)
 +{
 +	char * proto = (char *)wParam;
 +
 +	if (proto != NULL)
 +	{
 +		Protocol protocol = GetProtocolByName(proto);
 +		if (!protocol)
 +			return -1;
 +		
 +		if (!protocol.CanSetAvatar())
 +			return -2;
 +		
 +		protocol.SetAvatar((char *)lParam);
 +	}
 +	else
 +	{
 +		protocols->SetAvatars((char *)lParam);
 +	}
 +
 +	return 0;
 +}
 +
 +
 +int Status2SkinIcon(int status)
 +{
 +	switch(status) {
 +		case ID_STATUS_AWAY: return SKINICON_STATUS_AWAY;
 +		case ID_STATUS_NA: return SKINICON_STATUS_NA;
 +		case ID_STATUS_DND: return SKINICON_STATUS_DND;
 +		case ID_STATUS_OCCUPIED: return SKINICON_STATUS_OCCUPIED;
 +		case ID_STATUS_FREECHAT: return SKINICON_STATUS_FREE4CHAT;
 +		case ID_STATUS_ONLINE: return SKINICON_STATUS_ONLINE;
 +		case ID_STATUS_OFFLINE: return SKINICON_STATUS_OFFLINE;
 +		case ID_STATUS_INVISIBLE: return SKINICON_STATUS_INVISIBLE;
 +		case ID_STATUS_ONTHEPHONE: return SKINICON_STATUS_ONTHEPHONE;
 +		case ID_STATUS_OUTTOLUNCH: return SKINICON_STATUS_OUTTOLUNCH;
 +		case ID_STATUS_IDLE: return SKINICON_STATUS_AWAY;
 +	}
 +	return SKINICON_STATUS_OFFLINE;
 +}
 +
 +
 +
 +static int PluginCommand_GetMyAvatar(WPARAM wParam,LPARAM lParam)
 +{
 +	char * ret = (char *)lParam;
 +	char * proto = (char *)wParam;
 +
 +	if (ret == NULL)
 +		return -1;
 +
 +	if (proto == NULL)
 +	{
 +		if (protocols->default_avatar_file != NULL)
 +			lstrcpyn(ret, protocols->default_avatar_file, MS_MYDETAILS_GETMYAVATAR_BUFFER_SIZE);
 +		else 
 +			ret[0] = '\0';
 +	}
 +	else
 +	{
 +		Protocol protocol = GetProtocolByName(proto);
 +		if (!protocol)
 +			return -1;
 +		
 +		if (!protocol.CanGetAvatar())
 +			return -2;
 +
 +		lstrcpyn(ret, protocol.GetAvatarFile(), MS_MYDETAILS_GETMYAVATAR_BUFFER_SIZE);
 +	}
 +	
 +	return 0;
 +}
 +
 +static LRESULT CALLBACK StatusMsgEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 +{
 +    switch (msg) {
 +        case WM_CHAR:
 +		{
 +            if(wParam == 0x0a && (GetKeyState(VK_CONTROL) & 0x8000) != 0) {
 +				PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
 +				return 0;
 +			}
 +			
 +			break;
 +		}
 +	}
 +
 +    return CallWindowProc((WNDPROC) GetWindowLong(hwnd, GWL_USERDATA), hwnd, msg, wParam, lParam);
 +}
 +
 +struct SetStatusMessageData {
 +	int status;
 +	int proto_num;
 +};
 +
 +static BOOL CALLBACK DlgProcSetStatusMessage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 +{
 +	switch ( msg )
 +	{
 +		case WM_INITDIALOG:
 +		{
 +			TranslateDialogDefault(hwndDlg);
 +			SendMessage(GetDlgItem(hwndDlg, IDC_STATUSMESSAGE), EM_LIMITTEXT, 
 +					MS_MYDETAILS_GETMYSTATUSMESSAGE_BUFFER_SIZE - 1, 0);
 +
 +			WNDPROC old_proc = (WNDPROC) SetWindowLong(GetDlgItem(hwndDlg, IDC_STATUSMESSAGE), 
 +														GWL_WNDPROC, (LONG) StatusMsgEditSubclassProc);
 +
 +			SetWindowLong(GetDlgItem(hwndDlg, IDC_STATUSMESSAGE), GWL_USERDATA, (long) old_proc);
 +
 +			return TRUE;
 +		}
 +
 +		case WMU_SETDATA:
 +		{
 +			SetStatusMessageData *data = (SetStatusMessageData *) malloc(sizeof(SetStatusMessageData));
 +			data->status = (int)wParam;
 +			data->proto_num = (int)lParam;
 +
 +			SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) data);
 +
 +			if (data->proto_num >= 0)
 +			{
 +				Protocol proto = GetProtocolByIndex(data->proto_num);
 +
 +				HICON hIcon = (HICON) proto.Call(PS_LOADICON, PLI_PROTOCOL);
 +				if (hIcon != NULL)
 +				{
 +					SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
 +					DestroyIcon(hIcon);
 +				}
 +
 +				char title[256];
 +				mir_snprintf(title, sizeof(title), Translate("Set My Status Message for %s"), 
 +					proto.GetDescription());
 +				SendMessage(hwndDlg, WM_SETTEXT, 0, (LPARAM)title);
 +
 +				SetDlgItemText(hwndDlg, IDC_STATUSMESSAGE, proto.GetStatusMsg());
 +			}
 +			else if (data->status != 0)
 +			{
 +				SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedIcon(Status2SkinIcon(data->status)));
 +
 +				char title[256];
 +				mir_snprintf(title, sizeof(title), Translate("Set My Status Message for %s"), 
 +					CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, data->status, 0));
 +				SendMessage(hwndDlg, WM_SETTEXT, 0, (LPARAM)title);
 +
 +				SetDlgItemText(hwndDlg, IDC_STATUSMESSAGE, protocols->GetDefaultStatusMsg(data->status));
 +			}
 +			else
 +			{
 +				SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_MIRANDA));
 +
 +				SetDlgItemText(hwndDlg, IDC_STATUSMESSAGE, protocols->GetDefaultStatusMsg());
 +			}
 +
 +			return TRUE;
 +		}
 +		case WM_COMMAND:
 +			switch(wParam)
 +			{
 +				case IDOK:
 +				{
 +					char tmp[MS_MYDETAILS_GETMYSTATUSMESSAGE_BUFFER_SIZE];
 +					GetDlgItemText(hwndDlg, IDC_STATUSMESSAGE, tmp, sizeof(tmp));
 +
 +					SetStatusMessageData *data = (SetStatusMessageData *) GetWindowLong(hwndDlg, GWL_USERDATA);
 +
 +					if (data->proto_num >= 0)
 +						GetProtocolByIndex(data->proto_num).SetStatusMsg(tmp);
 +					else if (data->status == 0)
 +						protocols->SetStatusMsgs(tmp);
 +					else
 +						protocols->SetStatusMsgs(data->status, tmp);
 +
 +					// To force a refresh
 +					UpdateFrameData();
 +
 +					DestroyWindow(hwndDlg);
 +					break;
 +				}
 +				case IDCANCEL:
 +				{
 + 					DestroyWindow(hwndDlg);
 +					break;
 +				}
 +			}
 +			break;
 +
 +		case WM_CLOSE:
 +			DestroyWindow(hwndDlg);
 +			break;
 +
 +		case WM_DESTROY:
 +			SetWindowLong(GetDlgItem(hwndDlg, IDC_STATUSMESSAGE), GWL_WNDPROC, 
 +						  GetWindowLong(GetDlgItem(hwndDlg, IDC_STATUSMESSAGE), GWL_USERDATA));
 +			free((SetStatusMessageData *) GetWindowLong(hwndDlg, GWL_USERDATA));
 +			InterlockedExchange(&status_msg_dialog_open, 0);
 +			break;
 +	}
 +	
 +	return FALSE;
 +}
 +
 +static int PluginCommand_SetMyStatusMessageUI(WPARAM wParam,LPARAM lParam)
 +{
 +	int status = (int)wParam;
 +	char * proto_name = (char *)lParam;
 +	int proto_num = -1;
 +	Protocol proto(NULL);
 +	TCHAR status_message[256];
 +
 +	if (status != 0 && (status < ID_STATUS_OFFLINE || status > ID_STATUS_OUTTOLUNCH))
 +		return -10;
 +
 +	if (proto_name != NULL)
 +	{
 +		proto_num = GetProtocolIndexByName(proto_name);
 +		if (proto_num == -1)
 +			return -1;
 +
 +		proto = GetProtocolByIndex(proto_num);
 +		if (!proto.CanSetStatusMsg())
 +			return -2;
 +	}
 +
 +	if (ServiceExists(MS_NAS_INVOKESTATUSWINDOW))
 +	{
 +		NAS_ISWINFO iswi;
 +
 +		ZeroMemory(&iswi, sizeof(iswi));
 +
 +		iswi.cbSize = sizeof(NAS_ISWINFO);
 +
 +		if (proto)
 +		{
 +			// Has to get the unparsed message
 +			NAS_PROTOINFO pi;
 +
 +			ZeroMemory(&pi, sizeof(pi));
 +			pi.cbSize = sizeof(NAS_PROTOINFO);
 +			pi.szProto = (char *) proto.GetName();
 +			pi.status = status;
 +			pi.szMsg = NULL;
 +
 +			if (ServiceExists(MS_NAS_GETSTATE))
 +			{
 +				if (CallService(MS_NAS_GETSTATE, (WPARAM) &pi, 1) == 0)
 +				{
 +					if (pi.szMsg == NULL)
 +					{
 +						pi.szProto = NULL;
 +
 +						if (CallService(MS_NAS_GETSTATE, (WPARAM) &pi, 1) == 0)
 +						{
 +							if (pi.szMsg != NULL)
 +							{
 +								lstrcpyn(status_message, pi.szMsg, MAX_REGS(status_message));
 +								mir_free(pi.szMsg);
 +							}
 +						}
 +					}
 +					else // if (pi.szMsg != NULL)
 +					{
 +						lstrcpyn(status_message, pi.szMsg, MAX_REGS(status_message));
 +						mir_free(pi.szMsg);
 +					}
 +				}
 +			}
 +			// TODO: Remove when removing old NAS services support
 +			else
 +			{
 +				NAS_PROTOINFO *pii = π
 +
 +				// Old services
 +				if (CallService("NewAwaySystem/GetState", (WPARAM) &pii, 1) == 0)
 +				{
 +					if (pi.szMsg == NULL)
 +					{
 +						pi.szProto = NULL;
 +
 +						if (CallService("NewAwaySystem/GetState", (WPARAM) &pii, 1) == 0)
 +						{
 +							if (pi.szMsg != NULL)
 +							{
 +								lstrcpyn(status_message, pi.szMsg, MAX_REGS(status_message));
 +								mir_free(pi.szMsg);
 +							}
 +						}
 +					}
 +					else // if (pi.szMsg != NULL)
 +					{
 +						lstrcpyn(status_message, pi.szMsg, MAX_REGS(status_message));
 +						mir_free(pi.szMsg);
 +					}
 +				}
 +			}
 +
 +			iswi.szProto = (char *) proto.GetName();
 +			iswi.szMsg = status_message;
 +		}
 +		else
 +		{
 +			iswi.szMsg = protocols->GetDefaultStatusMsg();
 +		}
 +
 +		iswi.Flags = ISWF_NOCOUNTDOWN;
 +
 +		CallService(MS_NAS_INVOKESTATUSWINDOW, (WPARAM) &iswi, 0);
 +
 +		return 0;
 +	}
 +	else if (ServiceExists(MS_SA_SHOWSTATUSMSGDIALOG))
 +	{
 +		CallService(MS_SA_SHOWSTATUSMSGDIALOG, 0, (LPARAM) proto_name);
 +		return 0;
 +	}
 +	else if (ServiceExists(MS_SA_CHANGESTATUSMSG))
 +	{
 +		if (!proto && status == 0)
 +		{
 +			CallService(MS_SA_CHANGESTATUSMSG, protocols->GetGlobalStatus(), NULL);
 +		}
 +		else if (status == 0)
 +		{
 +			CallService(MS_SA_CHANGESTATUSMSG, proto.GetStatus(), (LPARAM) proto_name);
 +		}
 +		else
 +		{
 +			CallService(MS_SA_CHANGESTATUSMSG, status, (LPARAM) proto_name);
 +		}
 +
 +		return 0;
 +	}
 +	else if (!proto || proto.GetStatus() != ID_STATUS_OFFLINE)
 +	{
 +		if (!status_msg_dialog_open)
 +		{
 +			InterlockedExchange(&status_msg_dialog_open, 1);
 +
 +			hwndSetStatusMsg = CreateDialog(hInst, MAKEINTRESOURCE( IDD_SETSTATUSMESSAGE ), NULL, DlgProcSetStatusMessage );
 +			
 +			SendMessage(hwndSetStatusMsg, WMU_SETDATA, status, proto_num);
 +		}
 +
 +		SetForegroundWindow( hwndSetStatusMsg );
 +		SetFocus( hwndSetStatusMsg );
 + 		ShowWindow( hwndSetStatusMsg, SW_SHOW );
 +
 +		return 0;
 +	}
 +
 +	return -3;
 +}
 +
 +
 +static int PluginCommand_CicleThroughtProtocols(WPARAM wParam,LPARAM lParam)
 +{
 +	DBWriteContactSettingByte(NULL,"MyDetails","CicleThroughtProtocols", (BYTE) wParam);
 +
 +	LoadOptions();
 +
 +	return 0;
 +}
\ No newline at end of file diff --git a/plugins/MyDetails/mydetails.h b/plugins/MyDetails/mydetails.h new file mode 100644 index 0000000000..0780f7335e --- /dev/null +++ b/plugins/MyDetails/mydetails.h @@ -0,0 +1,42 @@ +/* 
 +Copyright (C) 2005 Ricardo Pescuma Domenecci
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt.  If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA.  
 +*/
 +
 +
 +#ifndef __MYDETAILS_H__
 +# define __MYDETAILS_H__
 +
 +
 +extern "C" 
 +{
 +
 +// Dll init
 +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved);
 +
 +// Exports:
 +__declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion);
 +int __declspec(dllexport) Load(PLUGINLINK *link);
 +int __declspec(dllexport) Unload(void);
 +
 +
 +}
 +
 +
 +
 +
 +#endif // __MYDETAILS_H__
\ No newline at end of file diff --git a/plugins/MyDetails/mydetails.vcproj b/plugins/MyDetails/mydetails.vcproj new file mode 100644 index 0000000000..db4b4631a3 --- /dev/null +++ b/plugins/MyDetails/mydetails.vcproj @@ -0,0 +1,642 @@ +<?xml version="1.0" encoding="windows-1251"?> +<VisualStudioProject +	ProjectType="Visual C++" +	Version="7.00" +	Name="mydetails" +	ProjectGUID="{A4855451-6447-437C-B024-B36C3C7901EA}" +	SccProjectName="SAK" +	SccAuxPath="SAK" +	SccLocalPath="SAK" +	SccProvider="SAK"> +	<Platforms> +		<Platform +			Name="Win32"/> +	</Platforms> +	<Configurations> +		<Configuration +			Name="Release|Win32" +			OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins" +			IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)" +			ConfigurationType="2" +			UseOfMFC="0" +			ATLMinimizesCRunTimeLibraryUsage="FALSE" +			CharacterSet="2"> +			<Tool +				Name="VCCLCompilerTool" +				Optimization="3" +				GlobalOptimizations="TRUE" +				InlineFunctionExpansion="1" +				FavorSizeOrSpeed="2" +				AdditionalIncludeDirectories="../../include;sdk" +				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MYDETAILS_EXPORTS" +				StringPooling="TRUE" +				RuntimeLibrary="2" +				EnableFunctionLevelLinking="TRUE" +				UsePrecompiledHeader="3" +				PrecompiledHeaderThrough="commons.h" +				WarningLevel="3" +				SuppressStartupBanner="TRUE" +				CompileAs="0"/> +			<Tool +				Name="VCCustomBuildTool"/> +			<Tool +				Name="VCLinkerTool" +				AdditionalDependencies="comctl32.lib odbc32.lib odbccp32.lib" +				LinkIncremental="1" +				SuppressStartupBanner="TRUE" +				TargetMachine="1"/> +			<Tool +				Name="VCMIDLTool" +				PreprocessorDefinitions="NDEBUG" +				MkTypLibCompatible="TRUE" +				SuppressStartupBanner="TRUE" +				TargetEnvironment="1" +				TypeLibraryName=".\Release/mydetails.tlb" +				HeaderFileName=""/> +			<Tool +				Name="VCPostBuildEventTool"/> +			<Tool +				Name="VCPreBuildEventTool"/> +			<Tool +				Name="VCPreLinkEventTool"/> +			<Tool +				Name="VCResourceCompilerTool" +				PreprocessorDefinitions="NDEBUG" +				Culture="1033"/> +			<Tool +				Name="VCWebServiceProxyGeneratorTool"/> +			<Tool +				Name="VCXMLDataGeneratorTool"/> +			<Tool +				Name="VCWebDeploymentTool"/> +			<Tool +				Name="VCManagedWrapperGeneratorTool"/> +			<Tool +				Name="VCAuxiliaryManagedWrapperGeneratorTool"/> +		</Configuration> +		<Configuration +			Name="Debug|Win32" +			OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins" +			IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)" +			ConfigurationType="2" +			UseOfMFC="0" +			ATLMinimizesCRunTimeLibraryUsage="FALSE" +			CharacterSet="2"> +			<Tool +				Name="VCCLCompilerTool" +				Optimization="0" +				AdditionalIncludeDirectories="../../include;sdk" +				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MYDETAILS_EXPORTS" +				BasicRuntimeChecks="3" +				RuntimeLibrary="2" +				BufferSecurityCheck="TRUE" +				UsePrecompiledHeader="3" +				PrecompiledHeaderThrough="commons.h" +				BrowseInformation="1" +				WarningLevel="3" +				SuppressStartupBanner="TRUE" +				DebugInformationFormat="4" +				CompileAs="0"/> +			<Tool +				Name="VCCustomBuildTool"/> +			<Tool +				Name="VCLinkerTool" +				AdditionalDependencies="comctl32.lib odbc32.lib odbccp32.lib" +				LinkIncremental="2" +				SuppressStartupBanner="TRUE" +				GenerateDebugInformation="TRUE" +				GenerateMapFile="TRUE" +				BaseAddress="0x3EC10000" +				TargetMachine="1"/> +			<Tool +				Name="VCMIDLTool" +				PreprocessorDefinitions="_DEBUG" +				MkTypLibCompatible="TRUE" +				SuppressStartupBanner="TRUE" +				TargetEnvironment="1" +				TypeLibraryName=".\Debug/mydetails.tlb" +				HeaderFileName=""/> +			<Tool +				Name="VCPostBuildEventTool"/> +			<Tool +				Name="VCPreBuildEventTool"/> +			<Tool +				Name="VCPreLinkEventTool"/> +			<Tool +				Name="VCResourceCompilerTool" +				PreprocessorDefinitions="_DEBUG" +				Culture="2057"/> +			<Tool +				Name="VCWebServiceProxyGeneratorTool"/> +			<Tool +				Name="VCXMLDataGeneratorTool"/> +			<Tool +				Name="VCWebDeploymentTool"/> +			<Tool +				Name="VCManagedWrapperGeneratorTool"/> +			<Tool +				Name="VCAuxiliaryManagedWrapperGeneratorTool"/> +		</Configuration> +		<Configuration +			Name="Debug Unicode|Win32" +			OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins" +			IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)" +			ConfigurationType="2" +			UseOfMFC="0" +			ATLMinimizesCRunTimeLibraryUsage="FALSE" +			CharacterSet="2"> +			<Tool +				Name="VCCLCompilerTool" +				Optimization="0" +				AdditionalIncludeDirectories="../../include;sdk" +				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MYDETAILS_EXPORTS" +				BasicRuntimeChecks="3" +				RuntimeLibrary="3" +				BufferSecurityCheck="TRUE" +				UsePrecompiledHeader="3" +				PrecompiledHeaderThrough="commons.h" +				BrowseInformation="1" +				WarningLevel="3" +				SuppressStartupBanner="TRUE" +				DebugInformationFormat="4" +				CompileAs="0"/> +			<Tool +				Name="VCCustomBuildTool"/> +			<Tool +				Name="VCLinkerTool" +				IgnoreImportLibrary="TRUE" +				AdditionalDependencies="comctl32.lib odbc32.lib odbccp32.lib" +				LinkIncremental="2" +				SuppressStartupBanner="TRUE" +				GenerateDebugInformation="TRUE" +				GenerateMapFile="TRUE" +				BaseAddress="0x3EC10000" +				TargetMachine="1"/> +			<Tool +				Name="VCMIDLTool" +				PreprocessorDefinitions="_DEBUG" +				MkTypLibCompatible="TRUE" +				SuppressStartupBanner="TRUE" +				TargetEnvironment="1" +				TypeLibraryName=".\Debug/mydetails.tlb" +				HeaderFileName=""/> +			<Tool +				Name="VCPostBuildEventTool"/> +			<Tool +				Name="VCPreBuildEventTool"/> +			<Tool +				Name="VCPreLinkEventTool"/> +			<Tool +				Name="VCResourceCompilerTool" +				PreprocessorDefinitions="_DEBUG" +				Culture="2057"/> +			<Tool +				Name="VCWebServiceProxyGeneratorTool"/> +			<Tool +				Name="VCXMLDataGeneratorTool"/> +			<Tool +				Name="VCWebDeploymentTool"/> +			<Tool +				Name="VCManagedWrapperGeneratorTool"/> +			<Tool +				Name="VCAuxiliaryManagedWrapperGeneratorTool"/> +		</Configuration> +		<Configuration +			Name="Release Unicode|Win32" +			OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins" +			IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)" +			ConfigurationType="2" +			UseOfMFC="0" +			ATLMinimizesCRunTimeLibraryUsage="FALSE" +			CharacterSet="2" +			WholeProgramOptimization="FALSE"> +			<Tool +				Name="VCCLCompilerTool" +				Optimization="3" +				GlobalOptimizations="TRUE" +				InlineFunctionExpansion="1" +				FavorSizeOrSpeed="2" +				AdditionalIncludeDirectories="../../include;sdk" +				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MYDETAILS_EXPORTS" +				StringPooling="TRUE" +				RuntimeLibrary="2" +				BufferSecurityCheck="TRUE" +				UsePrecompiledHeader="3" +				PrecompiledHeaderThrough="commons.h" +				WarningLevel="3" +				SuppressStartupBanner="TRUE" +				CompileAs="0"/> +			<Tool +				Name="VCCustomBuildTool"/> +			<Tool +				Name="VCLinkerTool" +				IgnoreImportLibrary="TRUE" +				AdditionalDependencies="comctl32.lib odbc32.lib odbccp32.lib" +				GenerateDebugInformation="TRUE" +				GenerateMapFile="TRUE" +				OptimizeReferences="2" +				EnableCOMDATFolding="2" +				OptimizeForWindows98="1" +				TargetMachine="1"/> +			<Tool +				Name="VCMIDLTool" +				PreprocessorDefinitions="NDEBUG" +				MkTypLibCompatible="TRUE" +				SuppressStartupBanner="TRUE" +				TargetEnvironment="1" +				TypeLibraryName=".\Release/mydetails.tlb" +				HeaderFileName=""/> +			<Tool +				Name="VCPostBuildEventTool"/> +			<Tool +				Name="VCPreBuildEventTool"/> +			<Tool +				Name="VCPreLinkEventTool"/> +			<Tool +				Name="VCResourceCompilerTool" +				PreprocessorDefinitions="NDEBUG" +				Culture="1033"/> +			<Tool +				Name="VCWebServiceProxyGeneratorTool"/> +			<Tool +				Name="VCXMLDataGeneratorTool"/> +			<Tool +				Name="VCWebDeploymentTool"/> +			<Tool +				Name="VCManagedWrapperGeneratorTool"/> +			<Tool +				Name="VCAuxiliaryManagedWrapperGeneratorTool"/> +		</Configuration> +	</Configurations> +	<References> +	</References> +	<Files> +		<Filter +			Name="Source Files" +			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"> +			<File +				RelativePath="data.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						BasicRuntimeChecks="3" +						BrowseInformation="1"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						BasicRuntimeChecks="3" +						BrowseInformation="1"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Release Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="frame.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						BasicRuntimeChecks="3" +						BrowseInformation="1"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						BasicRuntimeChecks="3" +						BrowseInformation="1"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Release Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="..\utils\mir_dblists.c"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						UsePrecompiledHeader="0"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						UsePrecompiledHeader="0"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						UsePrecompiledHeader="0"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Release Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						UsePrecompiledHeader="0"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="..\utils\mir_memory.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						UsePrecompiledHeader="0"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						BasicRuntimeChecks="3" +						UsePrecompiledHeader="0" +						BrowseInformation="1"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						BasicRuntimeChecks="3" +						UsePrecompiledHeader="0" +						BrowseInformation="1"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Release Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						UsePrecompiledHeader="0"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="..\utils\mir_options.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						UsePrecompiledHeader="0"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						BasicRuntimeChecks="3" +						UsePrecompiledHeader="0" +						BrowseInformation="1"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						BasicRuntimeChecks="3" +						UsePrecompiledHeader="0" +						BrowseInformation="1"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Release Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						UsePrecompiledHeader="0"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="..\utils\mir_smileys.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						UsePrecompiledHeader="0"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						BasicRuntimeChecks="3" +						UsePrecompiledHeader="0" +						BrowseInformation="1"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						BasicRuntimeChecks="3" +						UsePrecompiledHeader="0" +						BrowseInformation="1"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Release Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						UsePrecompiledHeader="0"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="mydetails.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						UsePrecompiledHeader="1"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						BasicRuntimeChecks="3" +						UsePrecompiledHeader="1" +						BrowseInformation="1"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						BasicRuntimeChecks="3" +						UsePrecompiledHeader="1" +						BrowseInformation="1"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Release Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						UsePrecompiledHeader="1"/> +				</FileConfiguration> +			</File> +			<File +				RelativePath="options.cpp"> +				<FileConfiguration +					Name="Release|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						BasicRuntimeChecks="3" +						BrowseInformation="1"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Debug Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="0" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)" +						BasicRuntimeChecks="3" +						BrowseInformation="1"/> +				</FileConfiguration> +				<FileConfiguration +					Name="Release Unicode|Win32"> +					<Tool +						Name="VCCLCompilerTool" +						Optimization="2" +						AdditionalIncludeDirectories="" +						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;MYDETAILS_EXPORTS;$(NoInherit)"/> +				</FileConfiguration> +			</File> +		</Filter> +		<Filter +			Name="Resource Files" +			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"> +			<File +				RelativePath="resource.rc"> +			</File> +		</Filter> +		<Filter +			Name="Header Files" +			Filter="h;hpp;hxx;hm;inl"> +			<File +				RelativePath="commons.h"> +			</File> +			<File +				RelativePath="data.h"> +			</File> +			<File +				RelativePath="frame.h"> +			</File> +			<File +				RelativePath="m_mydetails.h"> +			</File> +			<File +				RelativePath="m_simpleaway.h"> +			</File> +			<File +				RelativePath="..\utils\mir_dblists.h"> +			</File> +			<File +				RelativePath="..\utils\mir_memory.h"> +			</File> +			<File +				RelativePath="..\utils\mir_options.h"> +			</File> +			<File +				RelativePath="..\utils\mir_smileys.h"> +			</File> +			<File +				RelativePath="mydetails.h"> +			</File> +			<File +				RelativePath="options.h"> +			</File> +		</Filter> +	</Files> +	<Globals> +	</Globals> +</VisualStudioProject> + diff --git a/plugins/MyDetails/options.cpp b/plugins/MyDetails/options.cpp new file mode 100644 index 0000000000..c5c298c798 --- /dev/null +++ b/plugins/MyDetails/options.cpp @@ -0,0 +1,189 @@ +/* 
 +Copyright (C) 2005 Ricardo Pescuma Domenecci
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt.  If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA.  
 +*/
 +
 +
 +#include "commons.h"
 +#include "options.h"
 +
 +
 +
 +// Prototypes /////////////////////////////////////////////////////////////////////////////////////
 +
 +Options opts;
 +
 +
 +static BOOL CALLBACK DlgProcOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
 +
 +
 +// Functions //////////////////////////////////////////////////////////////////////////////////////
 +
 +
 +
 +static OptPageControl pageControls[] = { 
 +	{ &opts.draw_text_rtl,						CONTROL_CHECKBOX,	IDC_TEXT_RTL, "TextRTL", (BYTE) 0 },
 +	{ &opts.cycle_through_protocols,			CONTROL_CHECKBOX,	IDC_CYCLE_THROUGH_PROTOS, "CicleThroughtProtocols", (BYTE) 1 },
 +	{ &opts.seconds_to_show_protocol,			CONTROL_SPIN,		IDC_CYCLE_TIME, "CicleTime", (WORD) 5, IDC_CYCLE_TIME_SPIN, (WORD) 1, (WORD) 255 },
 +	{ &opts.replace_smileys,					CONTROL_CHECKBOX,	IDC_REPLACE_SMILEYS, "ReplaceSmileys", (BYTE) 1 },
 +	{ &opts.resize_smileys,						CONTROL_CHECKBOX,	IDC_RESIZE_SMILEYS, "ResizeSmileys", (BYTE) 0 },
 +	{ &opts.use_contact_list_smileys,			CONTROL_CHECKBOX,	IDC_USE_CONTACT_LIST_SMILEYS, "UseContactListSmileys", (BYTE) 0 },
 +	{ &opts.global_on_avatar,					CONTROL_CHECKBOX,	IDC_GLOBAL_ON_AVATAR, "GlobalOnAvatar", (BYTE) 0 },
 +	{ &opts.global_on_nickname,					CONTROL_CHECKBOX,	IDC_GLOBAL_ON_NICKNAME, "GlobalOnNickname", (BYTE) 0 },
 +	{ &opts.global_on_status,					CONTROL_CHECKBOX,	IDC_GLOBAL_ON_STATUS, "GlobalOnStatus", (BYTE) 0 },
 +	{ &opts.global_on_status_message,			CONTROL_CHECKBOX,	IDC_GLOBAL_ON_STATUS_MESSAGE, "GlobalOnStatusMessage", (BYTE) 0 },
 +	{ &opts.draw_avatar_border,					CONTROL_CHECKBOX,	IDC_AVATAR_DRAW_BORDER, "AvatarDrawBorders", (BYTE) 0 },
 +	{ &opts.draw_avatar_border_color,			CONTROL_COLOR,		IDC_AVATAR_BORDER_COLOR, "AvatarBorderColor", (DWORD) RGB(0,0,0) },
 +	{ &opts.draw_avatar_round_corner,			CONTROL_CHECKBOX,	IDC_AVATAR_ROUND_CORNERS, "AvatarRoundCorners", (BYTE) 1 },
 +	{ &opts.draw_avatar_use_custom_corner_size, CONTROL_CHECKBOX,	IDC_AVATAR_CUSTOM_CORNER_SIZE_CHECK, "AvatarUseCustomCornerSize", (BYTE) 0 },
 +	{ &opts.draw_avatar_custom_corner_size,		CONTROL_SPIN,		IDC_AVATAR_CUSTOM_CORNER_SIZE, "AvatarCustomCornerSize", (WORD) 4, IDC_AVATAR_CUSTOM_CORNER_SIZE_SPIN, (WORD) 1, (WORD) 255 },
 +	{ &opts.resize_frame,						CONTROL_CHECKBOX,	IDC_RESIZE_FRAME, "ResizeFrame", (BYTE) 0 },
 +};
 +
 +
 +// Initializations needed by options
 +void LoadOptions()
 +{
 +	if (GetSystemMetrics(SM_MIDEASTENABLED))
 +		pageControls[0].dwDefValue = TRUE;
 +
 +	LoadOpts(pageControls, MAX_REGS(pageControls), MODULE_NAME);
 +
 +	// This is created here to assert that this key always exists
 +	opts.refresh_status_message_timer = DBGetContactSettingWord(NULL,"MyDetails","RefreshStatusMessageTimer",12);
 +	DBWriteContactSettingWord(NULL,"MyDetails","RefreshStatusMessageTimer", opts.refresh_status_message_timer);
 +
 +	SetCycleTime();
 +	RedrawFrame();
 +}
 +
 +
 +int InitOptionsCallback(WPARAM wParam,LPARAM lParam)
 +{
 +	OPTIONSDIALOGPAGE odp;
 +
 +	ZeroMemory(&odp,sizeof(odp));
 +    odp.cbSize=sizeof(odp);
 +    odp.position=-200000000;
 +	odp.hInstance=hInst;
 +    odp.pfnDlgProc=DlgProcOpts;
 +    odp.pszTemplate=MAKEINTRESOURCE(IDD_OPTS);
 +    odp.pszGroup=Translate("Customize");
 +    odp.pszTitle=Translate("My Details");
 +    odp.flags=ODPF_BOLDGROUPS;
 +    CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
 +
 +	return 0;
 +}
 +
 +
 +void InitOptions()
 +{
 +	LoadOptions();
 +
 +	HookEvent(ME_OPT_INITIALISE, InitOptionsCallback);
 +}
 +
 +// Deinitializations needed by options
 +void DeInitOptions()
 +{
 +}
 +
 +
 +static BOOL CALLBACK DlgProcOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 +{
 +	BOOL ret = SaveOptsDlgProc(pageControls, MAX_REGS(pageControls), MODULE_NAME, hwndDlg, msg, wParam, lParam);
 +
 +	switch (msg)
 +	{
 +		case WM_INITDIALOG:
 +		{
 +			if(!IsDlgButtonChecked(hwndDlg,IDC_AVATAR_DRAW_BORDER)) 
 +			{
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_BORDER_COLOR_L),FALSE);
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_BORDER_COLOR),FALSE);
 +			}
 +			if(!IsDlgButtonChecked(hwndDlg,IDC_AVATAR_ROUND_CORNERS)) 
 +			{
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_CUSTOM_CORNER_SIZE_CHECK),FALSE);
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_CUSTOM_CORNER_SIZE),FALSE);
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_CUSTOM_CORNER_SIZE_SPIN),FALSE);
 +			}
 +			if(!IsDlgButtonChecked(hwndDlg,IDC_SHOW_PROTO_NAME)) 
 +			{
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_SHOW_CYCLE_PROTO_BUTTON),FALSE);
 +			}
 +			if (!ServiceExists(MS_SMILEYADD_BATCHPARSE))
 +			{
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_REPLACE_SMILEYS),FALSE);
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_USE_CONTACT_LIST_SMILEYS),FALSE);
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_RESIZE_SMILEYS),FALSE);
 +			}
 +			if (!ServiceExists(MS_CLIST_FRAMES_SETFRAMEOPTIONS))
 +			{
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_RESIZE_FRAME),FALSE);
 +			}
 +
 +			break;
 +		}
 +		case WM_COMMAND:
 +		{
 +			if (LOWORD(wParam)==IDC_AVATAR_DRAW_BORDER)
 +			{
 +				BOOL enabled = IsDlgButtonChecked(hwndDlg,IDC_AVATAR_DRAW_BORDER);
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_BORDER_COLOR_L),enabled);
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_BORDER_COLOR),enabled);
 +			}
 +			else if (LOWORD(wParam)==IDC_AVATAR_ROUND_CORNERS)
 +			{
 +				BOOL enabled = IsDlgButtonChecked(hwndDlg,IDC_AVATAR_ROUND_CORNERS);
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_CUSTOM_CORNER_SIZE_CHECK),enabled);
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_CUSTOM_CORNER_SIZE),enabled);
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_AVATAR_CUSTOM_CORNER_SIZE_SPIN),enabled);
 +			}
 +			else if (LOWORD(wParam)==IDC_SHOW_PROTO_NAME)
 +			{
 +				BOOL enabled = IsDlgButtonChecked(hwndDlg,IDC_SHOW_PROTO_NAME);
 +				EnableWindow(GetDlgItem(hwndDlg,IDC_SHOW_CYCLE_PROTO_BUTTON),enabled);
 +			}
 +
 +			break;
 +		}
 +		case WM_NOTIFY:
 +		{
 +			switch (((LPNMHDR)lParam)->idFrom) 
 +			{
 +				case 0:
 +				{
 +					switch (((LPNMHDR)lParam)->code)
 +					{
 +						case PSN_APPLY:
 +						{
 +							LoadOptions();
 +
 +							return TRUE;
 +						}
 +					}
 +					break;
 +				}
 +			}
 +			break;
 +		}
 +	}
 +
 +	return ret;
 +}
 diff --git a/plugins/MyDetails/options.h b/plugins/MyDetails/options.h new file mode 100644 index 0000000000..71d5f474c1 --- /dev/null +++ b/plugins/MyDetails/options.h @@ -0,0 +1,83 @@ +/* 
 +Copyright (C) 2005 Ricardo Pescuma Domenecci
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt.  If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA.  
 +*/
 +
 +
 +#ifndef __OPTIONS_H__
 +# define __OPTIONS_H__
 +
 +
 +#define TOP 0
 +#define LEFT 1
 +#define BOTTOM 2
 +#define RIGHT 3
 +
 +struct Options 
 +{
 +	bool cycle_through_protocols;
 +	int seconds_to_show_protocol;
 +	bool replace_smileys;
 +	bool resize_smileys;
 +	bool use_contact_list_smileys;
 +
 +	bool draw_text_rtl;
 +//	bool draw_text_align_right;
 +
 +//	bool draw_show_protocol_name;
 +//	bool show_protocol_cycle_button;
 +
 +	bool global_on_avatar;
 +	bool global_on_nickname;
 +	bool global_on_status;
 +	bool global_on_status_message;
 +
 +//	bool draw_avatar_custom_size;
 +//	bool draw_avatar_allow_to_grow;
 +//	int draw_avatar_custom_size_pixels;
 +	bool draw_avatar_border;
 +	COLORREF draw_avatar_border_color;
 +	bool draw_avatar_round_corner;
 +	bool draw_avatar_use_custom_corner_size;
 +	int draw_avatar_custom_corner_size;
 +
 +	COLORREF bkg_color;
 +//	int borders[4];
 +
 +//	bool use_avatar_space_to_draw_text;
 +
 +	bool resize_frame;
 +
 +	int refresh_status_message_timer;
 +};
 +
 +extern Options opts;
 +
 +
 +// Initializations needed by options
 +void InitOptions();
 +
 +// Deinitializations needed by options
 +void DeInitOptions();
 +
 +
 +// Loads the options from DB
 +// It don't need to be called, except in some rare cases
 +void LoadOptions();
 +
 +
 +#endif // __OPTIONS_H__
 diff --git a/plugins/MyDetails/res/leftarrow.ico b/plugins/MyDetails/res/leftarrow.ico Binary files differnew file mode 100644 index 0000000000..4953e83bb5 --- /dev/null +++ b/plugins/MyDetails/res/leftarrow.ico diff --git a/plugins/MyDetails/res/listening_to.ico b/plugins/MyDetails/res/listening_to.ico Binary files differnew file mode 100644 index 0000000000..d359ec1a11 --- /dev/null +++ b/plugins/MyDetails/res/listening_to.ico diff --git a/plugins/MyDetails/res/mail.ico b/plugins/MyDetails/res/mail.ico Binary files differnew file mode 100644 index 0000000000..ba0e7d35de --- /dev/null +++ b/plugins/MyDetails/res/mail.ico diff --git a/plugins/MyDetails/res/rightarrow.ico b/plugins/MyDetails/res/rightarrow.ico Binary files differnew file mode 100644 index 0000000000..2705830a79 --- /dev/null +++ b/plugins/MyDetails/res/rightarrow.ico diff --git a/plugins/MyDetails/resource.h b/plugins/MyDetails/resource.h new file mode 100644 index 0000000000..9bc277ea60 --- /dev/null +++ b/plugins/MyDetails/resource.h @@ -0,0 +1,72 @@ +//{{NO_DEPENDENCIES}}
 +// Microsoft Developer Studio generated include file.
 +// Used by resource.rc
 +//
 +#define IDD_SETNICKNAME                 101
 +#define IDD_OPTS                        102
 +#define IDD_SETSTATUSMESSAGE            103
 +#define IDR_MENU1                       104
 +#define IDI_LISTENINGTO                 105
 +#define IDI_RIGHT_ARROW                 106
 +#define IDI_LEFT_ARROW                  107
 +#define IDI_EMAIL                       111
 +#define IDC_NICKNAME                    1000
 +#define IDC_SHOW_PROTO_NAME             1001
 +#define IDC_CYCLE_THROUGH_PROTOS        1002
 +#define IDC_TEXT_RTL                    1003
 +#define IDC_TEXT_ALIGN_RIGHT            1004
 +#define IDC_REPLACE_SMILEYS             1005
 +#define IDC_RESIZE_SMILEYS              1006
 +#define IDC_RESIZE_FRAME                1007
 +#define IDC_RESIZE_SMILEYS2             1008
 +#define IDC_USE_CONTACT_LIST_SMILEYS    1008
 +#define IDC_STATUSMESSAGE               1009
 +#define IDC_GLOBAL_ON_NICKNAME          1009
 +#define IDC_AVATAR_ALLOW_TO_GROW        1010
 +#define IDC_GLOBAL_ON_STATUS_MESSAGE    1011
 +#define IDC_GLOBAL_ON_STATUS            1012
 +#define IDC_GLOBAL_ON_AVATAR            1013
 +#define IDC_SHOW_CYCLE_PROTO_BUTTON     1014
 +#define IDC_AVATAR_CUSTOM_CORNER_SIZE   1622
 +#define IDC_AVATAR_CUSTOM_CORNER_SIZE_SPIN 1623
 +#define IDC_BORDER_TOP                  1624
 +#define IDC_BORDER_TOP_SPIN             1625
 +#define IDC_BORDER_LEFT                 1626
 +#define IDC_BORDER_LEFT_SPIN            1627
 +#define IDC_BORDER_BOTTOM               1628
 +#define IDC_BORDER_BOTTOM_SPIN          1629
 +#define IDC_BORDER_RIGHT                1630
 +#define IDC_BORDER_RIGHT_SPIN           1631
 +#define IDC_CYCLE_TIME                  1632
 +#define IDC_CYCLE_TIME_SPIN             1633
 +#define IDC_AVATAR_CUSTOM_SIZE          1634
 +#define IDC_AVATAR_CUSTOM_SIZE_SPIN     1635
 +#define IDC_AVATAR_CUSTOM_CORNER_SIZE_CHECK 1761
 +#define IDC_AVATAR_DRAW_BORDER          1764
 +#define IDC_AVATAR_CUSTOM_SIZE_CHK      1765
 +#define IDC_AVATAR_ROUND_CORNERS        1800
 +#define IDC_AVATAR_USE_FREE_SPACE       1801
 +#define IDC_AVATAR_BORDER_COLOR_L       1839
 +#define IDC_AVATAR_BORDER_COLOR         1840
 +#define IDC_AVATAR_BKG_COLOR_L          1841
 +#define IDC_AVATAR_BKG_COLOR            1842
 +#define ID_CYCLE_THROUGH_PROTOS         40004
 +#define ID_DONT_CYCLE_THROUGH_PROTOS    40005
 +#define ID_SHOW_NEXT_PROTO              40006
 +#define ID_SHOW_PREV_PROTO              40007
 +#define ID_NICKPOPUP_SETMYNICKNAME      40008
 +#define ID_STATUSMESSAGEPOPUP_SETMYSTATUSMESSAGE 40009
 +#define ID_AVATARPOPUP_SETMYAVATAR      40010
 +#define ID_LISTENINGTOPOPUP_SENDLISTENINGTO 40011
 +#define ID_CONTEXTPOPUP_ENABLELISTENINGTO 40012
 +
 +// Next default values for new objects
 +// 
 +#ifdef APSTUDIO_INVOKED
 +#ifndef APSTUDIO_READONLY_SYMBOLS
 +#define _APS_NEXT_RESOURCE_VALUE        112
 +#define _APS_NEXT_COMMAND_VALUE         40013
 +#define _APS_NEXT_CONTROL_VALUE         1011
 +#define _APS_NEXT_SYMED_VALUE           101
 +#endif
 +#endif
 diff --git a/plugins/MyDetails/resource.rc b/plugins/MyDetails/resource.rc new file mode 100644 index 0000000000..5706422e8e --- /dev/null +++ b/plugins/MyDetails/resource.rc @@ -0,0 +1,326 @@ +//Microsoft Developer Studio generated resource script.
 +//
 +#include "resource.h"
 +
 +#define APSTUDIO_READONLY_SYMBOLS
 +/////////////////////////////////////////////////////////////////////////////
 +//
 +// Generated from the TEXTINCLUDE 2 resource.
 +//
 +#include "afxres.h"
 +#include "../../include/statusmodes.h"
 +
 +/////////////////////////////////////////////////////////////////////////////
 +#undef APSTUDIO_READONLY_SYMBOLS
 +
 +/////////////////////////////////////////////////////////////////////////////
 +// Neutral resources
 +
 +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
 +#ifdef _WIN32
 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
 +#pragma code_page(1252)
 +#endif //_WIN32
 +
 +/////////////////////////////////////////////////////////////////////////////
 +//
 +// Icon
 +//
 +
 +// Icon with lowest ID value placed first to ensure application icon
 +// remains consistent on all systems.
 +IDI_LISTENINGTO         ICON    DISCARDABLE     "res\\listening_to.ico"
 +IDI_RIGHT_ARROW         ICON    DISCARDABLE     "res\\rightarrow.ico"
 +IDI_LEFT_ARROW          ICON    DISCARDABLE     "res\\leftarrow.ico"
 +IDI_EMAIL               ICON    DISCARDABLE     "res\\mail.ico"
 +#endif    // Neutral resources
 +/////////////////////////////////////////////////////////////////////////////
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
 +// English (U.S.) resources
 +
 +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
 +#ifdef _WIN32
 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 +#pragma code_page(1252)
 +#endif //_WIN32
 +
 +#ifndef _MAC
 +/////////////////////////////////////////////////////////////////////////////
 +//
 +// Version
 +//
 +
 +VS_VERSION_INFO VERSIONINFO
 + FILEVERSION 0,0,1,11
 + PRODUCTVERSION 0,0,1,11
 + FILEFLAGSMASK 0x3fL
 +#ifdef _DEBUG
 + FILEFLAGS 0x1L
 +#else
 + FILEFLAGS 0x0L
 +#endif
 + FILEOS 0x40004L
 + FILETYPE 0x2L
 + FILESUBTYPE 0x0L
 +BEGIN
 +    BLOCK "StringFileInfo"
 +    BEGIN
 +        BLOCK "080004b0"
 +        BEGIN
 +            VALUE "Comments", "\0"
 +            VALUE "CompanyName", " \0"
 +            VALUE "FileDescription", "MyDetails Miranda Plugin\0"
 +            VALUE "FileVersion", "0, 0, 1, 11\0"
 +            VALUE "InternalName", "mydetails\0"
 +            VALUE "LegalCopyright", "Copyright © 2005-2008 Ricardo Pescuma Domenecci, Drugwash\0"
 +            VALUE "LegalTrademarks", "\0"
 +            VALUE "OriginalFilename", "mydetails.dll\0"
 +            VALUE "PrivateBuild", "\0"
 +            VALUE "ProductName", "\0"
 +            VALUE "ProductVersion", "0, 0, 1, 11\0"
 +            VALUE "SpecialBuild", "\0"
 +        END
 +    END
 +    BLOCK "VarFileInfo"
 +    BEGIN
 +        VALUE "Translation", 0x800, 1200
 +    END
 +END
 +
 +#endif    // !_MAC
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
 +//
 +// Dialog
 +//
 +
 +IDD_SETNICKNAME DIALOG DISCARDABLE  0, 0, 283, 65
 +STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | 
 +    WS_SYSMENU
 +CAPTION "Set My Nickname"
 +FONT 8, "MS Shell Dlg"
 +BEGIN
 +    RTEXT           "Nickname:",IDC_STATIC,7,8,51,12
 +    EDITTEXT        IDC_NICKNAME,67,7,209,31,ES_MULTILINE | ES_AUTOVSCROLL | 
 +                    WS_VSCROLL
 +    DEFPUSHBUTTON   "OK",IDOK,87,44,50,14
 +    PUSHBUTTON      "Cancel",IDCANCEL,146,44,50,14
 +END
 +
 +IDD_OPTS DIALOGEX 0, 0, 316, 246
 +STYLE DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
 +EXSTYLE WS_EX_CONTROLPARENT
 +FONT 8, "MS Shell Dlg"
 +BEGIN
 +    GROUPBOX        " General ",IDC_STATIC,7,7,302,70
 +    CONTROL         "Cycle through protocols every:",
 +                    IDC_CYCLE_THROUGH_PROTOS,"Button",BS_AUTOCHECKBOX | 
 +                    WS_TABSTOP,13,18,114,14
 +    EDITTEXT        IDC_CYCLE_TIME,129,18,35,12,ES_NUMBER
 +    CONTROL         "",IDC_CYCLE_TIME_SPIN,"msctls_updown32",UDS_SETBUDDYINT | 
 +                    UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | 
 +                    UDS_HOTTRACK,156,18,11,12
 +    LTEXT           "seconds",IDC_STATIC,171,21,32,11
 +    CONTROL         "Global on avatar",IDC_GLOBAL_ON_AVATAR,"Button",
 +                    BS_AUTOCHECKBOX | WS_TABSTOP,207,18,96,14
 +    CONTROL         "RTL",IDC_TEXT_RTL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
 +                    13,32,85,14
 +    CONTROL         "Global on nickname",IDC_GLOBAL_ON_NICKNAME,"Button",
 +                    BS_AUTOCHECKBOX | WS_TABSTOP,207,32,96,14
 +    CONTROL         "Auto-resize frame",IDC_RESIZE_FRAME,"Button",
 +                    BS_AUTOCHECKBOX | WS_TABSTOP,13,46,85,14
 +    CONTROL         "Use contact list smileys",IDC_USE_CONTACT_LIST_SMILEYS,
 +                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,105,46,96,14
 +    CONTROL         "Global on status",IDC_GLOBAL_ON_STATUS,"Button",
 +                    BS_AUTOCHECKBOX | WS_TABSTOP,207,46,96,14
 +    CONTROL         "Replace Smileys",IDC_REPLACE_SMILEYS,"Button",
 +                    BS_AUTOCHECKBOX | WS_TABSTOP,13,60,85,14
 +    CONTROL         "Resize Smileys",IDC_RESIZE_SMILEYS,"Button",
 +                    BS_AUTOCHECKBOX | WS_TABSTOP,105,60,96,14
 +    CONTROL         "Global on status message",IDC_GLOBAL_ON_STATUS_MESSAGE,
 +                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,207,61,96,14
 +    GROUPBOX        " Avatar ",IDC_STATIC,7,80,302,59
 +    CONTROL         "Draw border on avatar",IDC_AVATAR_DRAW_BORDER,"Button",
 +                    BS_AUTOCHECKBOX | WS_TABSTOP,16,95,103,9
 +    LTEXT           "Border Color:",IDC_AVATAR_BORDER_COLOR_L,123,95,53,10
 +    CONTROL         "",IDC_AVATAR_BORDER_COLOR,"ColourPicker",WS_TABSTOP,180,
 +                    92,17,13
 +    CONTROL         "Round corners of avatars",IDC_AVATAR_ROUND_CORNERS,
 +                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,109,280,8
 +    CONTROL         "Custom corner size:",
 +                    IDC_AVATAR_CUSTOM_CORNER_SIZE_CHECK,"Button",
 +                    BS_AUTOCHECKBOX | WS_TABSTOP,27,122,93,11
 +    EDITTEXT        IDC_AVATAR_CUSTOM_CORNER_SIZE,127,121,35,12,ES_NUMBER
 +    CONTROL         "",IDC_AVATAR_CUSTOM_CORNER_SIZE_SPIN,"msctls_updown32",
 +                    UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | 
 +                    UDS_NOTHOUSANDS | UDS_HOTTRACK,165,121,11,12
 +    LTEXT           "pixels",IDC_STATIC,179,124,41,11
 +END
 +
 +IDD_SETSTATUSMESSAGE DIALOG DISCARDABLE  0, 0, 283, 68
 +STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | 
 +    WS_SYSMENU
 +CAPTION "Set My Status Message for All Status"
 +FONT 8, "MS Shell Dlg"
 +BEGIN
 +    RTEXT           "Status Message:",IDC_STATIC,7,8,69,12
 +    EDITTEXT        IDC_STATUSMESSAGE,81,7,195,35,ES_MULTILINE | 
 +                    ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
 +    DEFPUSHBUTTON   "OK",IDOK,87,47,50,14
 +    PUSHBUTTON      "Cancel",IDCANCEL,146,47,50,14
 +END
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
 +//
 +// DESIGNINFO
 +//
 +
 +#ifdef APSTUDIO_INVOKED
 +GUIDELINES DESIGNINFO DISCARDABLE 
 +BEGIN
 +    IDD_SETNICKNAME, DIALOG
 +    BEGIN
 +        LEFTMARGIN, 7
 +        RIGHTMARGIN, 276
 +        TOPMARGIN, 7
 +        BOTTOMMARGIN, 58
 +    END
 +
 +    IDD_OPTS, DIALOG
 +    BEGIN
 +        LEFTMARGIN, 7
 +        RIGHTMARGIN, 309
 +        TOPMARGIN, 7
 +        BOTTOMMARGIN, 238
 +    END
 +
 +    IDD_SETSTATUSMESSAGE, DIALOG
 +    BEGIN
 +        LEFTMARGIN, 7
 +        RIGHTMARGIN, 276
 +        TOPMARGIN, 7
 +        BOTTOMMARGIN, 61
 +    END
 +END
 +#endif    // APSTUDIO_INVOKED
 +
 +#endif    // English (U.S.) resources
 +/////////////////////////////////////////////////////////////////////////////
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
 +// Portuguese (Brazil) resources
 +
 +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_PTB)
 +#ifdef _WIN32
 +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN
 +#pragma code_page(1252)
 +#endif //_WIN32
 +
 +#ifdef APSTUDIO_INVOKED
 +/////////////////////////////////////////////////////////////////////////////
 +//
 +// TEXTINCLUDE
 +//
 +
 +1 TEXTINCLUDE DISCARDABLE 
 +BEGIN
 +    "resource.h\0"
 +END
 +
 +2 TEXTINCLUDE DISCARDABLE 
 +BEGIN
 +    "#include ""afxres.h""\r\n"
 +    "#include ""../../include/statusmodes.h""\r\n"
 +    "\0"
 +END
 +
 +3 TEXTINCLUDE DISCARDABLE 
 +BEGIN
 +    "\r\n"
 +    "\0"
 +END
 +
 +#endif    // APSTUDIO_INVOKED
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
 +//
 +// Menu
 +//
 +
 +IDR_MENU1 MENU DISCARDABLE 
 +BEGIN
 +    POPUP "Status popup"
 +    BEGIN
 +        MENUITEM "&Offline",                    ID_STATUS_OFFLINE
 +        MENUITEM "On&line",                     ID_STATUS_ONLINE
 +        MENUITEM "&Away",                       ID_STATUS_AWAY
 +        MENUITEM "&NA",                         ID_STATUS_NA
 +        MENUITEM "Occ&upied",                   ID_STATUS_OCCUPIED
 +        MENUITEM "&DND",                        ID_STATUS_DND
 +        MENUITEM "&Free for chat",              ID_STATUS_FREECHAT
 +        MENUITEM "&Invisible",                  ID_STATUS_INVISIBLE
 +        MENUITEM "On the &Phone",               ID_STATUS_ONTHEPHONE
 +        MENUITEM "Out to &Lunch",               ID_STATUS_OUTTOLUNCH
 +    END
 +    POPUP "Context popup"
 +    BEGIN
 +        MENUITEM SEPARATOR
 +        MENUITEM "Set My Avatar...",            ID_AVATARPOPUP_SETMYAVATAR
 +        MENUITEM "Set My Nickname...",          ID_NICKPOPUP_SETMYNICKNAME
 +        MENUITEM "Set My Status Message...",    ID_STATUSMESSAGEPOPUP_SETMYSTATUSMESSAGE
 +
 +        MENUITEM "Enable Listening To",         ID_CONTEXTPOPUP_ENABLELISTENINGTO
 +
 +        MENUITEM SEPARATOR
 +        MENUITEM "Show next protocol",          ID_SHOW_NEXT_PROTO
 +        MENUITEM "Show previous protocol",      ID_SHOW_PREV_PROTO
 +        MENUITEM SEPARATOR
 +        MENUITEM "Cycle through protocols",     ID_CYCLE_THROUGH_PROTOS
 +        MENUITEM "Don't cycle through protocols", 
 +                                                ID_DONT_CYCLE_THROUGH_PROTOS
 +    END
 +    POPUP "Nick popup"
 +    BEGIN
 +        MENUITEM SEPARATOR
 +        MENUITEM "Set My Nickname...",          ID_NICKPOPUP_SETMYNICKNAME
 +    END
 +    POPUP "Status message popup"
 +    BEGIN
 +        MENUITEM SEPARATOR
 +        MENUITEM "Set My Status Message...",    ID_STATUSMESSAGEPOPUP_SETMYSTATUSMESSAGE
 +
 +    END
 +    POPUP "Avatar popup"
 +    BEGIN
 +        MENUITEM SEPARATOR
 +        MENUITEM "Set My Avatar...",            ID_AVATARPOPUP_SETMYAVATAR
 +    END
 +    POPUP "ListeningTo popup"
 +    BEGIN
 +        MENUITEM SEPARATOR
 +        MENUITEM "Enable Listening To",         ID_LISTENINGTOPOPUP_SENDLISTENINGTO
 +
 +    END
 +END
 +
 +#endif    // Portuguese (Brazil) resources
 +/////////////////////////////////////////////////////////////////////////////
 +
 +
 +
 +#ifndef APSTUDIO_INVOKED
 +/////////////////////////////////////////////////////////////////////////////
 +//
 +// Generated from the TEXTINCLUDE 3 resource.
 +//
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
 +#endif    // not APSTUDIO_INVOKED
 +
 diff --git a/plugins/Skins/Docs/langpack_skins.txt b/plugins/Skins/Docs/langpack_skins.txt new file mode 100644 index 0000000000..1819d74fce --- /dev/null +++ b/plugins/Skins/Docs/langpack_skins.txt @@ -0,0 +1,2 @@ +; Skins
 +; Author: Pescuma
 diff --git a/plugins/Skins/Docs/skins_changelog.txt b/plugins/Skins/Docs/skins_changelog.txt new file mode 100644 index 0000000000..fcaa8da44c --- /dev/null +++ b/plugins/Skins/Docs/skins_changelog.txt @@ -0,0 +1,25 @@ +Skins
 +
 +Changelog:
 +
 +. 0.0.0.5
 +  + Allow changing skins
 +  * Updated v8
 +  * Updated updater to use googlecode
 +  
 +. 0.0.0.4
 +  * Fixed font service iteration
 +  * Fixed naming of skin options
 +
 +. 0.0.0.3
 +  * Better handling of small sizes
 +
 +. 0.0.0.2
 +  * Fix for float numbers
 +  + Added valign (not used yet)
 +  + Added dialog info (allow clients to set script variables starting with info)
 +  + The zip will contain also the pdbs (at least until it is more stable)
 +  * Fix for ASCII strings
 +
 +. 0.0.0.1
 +  + Initial version
\ No newline at end of file diff --git a/plugins/Skins/Docs/skins_readme.txt b/plugins/Skins/Docs/skins_readme.txt new file mode 100644 index 0000000000..fd06309ad1 --- /dev/null +++ b/plugins/Skins/Docs/skins_readme.txt @@ -0,0 +1,31 @@ +Skins plugin
 +----------------
 +
 +CAUTION: THIS IS AN ALPHA STAGE PLUGIN. IT CAN DO VERY BAD THINGS. USE AT YOUR OWN RISK.
 +
 +This is a service plugin to allow using different skins. It uses javascript as the language the skins are written, thus allowing a lot of flexibility. 
 +
 +Keep in mind that this is an initial version of the plugin. It is intended to grow a loot (its to do list is bigger than its features list :P ). Currently it allows only calculating the position of elements.
 +
 +It works based in the consept of a skin beeing a group of small skins (one for each client). The skins are inside the dir <Miranda>\Skins\<Skin name> , and inside that folder, each client skin has the name <Client>.msk
 +
 +Inside the zip there is also a version of MyDetails using this plugin.
 +
 +Many thanks to the v8 team for the javascript engine implementation.
 +
 +This needs Miranda 0.8 to work.
 +
 +To report bugs/make suggestions, go to the forum thread: http://forums.miranda-im.org/showthread.php?p=172392
 +
 +
 +TODO:
 + - Allow changing skin without restart
 + - Add support for handling skin packs
 + - Add support for emoticons in text fields
 + - Add code to draw elements on screen
 + - Add service to create a new frame only based on the fields
 + - Allow setting variables by the users of the plugin
 +
 +
 +KNOWN PROBLEMS:
 + - It seems to have a memory leak (last time I debugged it, it was inside v8 - maybe I just don't understant its garbage collector?)
 diff --git a/plugins/Skins/Docs/skins_version.txt b/plugins/Skins/Docs/skins_version.txt new file mode 100644 index 0000000000..92fad2b10f --- /dev/null +++ b/plugins/Skins/Docs/skins_version.txt @@ -0,0 +1 @@ +Skins 0.0.0.5
\ No newline at end of file diff --git a/plugins/Skins/MirandaField.h b/plugins/Skins/MirandaField.h new file mode 100644 index 0000000000..d89901c77d --- /dev/null +++ b/plugins/Skins/MirandaField.h @@ -0,0 +1,14 @@ +#ifndef __MIRANDA_FIELD_H__
 +# define __MIRANDA_FIELD_H__
 +
 +
 +class MirandaField
 +{
 +public:
 +	virtual void configure() = 0;
 +};
 +
 +
 +
 +
 +#endif // __MIRANDA_FIELD_H__
 diff --git a/plugins/Skins/MirandaFont.cpp b/plugins/Skins/MirandaFont.cpp new file mode 100644 index 0000000000..51b0f34f9b --- /dev/null +++ b/plugins/Skins/MirandaFont.cpp @@ -0,0 +1,87 @@ +#include "MirandaFont.h"
 +
 +MirandaFont::MirandaFont(Field *aField, const char *description) 
 +		: field(aField), hFont(NULL)
 +{
 +	ZeroMemory(&fid, sizeof(fid));
 +	lstrcpyn(fid.name, CharToTchar(description), sizeof(fid.name));
 +}
 +
 +MirandaFont::~MirandaFont()
 +{
 +	releaseFont();
 +}
 +
 +void MirandaFont::registerFont(FontState *font)
 +{
 +	if (fid.cbSize != 0)
 +		return;
 +
 +	MirandaSkinnedDialog * dlg = (MirandaSkinnedDialog *) field->getDialog();
 +
 +	HDC hdc = GetDC(NULL);
 +
 +	fid.cbSize = sizeof(fid);
 +	lstrcpyn(fid.group, CharToTchar(dlg->getDescription()), sizeof(fid.group));
 +	strncpy(fid.dbSettingsGroup, dlg->getModule(), sizeof(fid.dbSettingsGroup));
 +
 +	char tmp[sizeof(fid.prefix)];
 +	mir_snprintf(tmp, sizeof(tmp), "%s%s%sFont", TcharToChar(dlg->getSkinName()), dlg->getName(), field->getName());
 +	strncpy(fid.prefix, tmp, sizeof(fid.prefix));
 +
 +	fid.deffontsettings.colour = font->getColor();
 +	fid.deffontsettings.size = -MulDiv(font->getSize(), GetDeviceCaps(hdc, LOGPIXELSY), 72);
 +	fid.deffontsettings.style = (font->isBold() ? DBFONTF_BOLD : 0)
 +		| (font->isItalic() ? DBFONTF_ITALIC : 0)
 +		| (font->isUnderline() ? DBFONTF_UNDERLINE : 0)
 +		| (font->isStrikeOut() ? DBFONTF_STRIKEOUT : 0);
 +	fid.deffontsettings.charset = DEFAULT_CHARSET;
 +	lstrcpyn(fid.deffontsettings.szFace, font->getFace(), sizeof(fid.deffontsettings.szFace));
 +	fid.order = dlg->getIndexOf(field);
 +	fid.flags = FIDF_DEFAULTVALID | FIDF_ALLOWEFFECTS;
 +
 +	CallService(MS_FONT_REGISTERT, (WPARAM)&fid, 0);
 +
 +	ReleaseDC(NULL, hdc);
 +
 +	HookEventObj(ME_FONT_RELOAD, staticReloadFont, this);
 +
 +	reloadFont();
 +}
 +
 +void MirandaFont::reloadFont()
 +{
 +	releaseFont();
 +
 +	LOGFONT log_font;
 +	COLORREF color = (COLORREF) CallService(MS_FONT_GETT, (WPARAM) &fid, (LPARAM) &log_font);
 +	hFont = CreateFontIndirect(&log_font);
 +
 +	switch(field->getType())
 +	{
 +		case SIMPLE_TEXT:
 +			((TextField *) field)->setFontColor(color);
 +			((TextField *) field)->setFont(hFont);
 +			break;
 +		case CONTROL_LABEL:
 +		case CONTROL_BUTTON:
 +		case CONTROL_EDIT:
 +			((ControlField *) field)->setFont(hFont);
 +			break;
 +	}
 +}
 +
 +int MirandaFont::staticReloadFont(void *obj, WPARAM wParam, LPARAM lParam)
 +{
 +	((MirandaFont *) obj)->reloadFont();
 +	return 0;
 +}
 +
 +void MirandaFont::releaseFont()
 +{
 +	if (hFont != NULL) 
 +	{
 +		DeleteObject(hFont);
 +		hFont = NULL;
 +	}
 +}
\ No newline at end of file diff --git a/plugins/Skins/MirandaFont.h b/plugins/Skins/MirandaFont.h new file mode 100644 index 0000000000..da9a40a06e --- /dev/null +++ b/plugins/Skins/MirandaFont.h @@ -0,0 +1,28 @@ +#ifndef __MIRANDA_FONT_H__
 +# define __MIRANDA_FONT_H__
 +
 +#include "commons.h"
 +
 +
 +class MirandaFont
 +{
 +public:
 +	MirandaFont(Field *field, const char *description);
 +	~MirandaFont();
 +
 +	void registerFont(FontState *font);
 +	void reloadFont();
 +
 +private:
 +	FontIDT fid;
 +	HFONT hFont;
 +	Field *field;
 +
 +	void releaseFont();
 +
 +	static int staticReloadFont(void *obj, WPARAM wParam, LPARAM lParam);
 +};
 +
 +
 +
 +#endif // __MIRANDA_FONT_H__
 diff --git a/plugins/Skins/MirandaIconField.cpp b/plugins/Skins/MirandaIconField.cpp new file mode 100644 index 0000000000..7861e11091 --- /dev/null +++ b/plugins/Skins/MirandaIconField.cpp @@ -0,0 +1,19 @@ +#include "MirandaIconField.h"
 +
 +MirandaIconField::MirandaIconField(MirandaSkinnedDialog *dlg, const char *name, const char *description)
 +		: IconField(dlg, name)
 +{
 +}
 +
 +MirandaIconField::~MirandaIconField()
 +{
 +}
 +
 +MirandaSkinnedDialog * MirandaIconField::getDialog() const
 +{
 +	return (MirandaSkinnedDialog *) IconField::getDialog();
 +}
 +
 +void MirandaIconField::configure()
 +{
 +}
\ No newline at end of file diff --git a/plugins/Skins/MirandaIconField.h b/plugins/Skins/MirandaIconField.h new file mode 100644 index 0000000000..0f6f15af9e --- /dev/null +++ b/plugins/Skins/MirandaIconField.h @@ -0,0 +1,21 @@ +#ifndef __MIRANDA_ICON_FIELD_H__
 +# define __MIRANDA_ICON_FIELD_H__
 +
 +#include "commons.h"
 +#include "MirandaField.h"
 +
 +
 +class MirandaIconField : public IconField, public MirandaField
 +{
 +public:
 +	MirandaIconField(MirandaSkinnedDialog *dlg, const char *name, const char *description);
 +	virtual ~MirandaIconField();
 +
 +	virtual MirandaSkinnedDialog * getDialog() const;
 +
 +	virtual void configure();
 +};
 +
 +
 +
 +#endif // __MIRANDA_ICON_FIELD_H__
 diff --git a/plugins/Skins/MirandaImageField.cpp b/plugins/Skins/MirandaImageField.cpp new file mode 100644 index 0000000000..2c9efe11f2 --- /dev/null +++ b/plugins/Skins/MirandaImageField.cpp @@ -0,0 +1,19 @@ +#include "MirandaImageField.h"
 +
 +MirandaImageField::MirandaImageField(MirandaSkinnedDialog *dlg, const char *name, const char *description)
 +		: ImageField(dlg, name)
 +{
 +}
 +
 +MirandaImageField::~MirandaImageField()
 +{
 +}
 +
 +MirandaSkinnedDialog * MirandaImageField::getDialog() const
 +{
 +	return (MirandaSkinnedDialog *) ImageField::getDialog();
 +}
 +
 +void MirandaImageField::configure()
 +{
 +}
\ No newline at end of file diff --git a/plugins/Skins/MirandaImageField.h b/plugins/Skins/MirandaImageField.h new file mode 100644 index 0000000000..70cd1ce873 --- /dev/null +++ b/plugins/Skins/MirandaImageField.h @@ -0,0 +1,21 @@ +#ifndef __MIRANDA_IMAGE_FIELD_H__
 +# define __MIRANDA_IMAGE_FIELD_H__
 +
 +#include "commons.h"
 +#include "MirandaField.h"
 +
 +
 +class MirandaImageField : public ImageField, public MirandaField
 +{
 +public:
 +	MirandaImageField(MirandaSkinnedDialog *dlg, const char *name, const char *description);
 +	virtual ~MirandaImageField();
 +
 +	virtual MirandaSkinnedDialog * getDialog() const;
 +
 +	virtual void configure();
 +};
 +
 +
 +#endif // __MIRANDA_IMAGE_FIELD_H__
 +
 diff --git a/plugins/Skins/MirandaSkinnedDialog.cpp b/plugins/Skins/MirandaSkinnedDialog.cpp new file mode 100644 index 0000000000..97bf236a5a --- /dev/null +++ b/plugins/Skins/MirandaSkinnedDialog.cpp @@ -0,0 +1,252 @@ +#include "commons.h"
 +#include "MirandaSkinnedDialog.h"
 +
 +#define SETTING_NAME_SIZE 256
 +
 +
 +MirandaSkinnedDialog::MirandaSkinnedDialog(const char *name, const char *aDescription, const char *aModule) 
 +		: SkinnedDialog(name), description(aDescription), module(aModule), 
 +		skinChangedCallback(NULL), skinChangedCallbackParam(NULL)
 +{
 +	getSettting("Skin", _T(DEFAULT_SKIN_NAME), skinName, true);
 +}
 +
 +MirandaSkinnedDialog::~MirandaSkinnedDialog()
 +{
 +}
 +
 +const char * MirandaSkinnedDialog::getDescription() const
 +{
 +	return description.c_str();
 +}
 +
 +const char * MirandaSkinnedDialog::getModule() const
 +{
 +	return module.c_str();
 +}
 +
 +const TCHAR * MirandaSkinnedDialog::getSkinName() const
 +{
 +	return skinName.c_str();
 +}
 +
 +void MirandaSkinnedDialog::setSkinName(const TCHAR *name)
 +{
 +	if (skinName == name)
 +		return;
 +
 +	skinName = name;
 +	setSettting("Skin", skinName.c_str(), true);
 +	updateFilename();
 +}
 +
 +bool MirandaSkinnedDialog::finishedConfiguring()
 +{
 +	updateFilename();
 +
 +	if (getDefaultState() == NULL || getOpts() == NULL)
 +		return false;
 +
 +	return true;
 +}
 +
 +void MirandaSkinnedDialog::updateFilename()
 +{
 +	std::tstring filename;
 +	getSkinnedDialogFilename(filename, getSkinName(), getName());
 +	setFilename(filename.c_str());
 +}
 +
 +void MirandaSkinnedDialog::loadFromDB(SkinOption *opt)
 +{
 +	switch(opt->getType())
 +	{
 +		case CHECKBOX:
 +		{
 +			opt->setValueCheckbox(getSettting(opt->getName(), opt->getValueCheckbox()));
 +			break;
 +		}
 +		case NUMBER:
 +		{
 +			opt->setValueNumber(getSettting(opt->getName(), opt->getValueNumber()));
 +			break;
 +		}
 +		case TEXT:
 +		{
 +			std::tstring tmp;
 +			getSettting(opt->getName(), opt->getValueText(), tmp);
 +			opt->setValueText(tmp.c_str());
 +			break;
 +		}
 +	}
 +}
 +
 +void MirandaSkinnedDialog::storeToDB(const SkinOptions *opts)
 +{
 +	for (unsigned int i = 0; i < opts->getNumOptions(); i++)
 +		storeToDB(opts->getOption(i));
 +
 +	fireOnSkinChanged();
 +}
 +
 +void MirandaSkinnedDialog::storeToDB(const SkinOption *opt)
 +{
 +	switch(opt->getType())
 +	{
 +		case CHECKBOX:
 +		{
 +			setSettting(opt->getName(), opt->getValueCheckbox());
 +			break;
 +		}
 +		case NUMBER:
 +		{
 +			setSettting(opt->getName(), opt->getValueNumber());
 +			break;
 +		}
 +		case TEXT:
 +		{
 +			setSettting(opt->getName(), opt->getValueText());
 +			break;
 +		}
 +	}
 +}
 +
 +bool MirandaSkinnedDialog::getSettting(const char *name, bool defVal, bool global)
 +{
 +	char setting[SETTING_NAME_SIZE];
 +	getSettingName(setting, name, global);
 +
 +	return DBGetContactSettingByte(NULL, getModule(), setting, defVal ? 1 : 0) != 0;
 +}
 +
 +void MirandaSkinnedDialog::setSettting(const char *name, bool val, bool global)
 +{
 +	char setting[SETTING_NAME_SIZE];
 +	getSettingName(setting, name, global);
 +
 +	DBWriteContactSettingByte(NULL, getModule(), setting, val ? 1 : 0);
 +}
 +
 +int MirandaSkinnedDialog::getSettting(const char *name, int defVal, bool global)
 +{
 +	char setting[SETTING_NAME_SIZE];
 +	getSettingName(setting, name, global);
 +
 +	return DBGetContactSettingDword(NULL, getModule(), setting, defVal);
 +}
 +
 +void MirandaSkinnedDialog::setSettting(const char *name, int val, bool global)
 +{
 +	char setting[SETTING_NAME_SIZE];
 +	getSettingName(setting, name, global);
 +
 +	DBWriteContactSettingDword(NULL, getModule(), setting, val);
 +}
 +
 +void MirandaSkinnedDialog::getSettting(const char *name, const WCHAR *defVal, std::wstring &ret, bool global)
 +{
 +	char setting[SETTING_NAME_SIZE];
 +	getSettingName(setting, name, global);
 +
 +	DBVARIANT dbv = {0};
 +	if (DBGetContactSettingWString(NULL, getModule(), setting, &dbv))
 +	{
 +		ret = defVal;
 +		return;
 +	}
 +
 +	ret = dbv.pwszVal;
 +	DBFreeVariant(&dbv);
 +}
 +
 +void MirandaSkinnedDialog::setSettting(const char *name, const WCHAR *val, bool global)
 +{
 +	char setting[SETTING_NAME_SIZE];
 +	getSettingName(setting, name, global);
 +
 +	DBWriteContactSettingWString(NULL, getModule(), setting, val);
 +}
 +
 +void MirandaSkinnedDialog::getSettting(const char *name, const char *defVal, std::string &ret, bool global)
 +{
 +	char setting[SETTING_NAME_SIZE];
 +	getSettingName(setting, name, global);
 +
 +	DBVARIANT dbv = {0};
 +	if (DBGetContactSettingString(NULL, getModule(), setting, &dbv))
 +	{
 +		ret = defVal;
 +		return;
 +	}
 +
 +	ret = dbv.pszVal;
 +	DBFreeVariant(&dbv);
 +}
 +
 +void MirandaSkinnedDialog::setSettting(const char *name, const char *val, bool global)
 +{
 +	char setting[SETTING_NAME_SIZE];
 +	getSettingName(setting, name, global);
 +
 +	DBWriteContactSettingString(NULL, getModule(), setting, val);
 +}
 +
 +void MirandaSkinnedDialog::getSettingName(char *setting, const char * name, bool global)
 +{
 +	if (global)
 +		mir_snprintf(setting, SETTING_NAME_SIZE, "%s%s", getName(), name);
 +	else
 +		mir_snprintf(setting, SETTING_NAME_SIZE, "%s%s%s", TcharToChar(getSkinName()), getName(), name);
 +}
 +
 +void MirandaSkinnedDialog::setOnSkinChangedCallback(MirandaSkinnedCallback cb, void *param)
 +{
 +	skinChangedCallback = cb;
 +	skinChangedCallbackParam = param;
 +}
 +
 +void MirandaSkinnedDialog::fireOnSkinChanged()
 +{
 +	if (skinChangedCallback != NULL)
 +		skinChangedCallback(skinChangedCallbackParam, this);
 +}
 +
 +int MirandaSkinnedDialog::compile()
 +{
 +	int ret = SkinnedDialog::compile();
 +
 +	if (ret == 2)
 +	{
 +		SkinOptions * opts = getOpts();
 +		_ASSERT(opts != NULL);
 +		
 +		for(unsigned int i = 0; i < opts->getNumOptions(); ++i)
 +		{
 +			SkinOption *opt = opts->getOption(i);
 +			loadFromDB(opt);
 +			opt->setOnChangeCallback(&staticOnOptionChange, this);
 +		}
 +
 +		for(unsigned int i = 0; i < getFieldCount(); ++i)
 +		{
 +			MirandaField *field = dynamic_cast<MirandaField *>(getField(i));
 +			field->configure();
 +		}
 +
 +		fireOnSkinChanged();
 +	}
 +
 +	return ret;
 +}
 +
 +void MirandaSkinnedDialog::onOptionChange(const SkinOption *opt)
 +{
 +	storeToDB(opt);
 +}
 +
 +void MirandaSkinnedDialog::staticOnOptionChange(void *param, const SkinOption *opt)
 +{
 +	_ASSERT(param != NULL);
 +
 +	((MirandaSkinnedDialog *) param)->onOptionChange(opt);
 +}
 diff --git a/plugins/Skins/MirandaSkinnedDialog.h b/plugins/Skins/MirandaSkinnedDialog.h new file mode 100644 index 0000000000..d556b9a495 --- /dev/null +++ b/plugins/Skins/MirandaSkinnedDialog.h @@ -0,0 +1,64 @@ +#ifndef __MIRANDA_SKINNED_DIALOG_H__
 +# define __MIRANDA_SKINNED_DIALOG_H__
 +
 +#include "SkinLib\SkinnedDialog.h"
 +
 +class SkinOption;
 +class MirandaSkinnedDialog;
 +
 +typedef void (*MirandaSkinnedCallback)(void *param, const MirandaSkinnedDialog *dlg);
 +
 +
 +class MirandaSkinnedDialog : public SkinnedDialog
 +{
 +public:
 +	MirandaSkinnedDialog(const char *name, const char *description, const char *module);
 +	virtual ~MirandaSkinnedDialog();
 +
 +	virtual const char * getDescription() const;
 +	virtual const char * getModule() const;
 +
 +	virtual const TCHAR * getSkinName() const;
 +	virtual void setSkinName(const TCHAR *name);
 +
 +	virtual bool finishedConfiguring();
 +
 +	virtual void storeToDB(const SkinOptions *opts);
 +
 +	virtual void setOnSkinChangedCallback(MirandaSkinnedCallback cb, void *param);
 +
 +protected:
 +	virtual int compile();
 +
 +private:
 +	std::string description;
 +	std::string module;
 +	std::tstring skinName;
 +	MirandaSkinnedCallback skinChangedCallback;
 +	void *skinChangedCallbackParam;
 +
 +	void updateFilename();
 +
 +	void loadFromDB(SkinOption *opt);
 +	void storeToDB(const SkinOption *opt);
 +
 +	bool getSettting(const char *name, bool defVal, bool global = false);
 +	void setSettting(const char *name, bool val, bool global = false);
 +	int getSettting(const char *name, int defVal, bool global = false);
 +	void setSettting(const char *name, int val, bool global = false);
 +	void getSettting(const char *name, const WCHAR *defVal, std::wstring &ret, bool global = false);
 +	void setSettting(const char *name, const WCHAR *val, bool global = false);
 +	void getSettting(const char *name, const char *defVal, std::string &ret, bool global = false);
 +	void setSettting(const char *name, const char *val, bool global = false);
 +
 +	inline void getSettingName(char *setting, const char * name, bool global);
 +
 +	void fireOnSkinChanged();
 +
 +	void onOptionChange(const SkinOption *opt);
 +
 +	static void staticOnOptionChange(void *param, const SkinOption *opt);
 +};
 +
 +
 +#endif // __MIRANDA_SKINNED_DIALOG_H__
 diff --git a/plugins/Skins/MirandaTextField.cpp b/plugins/Skins/MirandaTextField.cpp new file mode 100644 index 0000000000..4a3591a322 --- /dev/null +++ b/plugins/Skins/MirandaTextField.cpp @@ -0,0 +1,27 @@ +#include "MirandaTextField.h"
 +#include "MirandaFont.h"
 +
 +
 +MirandaTextField::MirandaTextField(MirandaSkinnedDialog *dlg, const char *name, const char *aDescription) 
 +		: TextField(dlg, name)
 +{
 +	font = new MirandaFont(this, aDescription);
 +}
 +
 +MirandaTextField::~MirandaTextField()
 +{
 +	delete font;
 +}
 +
 +MirandaSkinnedDialog * MirandaTextField::getDialog() const
 +{
 +	return (MirandaSkinnedDialog *) TextField::getDialog();
 +}
 +
 +void MirandaTextField::configure()
 +{
 +	TextFieldState *field = (TextFieldState *) getDialog()->getDefaultState()->getField(getName());
 +	_ASSERT(field != NULL);
 +
 +	font->registerFont(field->getFont());
 +}
 diff --git a/plugins/Skins/MirandaTextField.h b/plugins/Skins/MirandaTextField.h new file mode 100644 index 0000000000..36b7ea7292 --- /dev/null +++ b/plugins/Skins/MirandaTextField.h @@ -0,0 +1,27 @@ +#ifndef __MIRANDA_TEXT_FIELD_H__
 +# define __MIRANDA_TEXT_FIELD_H__
 +
 +#include "commons.h"
 +#include "MirandaField.h"
 +
 +class MirandaFont;
 +
 +
 +class MirandaTextField : public TextField, public MirandaField
 +{
 +public:
 +	MirandaTextField(MirandaSkinnedDialog *dlg, const char *name, const char *description);
 +	virtual ~MirandaTextField();
 +
 +	virtual MirandaSkinnedDialog * getDialog() const;
 +
 +	virtual void configure();
 +
 +private:
 +	MirandaFont *font;
 +
 +};
 +
 +
 +
 +#endif // __MIRANDA_TEXT_FIELD_H__
 diff --git a/plugins/Skins/SkinLib/BorderState.cpp b/plugins/Skins/SkinLib/BorderState.cpp new file mode 100644 index 0000000000..83dcdbcf11 --- /dev/null +++ b/plugins/Skins/SkinLib/BorderState.cpp @@ -0,0 +1,61 @@ +#include "globals.h"
 +#include <windows.h>
 +#include "BorderState.h"
 +
 +BorderState::BorderState(int aLeft, int aRight, int aTop, int aBottom) 
 +		: left(aLeft), right(aRight), top(aTop), bottom(aBottom)
 +{
 +}
 +
 +BorderState::~BorderState()
 +{
 +}
 +
 +int BorderState::getLeft() const
 +{
 +	return left;
 +}
 +
 +void BorderState::setLeft(int left)
 +{
 +	this->left = max(0, left);
 +}
 +
 +int BorderState::getRight() const
 +{
 +	return right;
 +}
 +
 +void BorderState::setRight(int right)
 +{
 +	this->right = max(0, right);
 +}
 +
 +int BorderState::getTop() const
 +{
 +	return top;
 +}
 +
 +void BorderState::setTop(int top)
 +{
 +	this->top = max(0, top);
 +}
 +
 +int BorderState::getBottom() const
 +{
 +	return bottom;
 +}
 +
 +void BorderState::setBottom(int bottom)
 +{
 +	this->bottom = max(0, bottom);
 +}
 +
 +void BorderState::setAll(int border)
 +{
 +	border = max(0, border);
 +	left = border;
 +	right = border; 
 +	top = border;
 +	bottom = border;
 +}
 diff --git a/plugins/Skins/SkinLib/BorderState.h b/plugins/Skins/SkinLib/BorderState.h new file mode 100644 index 0000000000..2cac3c1aa5 --- /dev/null +++ b/plugins/Skins/SkinLib/BorderState.h @@ -0,0 +1,28 @@ +#pragma once
 +
 +class BorderState
 +{
 +public:
 +	BorderState(int left, int right, int top, int bottom);
 +	~BorderState();
 +
 +	int getLeft() const;
 +	void setLeft(int left);
 +
 +	int getRight() const;
 +	void setRight(int right);
 +
 +	int getTop() const;
 +	void setTop(int top);
 +
 +	int getBottom() const;
 +	void setBottom(int bottom);
 +
 +	void setAll(int border);
 +
 +private:
 +	int left;
 +	int right;
 +	int top;
 +	int bottom;
 +};
 diff --git a/plugins/Skins/SkinLib/BorderState_v8_wrapper.cpp b/plugins/Skins/SkinLib/BorderState_v8_wrapper.cpp new file mode 100644 index 0000000000..71cc057419 --- /dev/null +++ b/plugins/Skins/SkinLib/BorderState_v8_wrapper.cpp @@ -0,0 +1,160 @@ +#include "globals.h"
 +#include "BorderState_v8_wrapper.h"
 +#include <v8.h>
 +#include "BorderState.h"
 +
 +using namespace v8;
 +
 +
 +#ifdef UNICODE
 +# define V8_TCHAR uint16_t
 +#else
 +# define V8_TCHAR char
 +#endif
 +
 +
 +static Handle<Value> Get_BorderState_left(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	BorderState *tmp = (BorderState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getLeft()) );
 +}
 +
 +static void Set_BorderState_left(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	BorderState *tmp = (BorderState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setLeft(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_BorderState_right(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	BorderState *tmp = (BorderState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getRight()) );
 +}
 +
 +static void Set_BorderState_right(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	BorderState *tmp = (BorderState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setRight(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_BorderState_top(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	BorderState *tmp = (BorderState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getTop()) );
 +}
 +
 +static void Set_BorderState_top(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	BorderState *tmp = (BorderState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setTop(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_BorderState_bottom(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	BorderState *tmp = (BorderState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getBottom()) );
 +}
 +
 +static void Set_BorderState_bottom(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	BorderState *tmp = (BorderState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setBottom(value->Int32Value());
 +}
 +
 +
 +void AddBorderStateAcessors(Handle<ObjectTemplate> &templ)
 +{
 +	HandleScope scope;
 +	
 +	templ->SetAccessor(String::New("left"), Get_BorderState_left, Set_BorderState_left);
 +	templ->SetAccessor(String::New("right"), Get_BorderState_right, Set_BorderState_right);
 +	templ->SetAccessor(String::New("top"), Get_BorderState_top, Set_BorderState_top);
 +	templ->SetAccessor(String::New("bottom"), Get_BorderState_bottom, Set_BorderState_bottom);
 +}
 diff --git a/plugins/Skins/SkinLib/BorderState_v8_wrapper.h b/plugins/Skins/SkinLib/BorderState_v8_wrapper.h new file mode 100644 index 0000000000..70af9e41dc --- /dev/null +++ b/plugins/Skins/SkinLib/BorderState_v8_wrapper.h @@ -0,0 +1,10 @@ +#ifndef __BORDER_STATE_V8_WRAPPER_H__
 +# define __BORDER_STATE_V8_WRAPPER_H__
 +
 +#include <v8.h>
 +
 +void AddBorderStateAcessors(v8::Handle<v8::ObjectTemplate> &templ);
 +
 +
 +
 +#endif // __BORDER_STATE_V8_WRAPPER_H__
 diff --git a/plugins/Skins/SkinLib/ButtonField.cpp b/plugins/Skins/SkinLib/ButtonField.cpp new file mode 100644 index 0000000000..e6c82ba5e3 --- /dev/null +++ b/plugins/Skins/SkinLib/ButtonField.cpp @@ -0,0 +1,22 @@ +#include "globals.h"
 +#include "ButtonField.h"
 +#include "ButtonFieldState.h"
 +
 +
 +ButtonField::ButtonField(Dialog *dlg, const char *name, HWND hwnd) : ControlField(dlg, name, hwnd)
 +{
 +}
 +
 +ButtonField::~ButtonField()
 +{
 +}
 +
 +FieldType ButtonField::getType() const
 +{
 +	return CONTROL_BUTTON;
 +}
 +
 +FieldState * ButtonField::createState(DialogState *dialogState)
 +{
 +	return new ButtonFieldState(dialogState, this);
 +}
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/ButtonField.h b/plugins/Skins/SkinLib/ButtonField.h new file mode 100644 index 0000000000..0d7a1555ca --- /dev/null +++ b/plugins/Skins/SkinLib/ButtonField.h @@ -0,0 +1,19 @@ +#ifndef __BUTTON_FIELD_H__
 +# define __BUTTON_FIELD_H__
 +
 +#include "ControlField.h"
 +
 +class ButtonField : public ControlField
 +{
 +public:
 +	ButtonField(Dialog *dlg, const char *name, HWND hwnd);
 +	virtual ~ButtonField();
 +
 +	virtual FieldType getType() const;
 +
 +	virtual FieldState * createState(DialogState *dialogState);
 +};
 +
 +
 +
 +#endif // __BUTTON_FIELD_H__
 diff --git a/plugins/Skins/SkinLib/ButtonFieldState.cpp b/plugins/Skins/SkinLib/ButtonFieldState.cpp new file mode 100644 index 0000000000..986484b20b --- /dev/null +++ b/plugins/Skins/SkinLib/ButtonFieldState.cpp @@ -0,0 +1,30 @@ +#include "globals.h"
 +#include "ButtonFieldState.h"
 +
 +ButtonFieldState::ButtonFieldState(DialogState *dialog, ControlField *field) 
 +		: ControlFieldState(dialog, field)
 +{
 +}
 +
 +ButtonFieldState::~ButtonFieldState()
 +{
 +}
 +
 +Size ButtonFieldState::getPreferedSize() const
 +{
 +	Size ret = getTextPreferedSize(DT_SINGLELINE);
 +
 +	int border = getField()->getBorderSize();
 +	ret.x += 2 * border;
 +	ret.y += 2 * border;
 +
 +	ret.x += 12;
 +	ret.y += 10;
 +
 +	return ret;
 +}
 +
 +bool ButtonFieldState::isEmpty() const
 +{
 +	return false;
 +}
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/ButtonFieldState.h b/plugins/Skins/SkinLib/ButtonFieldState.h new file mode 100644 index 0000000000..12b701035a --- /dev/null +++ b/plugins/Skins/SkinLib/ButtonFieldState.h @@ -0,0 +1,23 @@ +#ifndef __BUTTON_FIELD_STATE_H__
 +# define __BUTTON_FIELD_STATE_H__
 +
 +#include "ControlFieldState.h"
 +
 +
 +class ButtonFieldState : public ControlFieldState
 +{
 +public:
 +	virtual ~ButtonFieldState();
 +
 +	virtual Size getPreferedSize() const;
 +
 +	virtual bool isEmpty() const;
 +
 +private:
 +	ButtonFieldState(DialogState *dialog, ControlField *field);
 +
 +	friend class ButtonField;
 +};
 +
 +
 +#endif // __BUTTON_FIELD_STATE_H__
 diff --git a/plugins/Skins/SkinLib/ButtonFieldState_v8_wrapper.cpp b/plugins/Skins/SkinLib/ButtonFieldState_v8_wrapper.cpp new file mode 100644 index 0000000000..c5916b284c --- /dev/null +++ b/plugins/Skins/SkinLib/ButtonFieldState_v8_wrapper.cpp @@ -0,0 +1,20 @@ +#include "globals.h"
 +#include "ButtonFieldState_v8_wrapper.h"
 +#include <v8.h>
 +#include "ButtonFieldState.h"
 +
 +using namespace v8;
 +
 +
 +#ifdef UNICODE
 +# define V8_TCHAR uint16_t
 +#else
 +# define V8_TCHAR char
 +#endif
 +
 +
 +void AddButtonFieldStateAcessors(Handle<ObjectTemplate> &templ)
 +{
 +	HandleScope scope;
 +	
 +}
 diff --git a/plugins/Skins/SkinLib/ButtonFieldState_v8_wrapper.h b/plugins/Skins/SkinLib/ButtonFieldState_v8_wrapper.h new file mode 100644 index 0000000000..c69fdc5c87 --- /dev/null +++ b/plugins/Skins/SkinLib/ButtonFieldState_v8_wrapper.h @@ -0,0 +1,10 @@ +#ifndef __BUTTON_FIELD_STATE_V8_WRAPPER_H__
 +# define __BUTTON_FIELD_STATE_V8_WRAPPER_H__
 +
 +#include <v8.h>
 +
 +void AddButtonFieldStateAcessors(v8::Handle<v8::ObjectTemplate> &templ);
 +
 +
 +
 +#endif // __BUTTON_FIELD_STATE_V8_WRAPPER_H__
 diff --git a/plugins/Skins/SkinLib/ControlField.cpp b/plugins/Skins/SkinLib/ControlField.cpp new file mode 100644 index 0000000000..dd9d7026d9 --- /dev/null +++ b/plugins/Skins/SkinLib/ControlField.cpp @@ -0,0 +1,123 @@ +#include "globals.h"
 +#include "ControlField.h"
 +#include "ControlFieldState.h"
 +
 +
 +ControlField::ControlField(Dialog *dlg, const char *name, HWND aHwnd) 
 +		: Field(dlg, name), hwnd(aHwnd), textSet(false), hFont(NULL)
 +{
 +}
 +
 +
 +ControlField::~ControlField()
 +{
 +}
 +
 +
 +HWND ControlField::getHWND()
 +{
 +	return hwnd;
 +}
 +
 +
 +
 +void ControlField::setText(const TCHAR *text)
 +{
 +	if (text == NULL)
 +	{
 +		if (!textSet)
 +			return;
 +
 +		textSet = false;
 +		this->text.clear();
 +		fireOnChange();
 +	}
 +	else
 +	{
 +		textSet = true;
 +		if (this->text == text)
 +			return;
 +
 +		this->text = text;
 +	//	SetWindowText(hwnd, text);
 +		fireOnChange();
 +	}
 +}
 +
 +
 +const TCHAR * ControlField::getText()
 +{
 +	if (textSet)
 +		return text.c_str();
 +
 +	// Control text is the default value
 +	int length = GetWindowTextLength(hwnd);
 +	if (length <= 0)
 +	{
 +		text = _T("");
 +	}
 +	else
 +	{
 +		TCHAR *tmp = new TCHAR[length+1];
 +
 +		if (GetWindowText(hwnd, tmp, length+1) == 0)
 +			tmp[0] = 0;
 +
 +		text = tmp;
 +
 +		delete[] tmp;
 +	}
 +
 +	return text.c_str();
 +}
 +
 +
 +void ControlField::setFont(HFONT hFont)
 +{
 +	if (this->hFont == hFont)
 +		return;
 +
 +	this->hFont = hFont;
 +//	SendMessage(hwnd, WM_SETFONT, (WPARAM) hFont, FALSE);
 +	fireOnChange();
 +}
 +
 +
 +HFONT ControlField::getFont() const
 +{
 +	if (hFont != NULL)
 +		return hFont;
 +	
 +	// Control font is the default value
 +	return (HFONT) SendMessage(hwnd, WM_GETFONT, 0, 0);
 +}
 +
 +
 +COLORREF ControlField::getFontColor() const
 +{
 +	return GetSysColor(COLOR_WINDOWTEXT);
 +}
 +
 +
 +int ControlField::getBorderSize() const
 +{
 +	int exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
 +	if (exstyle & WS_EX_CLIENTEDGE) 
 +		return GetSystemMetrics(SM_CXEDGE);
 +	if (exstyle & WS_EX_STATICEDGE) 
 +		return GetSystemMetrics(SM_CXBORDER);
 +
 +	int style = GetWindowLong(hwnd, GWL_STYLE);
 +	if (style & WS_BORDER) 
 +		return GetSystemMetrics(SM_CXBORDER);
 +
 +	return 0;
 +}
 +
 +bool ControlField::isScrollVisible(bool horizontal) const
 +{
 +	SCROLLBARINFO sbi = {0};
 +	sbi.cbSize = sizeof(SCROLLBARINFO);
 +	GetScrollBarInfo(hwnd, horizontal ? OBJID_HSCROLL : OBJID_VSCROLL, &sbi);
 +	return (sbi.rgstate[0] & STATE_SYSTEM_INVISIBLE) == 0;
 +}
 diff --git a/plugins/Skins/SkinLib/ControlField.h b/plugins/Skins/SkinLib/ControlField.h new file mode 100644 index 0000000000..014ee04b9b --- /dev/null +++ b/plugins/Skins/SkinLib/ControlField.h @@ -0,0 +1,37 @@ +#ifndef __LABEL_CONTROL_FIELD_H__
 +# define __LABEL_CONTROL_FIELD_H__
 +
 +#include "Field.h"
 +
 +class ControlField : public Field
 +{
 +public:
 +	ControlField(Dialog *dlg, const char *name, HWND hwnd);
 +	virtual ~ControlField();
 +
 +	virtual HWND getHWND();
 +
 +	virtual void setText(const TCHAR *text);
 +	virtual const TCHAR * getText();
 +
 +	virtual void setFont(HFONT hFont);
 +	virtual HFONT getFont() const;
 +
 +	virtual COLORREF getFontColor() const;
 +
 +	virtual int getBorderSize() const;
 +
 +	virtual bool isScrollVisible(bool horizontal) const;
 +
 +private:
 +	HWND hwnd;
 +
 +	bool textSet;
 +	std::tstring text;
 +
 +	HFONT hFont;
 +};
 +
 +
 +
 +#endif // __LABEL_CONTROL_FIELD_H__
 diff --git a/plugins/Skins/SkinLib/ControlFieldState.cpp b/plugins/Skins/SkinLib/ControlFieldState.cpp new file mode 100644 index 0000000000..37c412058a --- /dev/null +++ b/plugins/Skins/SkinLib/ControlFieldState.cpp @@ -0,0 +1,86 @@ +#include "globals.h"
 +#include "ControlFieldState.h"
 +
 +
 +ControlFieldState::ControlFieldState(DialogState *dialog, ControlField *field) 
 +		: FieldState(dialog, field), textSet(false), font(field->getFont(), field->getFontColor())
 +{
 +}
 +
 +
 +ControlFieldState::~ControlFieldState()
 +{
 +}
 +
 +
 +ControlField * ControlFieldState::getField() const
 +{
 +	return (ControlField *) FieldState::getField();
 +}
 +
 +
 +Size ControlFieldState::getTextPreferedSize(unsigned int format) const
 +{
 +	HDC hdc = CreateCompatibleDC(NULL);
 +
 +	HFONT newFont = getFont()->getHFONT();
 +	HFONT oldFont = (HFONT) SelectObject(hdc, newFont);
 +
 +	int width = 0;
 +	int height = 0;
 +
 +	const TCHAR *text = getText();
 +	int len = lstrlen(text);
 +	if (len <= 0)
 +	{
 +		TEXTMETRIC tm = {0};
 +		GetTextMetrics(hdc, &tm);
 +		height = tm.tmHeight;
 +	}
 +	else
 +	{
 +		RECT rc = {0};
 +		if ((format & DT_SINGLELINE) == 0 && size.x >= 0)
 +		{
 +			format |= DT_WORDBREAK;
 +			rc.right = size.x;
 +		}
 +		DrawText(hdc, text, len, &rc, DT_CALCRECT | format);
 +		width = rc.right - rc.left;
 +		height = rc.bottom - rc.top;
 +	}
 +
 +	SelectObject(hdc, oldFont);
 +
 +	DeleteDC(hdc);
 +
 +	return Size(width, height);
 +}
 +
 +
 +const TCHAR * ControlFieldState::getText() const
 +{
 +	if (textSet)
 +		return text.c_str();
 +
 +	return getField()->getText();
 +}
 +
 +
 +void ControlFieldState::setText(const TCHAR *text)
 +{
 +	this->text = text;
 +	textSet = true;
 +}
 +
 +
 +FontState * ControlFieldState::getFont()
 +{
 +	return &font;
 +}
 +
 +
 +const FontState * ControlFieldState::getFont() const
 +{
 +	return &font;
 +}
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/ControlFieldState.h b/plugins/Skins/SkinLib/ControlFieldState.h new file mode 100644 index 0000000000..85186c304a --- /dev/null +++ b/plugins/Skins/SkinLib/ControlFieldState.h @@ -0,0 +1,39 @@ +#ifndef __LABEL_CONTROL_FIELD_STATE_H__
 +# define __LABEL_CONTROL_FIELD_STATE_H__
 +
 +#include "ControlField.h"
 +#include "FieldState.h"
 +#include "FontState.h"
 +
 +
 +class ControlFieldState : public FieldState
 +{
 +public:
 +	virtual ~ControlFieldState();
 +
 +	virtual ControlField * getField() const;
 +
 +	virtual Size getPreferedSize() const = 0;
 +
 +	virtual const TCHAR * getText() const;
 +	virtual void setText(const TCHAR *text);
 +
 +	virtual FontState * getFont();
 +	virtual const FontState * getFont() const;
 +
 +protected:
 +	ControlFieldState(DialogState *dialog, ControlField *field);
 +
 +	virtual Size getTextPreferedSize(unsigned int format) const;
 +
 +private:
 +	FontState font;
 +
 +	bool textSet;
 +	std::tstring text;
 +
 +	friend class ControlField;
 +};
 +
 +
 +#endif // __LABEL_CONTROL_FIELD_STATE_H__
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/ControlFieldState_v8_wrapper.cpp b/plugins/Skins/SkinLib/ControlFieldState_v8_wrapper.cpp new file mode 100644 index 0000000000..70d3e06a45 --- /dev/null +++ b/plugins/Skins/SkinLib/ControlFieldState_v8_wrapper.cpp @@ -0,0 +1,59 @@ +#include "globals.h"
 +#include "ControlFieldState_v8_wrapper.h"
 +#include <v8.h>
 +#include "ControlFieldState.h"
 +#include <utf8_helpers.h>
 +
 +using namespace v8;
 +
 +
 +#ifdef UNICODE
 +# define V8_TCHAR uint16_t
 +#else
 +# define V8_TCHAR char
 +#endif
 +
 +
 +static Handle<Value> Get_ControlFieldState_text(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	ControlFieldState *tmp = (ControlFieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( String::New((const V8_TCHAR *) tmp->getText()) );
 +}
 +
 +static void Set_ControlFieldState_text(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	ControlFieldState *tmp = (ControlFieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsString())
 +	{
 +		String::Utf8Value utf8_value(value);
 +		tmp->setText(Utf8ToTchar(*utf8_value));
 +	}
 +}
 +
 +
 +void AddControlFieldStateAcessors(Handle<ObjectTemplate> &templ)
 +{
 +	HandleScope scope;
 +	
 +	templ->SetAccessor(String::New("text"), Get_ControlFieldState_text, Set_ControlFieldState_text);
 +}
 diff --git a/plugins/Skins/SkinLib/ControlFieldState_v8_wrapper.h b/plugins/Skins/SkinLib/ControlFieldState_v8_wrapper.h new file mode 100644 index 0000000000..c86964ce30 --- /dev/null +++ b/plugins/Skins/SkinLib/ControlFieldState_v8_wrapper.h @@ -0,0 +1,10 @@ +#ifndef __CONTROL_FIELD_STATE_V8_WRAPPER_H__
 +# define __CONTROL_FIELD_STATE_V8_WRAPPER_H__
 +
 +#include <v8.h>
 +
 +void AddControlFieldStateAcessors(v8::Handle<v8::ObjectTemplate> &templ);
 +
 +
 +
 +#endif // __CONTROL_FIELD_STATE_V8_WRAPPER_H__
 diff --git a/plugins/Skins/SkinLib/Dialog.cpp b/plugins/Skins/SkinLib/Dialog.cpp new file mode 100644 index 0000000000..edc8437817 --- /dev/null +++ b/plugins/Skins/SkinLib/Dialog.cpp @@ -0,0 +1,100 @@ +#include "globals.h"
 +#include "Dialog.h"
 +#include "DialogState.h"
 +
 +
 +Dialog::Dialog(const char *aName) : name(aName)
 +{
 +}
 +
 +
 +Dialog::~Dialog()
 +{
 +	for(unsigned int i = 0; i < fields.size(); i++) 
 +		delete fields[i];
 +
 +	fields.clear();
 +}
 +
 +
 +const char * Dialog::getName() const
 +{
 +	return name.c_str();
 +}
 +
 +
 +bool Dialog::addField(Field *field)
 +{
 +	if (getField(field->getName()) != NULL)
 +		return false;
 +
 +	fields.push_back(field);
 +	return true;
 +}
 +
 +
 +Field * Dialog::getField(const char *name) const
 +{
 +	if (name == NULL || name[0] == 0)
 +		return NULL;
 +
 +	for(unsigned int i = 0; i < fields.size(); i++) 
 +	{
 +		Field *field = fields[i];
 +		if (strcmp(name, field->getName()) == 0)
 +			return field;
 +	}
 +
 +	return NULL;
 +}
 +
 +Field * Dialog::getField(unsigned int pos) const
 +{
 +	if (pos >= fields.size())
 +		return NULL;
 +	return fields[pos];
 +}
 +
 +int Dialog::getIndexOf(Field *field) const
 +{
 +	for(unsigned int i = 0; i < fields.size(); i++) 
 +	{
 +		Field *f = fields[i];
 +		if (field == f)
 +			return i;
 +	}
 +
 +	return -1;
 +}
 +
 +unsigned int Dialog::getFieldCount() const
 +{
 +	return fields.size();
 +}
 +
 +DialogInfo * Dialog::getInfo()
 +{
 +	return &info;
 +}
 +
 +const Size & Dialog::getSize() const
 +{
 +	return size;
 +}
 +
 +
 +void Dialog::setSize(const Size &size)
 +{
 +	this->size = size;
 +}
 +
 +
 +DialogState * Dialog::createState()
 +{
 +	DialogState *ret = new DialogState(this);
 +
 +	for(unsigned int i = 0; i < fields.size(); i++) 
 +		ret->fields.push_back(fields[i]->createState(ret));
 +
 +	return ret;
 +}
 diff --git a/plugins/Skins/SkinLib/Dialog.h b/plugins/Skins/SkinLib/Dialog.h new file mode 100644 index 0000000000..0e85b8e340 --- /dev/null +++ b/plugins/Skins/SkinLib/Dialog.h @@ -0,0 +1,41 @@ +#ifndef __DIALOG_H__
 +# define __DIALOG_H__
 +
 +#include <vector>
 +#include "Field.h"
 +#include "DialogInfo.h"
 +
 +class DialogState;
 +
 +
 +/// It is responsible for freeing the Fields
 +class Dialog
 +{
 +public:
 +	Dialog(const char *name);
 +	virtual ~Dialog();
 +
 +	virtual const char * getName() const;
 +
 +	virtual bool addField(Field *field);
 +	virtual Field * getField(const char *name) const;
 +	virtual Field * getField(unsigned int pos) const;
 +	virtual int getIndexOf(Field *field) const;
 +	virtual unsigned int getFieldCount() const;
 +
 +	virtual DialogInfo * getInfo();
 +
 +	virtual const Size & getSize() const;
 +	virtual void setSize(const Size &size);
 +
 +	virtual DialogState * createState();
 +
 +private:
 +	const std::string name;
 +	std::vector<Field *> fields;
 +	DialogInfo info;
 +	Size size;
 +};
 +
 +
 +#endif // __DIALOG_H__
 diff --git a/plugins/Skins/SkinLib/DialogInfo.cpp b/plugins/Skins/SkinLib/DialogInfo.cpp new file mode 100644 index 0000000000..fd29a37392 --- /dev/null +++ b/plugins/Skins/SkinLib/DialogInfo.cpp @@ -0,0 +1,190 @@ +#include "globals.h"
 +#include "DialogInfo.h"
 +#include "tstring.h"
 +
 +class DialogInfoValue
 +{
 +public:
 +	DialogInfoValue(const char *aName) : name(aName), type(UNKNOWN) {}
 +
 +	const char * getName() { return name.c_str(); }
 +
 +	void set(const TCHAR *value) { valueString = value; type = TYPE_STRING; }
 +	void set(int value) { valueInt = value; type = TYPE_INT; }
 +	void set(double value) { valueDouble = value; type = TYPE_DOUBLE; }
 +	void set(bool value) { valueBool = value; type = TYPE_BOOL; }
 +
 +	DialogInfoType getType() { return type; }
 +
 +	const TCHAR * getAsString() { return valueString.c_str(); }
 +	int getAsInt() { return valueInt; }
 +	double getAsDouble() { return valueDouble; }
 +	bool getAsBool() { return valueBool; }
 +
 +private:
 +	std::string name;
 +
 +	DialogInfoType type;
 +
 +	std::tstring valueString;
 +	int valueInt;
 +	double valueDouble;
 +	bool valueBool;
 +};
 +
 +DialogInfo::DialogInfo()
 +{
 +}
 +
 +DialogInfo::~DialogInfo()
 +{
 +	for(size_t i = 0; i < values.size(); ++i)
 +		delete values[i];
 +}
 +
 +
 +void DialogInfo::set(const char *name, const TCHAR *value)
 +{
 +	bool isVar;
 +	DialogInfoValue * val = findValue(name, true, &isVar);
 +
 +	if (isVar)
 +		return;
 +
 +	val->set(value);
 +}
 +
 +void DialogInfo::set(const char *name, int value)
 +{
 +	bool isVar;
 +	DialogInfoValue * val = findValue(name, true, &isVar);
 +
 +	if (isVar)
 +		return;
 +
 +	val->set(value);
 +}
 +
 +void DialogInfo::set(const char *name, double value)
 +{
 +	bool isVar;
 +	DialogInfoValue * val = findValue(name, true, &isVar);
 +
 +	if (isVar)
 +		return;
 +
 +	val->set(value);
 +}
 +
 +void DialogInfo::set(const char *name, bool value)
 +{
 +	bool isVar;
 +	DialogInfoValue * val = findValue(name, true, &isVar);
 +
 +	if (isVar)
 +		return;
 +
 +	val->set(value);
 +}
 +
 +void DialogInfo::remove(const char *name)
 +{
 +	size_t len = strlen(name);
 +
 +	for(std::vector<DialogInfoValue *>::iterator it = values.begin(); it != values.end(); )
 +	{
 +		DialogInfoValue *val = *it;
 +
 +		if (stricmp(name, val->getName()) == 0)
 +			it = values.erase(it);
 +		
 +		else if (strnicmp(name, val->getName(), len) == 0 && val->getName()[len] == '.')
 +			it = values.erase(it);
 +		
 +		else
 +			it++;
 +	}
 +}
 +
 +DialogInfoType DialogInfo::getType(const char *name)
 +{
 +	bool isVar;
 +	DialogInfoValue * val = findValue(name, false, &isVar);
 +
 +	if (isVar)
 +		return TYPE_VARIABLE;
 +
 +	else if (val == NULL)
 +		return UNKNOWN;
 +
 +	else
 +		return val->getType();
 +}
 +
 +
 +const TCHAR * DialogInfo::getAsString(const char *name)
 +{
 +	DialogInfoValue * val = findValue(name);
 +	if (val == NULL)
 +		return NULL;
 +	
 +	return val->getAsString();
 +}
 +
 +int DialogInfo::getAsInt(const char *name)
 +{
 +	DialogInfoValue * val = findValue(name);
 +	if (val == NULL)
 +		return 0;
 +	
 +	return val->getAsInt();
 +}
 +
 +double DialogInfo::getAsDouble(const char *name)
 +{
 +	DialogInfoValue * val = findValue(name);
 +	if (val == NULL)
 +		return 0;
 +	
 +	return val->getAsDouble();
 +}
 +
 +bool DialogInfo::getAsBool(const char *name)
 +{
 +	DialogInfoValue * val = findValue(name);
 +	if (val == NULL)
 +		return false;
 +	
 +	return val->getAsBool();
 +}
 +
 +DialogInfoValue * DialogInfo::findValue(const char *name, bool create, bool *isVar)
 +{
 +	size_t len = strlen(name);
 +
 +	if (isVar != NULL) *isVar = false;
 +
 +	for(size_t i = 0; i < values.size(); ++i)
 +	{
 +		DialogInfoValue *val = values[i];
 +
 +		if (stricmp(name, val->getName()) == 0)
 +		{
 +			return val;
 +		}
 +		else if (strnicmp(name, val->getName(), len) == 0 && val->getName()[len] == '.')
 +		{
 +			if (isVar != NULL) *isVar = true;
 +			return val;
 +		}
 +	}
 +
 +	if (create)
 +	{
 +		DialogInfoValue *ret = new DialogInfoValue(name);
 +		values.push_back(ret);
 +		return ret;
 +	}
 +
 +	return NULL;
 +}
 diff --git a/plugins/Skins/SkinLib/DialogInfo.h b/plugins/Skins/SkinLib/DialogInfo.h new file mode 100644 index 0000000000..02f07310d7 --- /dev/null +++ b/plugins/Skins/SkinLib/DialogInfo.h @@ -0,0 +1,50 @@ +#ifndef __DIALOG_INFO_H__
 +# define __DIALOG_INFO_H__
 +
 +#include <windows.h>
 +#include <vector>
 +
 +
 +enum DialogInfoType
 +{
 +	UNKNOWN = 0,
 +	TYPE_VARIABLE,
 +	TYPE_INT,
 +	TYPE_DOUBLE,
 +	TYPE_BOOL,
 +	TYPE_STRING
 +};
 +
 +
 +class DialogInfoValue;
 +
 +class DialogInfo
 +{
 +public:
 +	DialogInfo();
 +	~DialogInfo();
 +
 +	void set(const char *name, const TCHAR *value);
 +	void set(const char *name, int value);
 +	void set(const char *name, double value);
 +	void set(const char *name, bool value);
 +
 +	void remove(const char *name);
 +
 +	DialogInfoType getType(const char *name);
 +
 +	const TCHAR * getAsString(const char *name);
 +	int getAsInt(const char *name);
 +	double getAsDouble(const char *name);
 +	bool getAsBool(const char *name);
 +
 +private:
 +	std::vector<DialogInfoValue *> values; 
 +
 +	DialogInfoValue * findValue(const char *name, bool create = false, bool *isVar = NULL);
 +
 +};
 +
 +
 +
 +#endif // __DIALOG_INFO_H__
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/DialogState.cpp b/plugins/Skins/SkinLib/DialogState.cpp new file mode 100644 index 0000000000..e1e7654930 --- /dev/null +++ b/plugins/Skins/SkinLib/DialogState.cpp @@ -0,0 +1,132 @@ +#include "globals.h"
 +#include "DialogState.h"
 +
 +
 +DialogState::DialogState(Dialog *aDialog) : dialog(aDialog), size(-1,-1), borders(0,0,0,0)
 +{
 +}
 +
 +DialogState::~DialogState()
 +{
 +	for(unsigned int i = 0; i < fields.size(); i++) 
 +		delete fields[i];
 +
 +	fields.clear();
 +}
 +
 +Dialog * DialogState::getDialog() const
 +{
 +	return dialog;
 +}
 +
 +FieldState * DialogState::getField(const char *name) const
 +{
 +	if (name == NULL || name[0] == 0)
 +		return NULL;
 +
 +	for(unsigned int i = 0; i < fields.size(); i++) 
 +	{
 +		FieldState *field = fields[i];
 +		if (strcmp(name, field->getField()->getName()) == 0)
 +			return field;
 +	}
 +
 +	return NULL;
 +}
 +
 +int DialogState::getX() const
 +{
 +	return 0;
 +}
 +
 +int DialogState::getY() const
 +{
 +	return 0;
 +}
 +
 +int DialogState::getLeft() const
 +{
 +	return getX();
 +}
 +
 +int DialogState::getTop() const
 +{
 +	return getY();
 +}
 +
 +int DialogState::getRight() const
 +{
 +	return getX() + getWidth();
 +}
 +
 +int DialogState::getBottom() const
 +{
 +	return getY() + getHeight();
 +}
 +
 +int DialogState::getWidth() const
 +{
 +	if (size.x >= 0)
 +		return size.x - getHorizontalBorders();
 +
 +	return dialog->getSize().x - getHorizontalBorders();
 +}
 +
 +void DialogState::setWidth(int width)
 +{
 +	size.x = max(0, width) + getHorizontalBorders();
 +}
 +
 +int DialogState::getHeight() const
 +{
 +	if (size.y >= 0)
 +		return size.y - getVerticalBorders();
 +
 +	return dialog->getSize().y - getVerticalBorders();
 +}
 +
 +void DialogState::setHeight(int height)
 +{
 +	size.y = max(0, height) + getVerticalBorders();
 +}
 +
 +BorderState * DialogState::getBorders()
 +{
 +	return &borders;
 +}
 +
 +const BorderState * DialogState::getBorders() const
 +{
 +	return &borders;
 +}
 +
 +int DialogState::getHorizontalBorders() const
 +{
 +	return borders.getLeft() + borders.getRight();
 +}
 +
 +int DialogState::getVerticalBorders() const
 +{
 +	return borders.getTop() + borders.getBottom();
 +}
 +
 +RECT DialogState::getInsideRect() const
 +{
 +	RECT ret;
 +	ret.left = borders.getLeft();
 +	ret.right = ret.left + getWidth();
 +	ret.top = borders.getTop();
 +	ret.bottom = ret.top + getHeight();
 +	return ret;
 +}
 +
 +RECT DialogState::getRect() const
 +{
 +	RECT ret;
 +	ret.left = 0;
 +	ret.right = borders.getLeft() + getWidth() + borders.getRight();
 +	ret.top = 0;
 +	ret.bottom = borders.getTop() + getHeight() + borders.getBottom();
 +	return ret;
 +}
 +
 diff --git a/plugins/Skins/SkinLib/DialogState.h b/plugins/Skins/SkinLib/DialogState.h new file mode 100644 index 0000000000..e27fc929da --- /dev/null +++ b/plugins/Skins/SkinLib/DialogState.h @@ -0,0 +1,59 @@ +#ifndef __DIALOG_STATE_H__
 +# define __DIALOG_STATE_H__
 +
 +#include "Dialog.h"
 +#include "FieldState.h"
 +#include "BorderState.h"
 +
 +
 +/// This have to be deleted before the owning dialog
 +/// It is responsible for freeing the FieldStates
 +class DialogState
 +{
 +public:
 +	~DialogState();
 +
 +	Dialog * getDialog() const;
 +
 +	std::vector<FieldState *> fields;
 +	FieldState * getField(const char *name) const;
 +
 +	// Used inside script
 +
 +	virtual int getX() const;
 +	virtual int getY() const;
 +	virtual int getLeft() const;
 +	virtual int getTop() const;
 +	virtual int getRight() const;
 +	virtual int getBottom() const;
 +
 +	int getWidth() const;
 +	void setWidth(int width);
 +
 +	int getHeight() const;
 +	void setHeight(int height);
 +
 +	BorderState * getBorders();
 +	const BorderState * getBorders() const;
 +
 +	// Results
 +
 +	RECT getInsideRect() const;
 +	RECT getRect() const;
 +
 +private:
 +	DialogState(Dialog *dialog);
 +
 +	Dialog *dialog;
 +
 +	Size size;
 +	BorderState borders;
 +
 +	int getHorizontalBorders() const;
 +	int getVerticalBorders() const;
 +
 +	friend class Dialog;
 +};
 +
 +
 +#endif // __DIALOG_STATE_H__
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/DialogState_v8_wrapper.cpp b/plugins/Skins/SkinLib/DialogState_v8_wrapper.cpp new file mode 100644 index 0000000000..5739414d69 --- /dev/null +++ b/plugins/Skins/SkinLib/DialogState_v8_wrapper.cpp @@ -0,0 +1,233 @@ +#include "globals.h"
 +#include "DialogState_v8_wrapper.h"
 +#include <v8.h>
 +#include "DialogState.h"
 +
 +using namespace v8;
 +
 +
 +#ifdef UNICODE
 +# define V8_TCHAR uint16_t
 +#else
 +# define V8_TCHAR char
 +#endif
 +
 +
 +static Handle<Value> Get_DialogState_width(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	DialogState *tmp = (DialogState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getWidth()) );
 +}
 +
 +static void Set_DialogState_width(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	DialogState *tmp = (DialogState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setWidth(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_DialogState_height(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	DialogState *tmp = (DialogState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getHeight()) );
 +}
 +
 +static void Set_DialogState_height(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	DialogState *tmp = (DialogState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setHeight(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_DialogState_x(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	DialogState *tmp = (DialogState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getX()) );
 +}
 +
 +
 +static Handle<Value> Get_DialogState_y(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	DialogState *tmp = (DialogState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getY()) );
 +}
 +
 +
 +static Handle<Value> Get_DialogState_left(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	DialogState *tmp = (DialogState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getLeft()) );
 +}
 +
 +
 +static Handle<Value> Get_DialogState_top(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	DialogState *tmp = (DialogState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getTop()) );
 +}
 +
 +
 +static Handle<Value> Get_DialogState_right(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	DialogState *tmp = (DialogState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getRight()) );
 +}
 +
 +
 +static Handle<Value> Get_DialogState_bottom(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	DialogState *tmp = (DialogState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getBottom()) );
 +}
 +
 +
 +static Handle<Value> Get_DialogState_borders(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	DialogState *tmp = (DialogState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +	
 +	return scope.Close( self->Get(String::New("bordersRaw")) );
 +}
 +
 +static void Set_DialogState_borders(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	DialogState *tmp = (DialogState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsInt32())
 +		tmp->getBorders()->setAll(value->Int32Value()); 
 +}
 +
 +
 +void AddDialogStateAcessors(Handle<ObjectTemplate> &templ)
 +{
 +	HandleScope scope;
 +	
 +	templ->SetAccessor(String::New("width"), Get_DialogState_width, Set_DialogState_width);
 +	templ->SetAccessor(String::New("height"), Get_DialogState_height, Set_DialogState_height);
 +	templ->SetAccessor(String::New("x"), Get_DialogState_x, NULL, Handle<Value>(), DEFAULT, ReadOnly);
 +	templ->SetAccessor(String::New("y"), Get_DialogState_y, NULL, Handle<Value>(), DEFAULT, ReadOnly);
 +	templ->SetAccessor(String::New("left"), Get_DialogState_left, NULL, Handle<Value>(), DEFAULT, ReadOnly);
 +	templ->SetAccessor(String::New("top"), Get_DialogState_top, NULL, Handle<Value>(), DEFAULT, ReadOnly);
 +	templ->SetAccessor(String::New("right"), Get_DialogState_right, NULL, Handle<Value>(), DEFAULT, ReadOnly);
 +	templ->SetAccessor(String::New("bottom"), Get_DialogState_bottom, NULL, Handle<Value>(), DEFAULT, ReadOnly);
 +	templ->SetAccessor(String::New("borders"), Get_DialogState_borders, Set_DialogState_borders);
 +}
 diff --git a/plugins/Skins/SkinLib/DialogState_v8_wrapper.h b/plugins/Skins/SkinLib/DialogState_v8_wrapper.h new file mode 100644 index 0000000000..709ef2d738 --- /dev/null +++ b/plugins/Skins/SkinLib/DialogState_v8_wrapper.h @@ -0,0 +1,10 @@ +#ifndef __DIALOG_STATE_V8_WRAPPER_H__
 +# define __DIALOG_STATE_V8_WRAPPER_H__
 +
 +#include <v8.h>
 +
 +void AddDialogStateAcessors(v8::Handle<v8::ObjectTemplate> &templ);
 +
 +
 +
 +#endif // __DIALOG_STATE_V8_WRAPPER_H__
 diff --git a/plugins/Skins/SkinLib/EditField.cpp b/plugins/Skins/SkinLib/EditField.cpp new file mode 100644 index 0000000000..8eb0d5050f --- /dev/null +++ b/plugins/Skins/SkinLib/EditField.cpp @@ -0,0 +1,23 @@ +#include "globals.h"
 +#include "EditField.h"
 +#include "EditFieldState.h"
 +
 +
 +EditField::EditField(Dialog *dlg, const char *name, HWND hwnd) 
 +		: ControlField(dlg, name, hwnd)
 +{
 +}
 +
 +EditField::~EditField()
 +{
 +}
 +
 +FieldType EditField::getType() const
 +{
 +	return CONTROL_EDIT;
 +}
 +
 +FieldState * EditField::createState(DialogState *dialogState)
 +{
 +	return new EditFieldState(dialogState, this);
 +}
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/EditField.h b/plugins/Skins/SkinLib/EditField.h new file mode 100644 index 0000000000..f69f23576c --- /dev/null +++ b/plugins/Skins/SkinLib/EditField.h @@ -0,0 +1,19 @@ +#ifndef __EDIT_FIELD_H__
 +# define __EDIT_FIELD_H__
 +
 +#include "ControlField.h"
 +
 +
 +class EditField : public ControlField
 +{
 +public:
 +	EditField(Dialog *dlg, const char *name, HWND hwnd);
 +	virtual ~EditField();
 +
 +	virtual FieldType getType() const;
 +
 +	virtual FieldState * createState(DialogState *dialogState);
 +};
 +
 +
 +#endif // __EDIT_FIELD_H__
 diff --git a/plugins/Skins/SkinLib/EditFieldState.cpp b/plugins/Skins/SkinLib/EditFieldState.cpp new file mode 100644 index 0000000000..e634be7b55 --- /dev/null +++ b/plugins/Skins/SkinLib/EditFieldState.cpp @@ -0,0 +1,58 @@ +#include "globals.h"
 +#include "EditFieldState.h"
 +
 +
 +EditFieldState::EditFieldState(DialogState *dialog, EditField *field) 
 +		: ControlFieldState(dialog, field)
 +{
 +}
 +
 +EditFieldState::~EditFieldState()
 +{
 +}
 +
 +Size EditFieldState::getPreferedSize() const
 +{
 +	ControlField *field = getField();
 +	HWND hwnd = field->getHWND();
 +
 +	int style = GetWindowLong(hwnd, GWL_STYLE);
 +	int exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
 +
 +	int format = DT_NOPREFIX | DT_EDITCONTROL;
 +	if (!(style & ES_MULTILINE))
 +		format |= DT_SINGLELINE;
 +	Size ret = getTextPreferedSize(format);
 +
 +	RECT rc = {0};
 +	SetRect(&rc, 0, 0, ret.x, ret.y);
 +	AdjustWindowRectEx(&rc, style, false, exstyle);
 +
 +	bool hasHorScroll = field->isScrollVisible(true);
 +	if (hasHorScroll) 
 +		rc.bottom += GetSystemMetrics(SM_CYHSCROLL);
 +	if (field->isScrollVisible(false)) 
 +		rc.right += GetSystemMetrics(SM_CXVSCROLL);
 +
 +	int margins = SendMessage(hwnd, EM_GETMARGINS, 0, 0);
 +	rc.left -= LOWORD(margins);
 +	rc.right += HIWORD(margins);
 +	if (hasHorScroll || (style & ES_AUTOHSCROLL)) 
 +		rc.right++;
 +
 +	ret.x = rc.right - rc.left;
 +	ret.y = rc.bottom - rc.top;
 +
 +	if ((exstyle & WS_EX_CLIENTEDGE) || (exstyle & WS_EX_STATICEDGE) || (style & WS_BORDER))
 +	{
 +		ret.x += 3;
 +		ret.y += 3;
 +	}
 +
 +	return ret;
 +}
 +
 +bool EditFieldState::isEmpty() const
 +{
 +	return false;
 +}
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/EditFieldState.h b/plugins/Skins/SkinLib/EditFieldState.h new file mode 100644 index 0000000000..c2372d553d --- /dev/null +++ b/plugins/Skins/SkinLib/EditFieldState.h @@ -0,0 +1,24 @@ +#ifndef __EDIT_FIELD_STATE_H__
 +# define __EDIT_FIELD_STATE_H__
 +
 +#include "ControlFieldState.h"
 +#include "EditField.h"
 +
 +
 +class EditFieldState : public ControlFieldState
 +{
 +public:
 +	virtual ~EditFieldState();
 +
 +	virtual Size getPreferedSize() const;
 +
 +	virtual bool isEmpty() const;
 +
 +private:
 +	EditFieldState(DialogState *dialog, EditField *field);
 +
 +	friend class EditField;
 +};
 +
 +
 +#endif // __EDIT_FIELD_STATE_H__
 diff --git a/plugins/Skins/SkinLib/EditFieldState_v8_wrapper.cpp b/plugins/Skins/SkinLib/EditFieldState_v8_wrapper.cpp new file mode 100644 index 0000000000..86522b87e3 --- /dev/null +++ b/plugins/Skins/SkinLib/EditFieldState_v8_wrapper.cpp @@ -0,0 +1,20 @@ +#include "globals.h"
 +#include "EditFieldState_v8_wrapper.h"
 +#include <v8.h>
 +#include "EditFieldState.h"
 +
 +using namespace v8;
 +
 +
 +#ifdef UNICODE
 +# define V8_TCHAR uint16_t
 +#else
 +# define V8_TCHAR char
 +#endif
 +
 +
 +void AddEditFieldStateAcessors(Handle<ObjectTemplate> &templ)
 +{
 +	HandleScope scope;
 +	
 +}
 diff --git a/plugins/Skins/SkinLib/EditFieldState_v8_wrapper.h b/plugins/Skins/SkinLib/EditFieldState_v8_wrapper.h new file mode 100644 index 0000000000..a58972549f --- /dev/null +++ b/plugins/Skins/SkinLib/EditFieldState_v8_wrapper.h @@ -0,0 +1,10 @@ +#ifndef __EDIT_FIELD_STATE_V8_WRAPPER_H__
 +# define __EDIT_FIELD_STATE_V8_WRAPPER_H__
 +
 +#include <v8.h>
 +
 +void AddEditFieldStateAcessors(v8::Handle<v8::ObjectTemplate> &templ);
 +
 +
 +
 +#endif // __EDIT_FIELD_STATE_V8_WRAPPER_H__
 diff --git a/plugins/Skins/SkinLib/Field.cpp b/plugins/Skins/SkinLib/Field.cpp new file mode 100644 index 0000000000..24b823bde6 --- /dev/null +++ b/plugins/Skins/SkinLib/Field.cpp @@ -0,0 +1,56 @@ +#include "globals.h"
 +#include "Field.h"
 +#include "FieldState.h"
 +
 +
 +Field::Field(Dialog *aDlg, const char *aName) 
 +		: dlg(aDlg), name(aName), onChangeCallback(NULL), onChangeCallbackParam(NULL), enabled(true)
 +{
 +}
 +
 +Field::~Field()
 +{
 +}
 +
 +Dialog * Field::getDialog() const
 +{
 +	return dlg;
 +}
 +
 +const char * Field::getName() const
 +{
 +	return name.c_str();
 +}
 +
 +bool Field::isEnabled() const
 +{
 +	return enabled;
 +}
 +
 +void Field::setEnabled(bool enabled)
 +{
 +	this->enabled = enabled;
 +	fireOnChange();
 +}
 +
 +const TCHAR * Field::getToolTip() const
 +{
 +	return tooltip.c_str();
 +}
 +
 +void Field::setToolTip(const TCHAR *tooltip)
 +{
 +	this->tooltip = tooltip;
 +}
 +
 +void Field::setOnChangeCallback(FieldCallback cb, void *param /*= NULL*/)
 +{
 +	onChangeCallback = cb;
 +	onChangeCallbackParam = param;
 +}
 +
 +void Field::fireOnChange() const
 +{
 +	if (onChangeCallback != NULL)
 +		onChangeCallback(onChangeCallbackParam, this);
 +}
 diff --git a/plugins/Skins/SkinLib/Field.h b/plugins/Skins/SkinLib/Field.h new file mode 100644 index 0000000000..4cf7faaa51 --- /dev/null +++ b/plugins/Skins/SkinLib/Field.h @@ -0,0 +1,66 @@ +#ifndef __FIELD_H__
 +# define __FIELD_H__
 +
 +#include <windows.h>
 +#include <tchar.h>
 +#include "tstring.h"
 +#include "Size.h"
 +#include "Position.h"
 +
 +
 +enum FieldType
 +{
 +	SIMPLE_TEXT = 1,
 +	SIMPLE_IMAGE,
 +	SIMPLE_ICON,
 +	CONTROL_LABEL,
 +	CONTROL_BUTTON,
 +	CONTROL_EDIT,
 +	USER_DEFINED = 0x100
 +};
 +
 +class Dialog;
 +class DialogState;
 +class Field;
 +class FieldState;
 +
 +typedef void (*FieldCallback)(void *param, const Field *field);
 +
 +
 +class Field
 +{
 +public:
 +	Field(Dialog *dlg, const char *name);
 +	virtual ~Field();
 +
 +	virtual Dialog * getDialog() const;
 +	virtual const char * getName() const;
 +	virtual FieldType getType() const = 0;
 +
 +	virtual bool isEnabled() const;
 +	virtual void setEnabled(bool enabled);
 +
 +	virtual const TCHAR * getToolTip() const;
 +	virtual void setToolTip(const TCHAR *tooltip);
 +
 +	virtual FieldState * createState(DialogState *dialogState) = 0;
 +
 +	virtual void setOnChangeCallback(FieldCallback cb, void *param = NULL);
 +
 +protected:
 +	void fireOnChange() const;
 +
 +private:
 +	Dialog *dlg;
 +	const std::string name;
 +	bool enabled;
 +	std::tstring tooltip;
 +
 +	FieldCallback onChangeCallback;
 +	void *onChangeCallbackParam;
 +};
 +
 +
 +
 +
 +#endif // __FIELD_H__
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/FieldState.cpp b/plugins/Skins/SkinLib/FieldState.cpp new file mode 100644 index 0000000000..68510051da --- /dev/null +++ b/plugins/Skins/SkinLib/FieldState.cpp @@ -0,0 +1,303 @@ +#include "globals.h"
 +#include "FieldState.h"
 +#include "DialogState.h"
 +#include "BorderState.h"
 +
 +#define START		1<<0
 +#define LEN			1<<1
 +#define END			1<<2
 +#define USING_MASK	0xFF
 +#define LAST_SHIFT	8
 +#define SET(_FIELD_, _ITEM_)		_FIELD_ = (((_FIELD_ | _ITEM_) & USING_MASK) | (_ITEM_ << LAST_SHIFT))
 +#define LAST_SET(_FIELD_)			(_FIELD_ >> LAST_SHIFT)
 +
 +
 +FieldState::FieldState(DialogState *aDialog, Field *aField) 
 +		: field(aField), dialog(aDialog), size(-1, -1), pos(0, 0), 
 +		  usingX(0), usingY(0), visible(aField->isEnabled()), borders(0,0,0,0),
 +		  tooltipSet(false), halign(HORIZONTAL_ALIGN_LEFT), valign(VERTICAL_ALIGN_TOP)
 +{
 +}
 +
 +FieldState::~FieldState()
 +{
 +}
 +
 +Field * FieldState::getField() const
 +{
 +	return field;
 +}
 +
 +DialogState * FieldState::getDialog() const
 +{
 +	return dialog;
 +}
 +
 +int FieldState::getX() const
 +{
 +	return pos.x;
 +}
 +
 +void FieldState::setX(int x)
 +{
 +	if (usingX & END)
 +	{
 +		int diff = x - getX();
 +		size.x = max(0, getWidth() - getHorizontalBorders() - diff);
 +	}
 +
 +	pos.x = x;
 +
 +	SET(usingX, START);
 +}
 +
 +int FieldState::getY() const
 +{
 +	return pos.y;
 +}
 +
 +void FieldState::setY(int y)
 +{
 +	if (usingY & END)
 +	{
 +		int diff = y - getY();
 +		size.y = max(0, getHeight() - getVerticalBorders() - diff);
 +	}
 +
 +	pos.y = y;
 +
 +	SET(usingY, START);
 +}
 +
 +int FieldState::getWidth() const
 +{
 +	if (size.x >= 0)
 +		return size.x + getHorizontalBorders();
 +
 +	return getPreferedSize().x + getHorizontalBorders();
 +}
 +
 +void FieldState::setWidth(int width)
 +{
 +	width = max(0, width - getHorizontalBorders()) + getHorizontalBorders();
 +
 +	if (LAST_SET(usingX) == END)
 +	{
 +		int diff = width - getWidth();
 +		pos.x = getX() - diff;
 +	}
 +
 +	size.x = width - getHorizontalBorders();
 +
 +	usingX |= LEN;
 +}
 +
 +int FieldState::getHeight() const
 +{
 +	if (size.y >= 0)
 +		return size.y + getVerticalBorders();
 +
 +	return getPreferedSize().y + getVerticalBorders();
 +}
 +
 +void FieldState::setHeight(int height)
 +{
 +	height = max(0, height - getVerticalBorders()) + getVerticalBorders();
 +
 +	if (LAST_SET(usingY) == END)
 +	{
 +		int diff = height - getHeight();
 +		pos.y = getY() - diff;
 +	}
 +
 +	size.y = height - getVerticalBorders();
 +
 +	usingY |= LEN;
 +}
 +
 +bool FieldState::isVisible() const
 +{
 +	if (!visible)
 +		return false;
 +
 +	RECT rc = getRect();
 +	if (rc.right <= rc.left || rc.bottom <= rc.top)
 +		return false;
 +
 +	return true;
 +}
 +
 +void FieldState::setVisible(bool visible)
 +{
 +	this->visible = visible;
 +}
 +
 +bool FieldState::isEnabled() const
 +{
 +	return field->isEnabled();
 +}
 +
 +int FieldState::getLeft() const
 +{
 +	return getX();
 +}
 +
 +void FieldState::setLeft(int left)
 +{
 +	setX(left);
 +}
 +
 +int FieldState::getTop() const
 +{
 +	return getY();
 +}
 +
 +void FieldState::setTop(int top)
 +{
 +	setY(top);
 +}
 +
 +int FieldState::getRight() const
 +{
 +	return getX() + getWidth();
 +}
 +
 +void FieldState::setRight(int right)
 +{
 +	if (usingX & START)
 +	{
 +		size.x = max(0, right - getX());
 +	}
 +	else
 +	{
 +		pos.x = right - getWidth();
 +	}
 +
 +	SET(usingX, END);
 +}
 +
 +int FieldState::getBottom() const
 +{
 +	return getY() + getHeight();
 +}
 +
 +void FieldState::setBottom(int botom)
 +{
 +	if (usingY & START)
 +	{
 +		size.y = max(0, botom - getY());
 +	}
 +	else
 +	{
 +		pos.y = botom - getHeight();
 +	}
 +
 +	SET(usingY, END);
 +}
 +
 +const TCHAR * FieldState::getToolTip() const
 +{
 +	if (tooltipSet)
 +		return tooltip.c_str();
 +	else
 +		return field->getToolTip();
 +}
 +
 +void FieldState::setToolTip(const TCHAR *tooltip)
 +{
 +	this->tooltip = tooltip;
 +	tooltipSet = true;
 +}
 +
 +BorderState * FieldState::getBorders()
 +{
 +	return &borders;
 +}
 +
 +const BorderState * FieldState::getBorders() const
 +{
 +	return &borders;
 +}
 +
 +int FieldState::getHorizontalBorders() const
 +{
 +	return borders.getLeft() + borders.getRight();
 +}
 +
 +int FieldState::getVerticalBorders() const
 +{
 +	return borders.getTop() + borders.getBottom();
 +}
 +
 +static inline int beetween(int val, int minVal, int maxVal)
 +{
 +	return max(minVal, min(maxVal, val));
 +}
 +
 +static inline void intersection(RECT &main, const RECT &other)
 +{
 +	main.left = beetween(main.left, other.left, other.right);
 +	main.right = beetween(main.right, other.left, other.right);
 +	main.top = beetween(main.top, other.top, other.bottom);
 +	main.bottom = beetween(main.bottom, other.top, other.bottom);
 +}
 +
 +RECT FieldState::getRect(bool raw) const
 +{
 +	RECT ret = {0};
 +
 +	if (!visible)
 +		return ret;
 +
 +	RECT inside = dialog->getInsideRect();
 +
 +	ret.left = getLeft() + inside.left;
 +	ret.right = getRight() + inside.left;
 +	ret.top = getTop() + inside.top;
 +	ret.bottom = getBottom() + inside.top;
 +
 +	if (!raw)
 +		intersection(ret, inside);
 +
 +	return ret;
 +}
 +
 +RECT FieldState::getInsideRect(bool raw) const
 +{
 +	RECT ret = {0};
 +
 +	if (!visible)
 +		return ret;
 +
 +	RECT inside = dialog->getInsideRect();
 +
 +	ret.left = getLeft() + borders.getLeft() + inside.left;
 +	ret.right = getRight() - borders.getRight() + inside.left;
 +	ret.top = getTop() + borders.getTop() + inside.top;
 +	ret.bottom = getBottom() - borders.getBottom() + inside.top;
 +
 +	if (!raw)
 +		intersection(ret, inside);
 +
 +	return ret;
 +}
 +
 +HORIZONTAL_ALIGN FieldState::getHAlign() const
 +{
 +	return halign;
 +}
 +
 +void FieldState::setHAlign(HORIZONTAL_ALIGN halign)
 +{
 +	this->halign = halign;
 +}
 +
 +VERTICAL_ALIGN FieldState::getVAlign() const
 +{
 +	return valign;
 +}
 +
 +void FieldState::setVAlign(VERTICAL_ALIGN valign)
 +{
 +	this->valign = valign;
 +}
 diff --git a/plugins/Skins/SkinLib/FieldState.h b/plugins/Skins/SkinLib/FieldState.h new file mode 100644 index 0000000000..d7c552105f --- /dev/null +++ b/plugins/Skins/SkinLib/FieldState.h @@ -0,0 +1,108 @@ +#ifndef __FIELD_STATE_H__
 +# define __FIELD_STATE_H__
 +
 +#include "Field.h"
 +#include "BorderState.h"
 +
 +class DialogState;
 +
 +enum HORIZONTAL_ALIGN
 +{
 +	HORIZONTAL_ALIGN_LEFT = 1,
 +	HORIZONTAL_ALIGN_CENTER,
 +	HORIZONTAL_ALIGN_RIGHT
 +};
 +
 +enum VERTICAL_ALIGN
 +{
 +	VERTICAL_ALIGN_TOP = 1,
 +	VERTICAL_ALIGN_CENTER,
 +	VERTICAL_ALIGN_BOTTOM
 +};
 +
 +
 +class FieldState
 +{
 +public:
 +	virtual ~FieldState();
 +
 +	virtual Field * getField() const;
 +	virtual DialogState * getDialog() const;
 +
 +	virtual Size getPreferedSize() const = 0;
 +
 +	// Used inside script
 +
 +	virtual int getX() const;
 +	virtual void setX(int x);
 +
 +	virtual int getY() const;
 +	virtual void setY(int y);
 +
 +	virtual int getWidth() const;
 +	virtual void setWidth(int width);
 +
 +	virtual int getHeight() const;
 +	virtual void setHeight(int height);
 +
 +	virtual int getLeft() const;
 +	virtual void setLeft(int left);
 +
 +	virtual int getTop() const;
 +	virtual void setTop(int top);
 +
 +	virtual int getRight() const;
 +	virtual void setRight(int right);
 +
 +	virtual int getBottom() const;
 +	virtual void setBottom(int bottom);
 +
 +	virtual bool isVisible() const;
 +	virtual void setVisible(bool visible);
 +
 +	virtual bool isEnabled() const;
 +
 +	virtual const TCHAR * getToolTip() const;
 +	virtual void setToolTip(const TCHAR *tooltip);
 +
 +	virtual BorderState * getBorders();
 +	virtual const BorderState * getBorders() const;
 +
 +	virtual HORIZONTAL_ALIGN getHAlign() const;
 +	virtual void setHAlign(HORIZONTAL_ALIGN halign);
 +
 +	virtual VERTICAL_ALIGN getVAlign() const;
 +	virtual void setVAlign(VERTICAL_ALIGN valign);
 +
 +	virtual bool isEmpty() const = 0;
 +
 +	// Results
 +
 +	virtual RECT getInsideRect(bool raw = false) const;
 +	virtual RECT getRect(bool raw = false) const;
 +
 +protected:
 +	FieldState(DialogState *dialog, Field *field);
 +
 +	Field *field;
 +	DialogState *dialog;
 +
 +	Size size;
 +	Position pos;
 +	int usingX;
 +	int usingY;
 +	bool visible;
 +	BorderState borders;
 +	bool tooltipSet;
 +	std::tstring tooltip;
 +	HORIZONTAL_ALIGN halign;
 +	VERTICAL_ALIGN valign;
 +
 +	int getHorizontalBorders() const;
 +	int getVerticalBorders() const;
 +
 +	friend class Field;
 +};
 +
 +
 +#endif  // __FIELD_STATE_H__
 diff --git a/plugins/Skins/SkinLib/FieldState.rec b/plugins/Skins/SkinLib/FieldState.rec new file mode 100644 index 0000000000..7b9ffd890d --- /dev/null +++ b/plugins/Skins/SkinLib/FieldState.rec @@ -0,0 +1,89 @@ +struct DialogState
 +{
 +	Int32 width;
 +	Int32 height;
 +	const Int32 x;
 +	const Int32 y;
 +	const Int32 left;
 +	const Int32 top;
 +	const Int32 right;
 +	const Int32 bottom;
 +	BorderState borders [setter: if (!value.IsEmpty() && value->IsInt32())\n\ttmp->getBorders()->setAll(value->Int32Value()); ];
 +};
 +
 +struct FieldState
 +{
 +	Int32 x;
 +	Int32 y;
 +	Int32 width;
 +	Int32 height;
 +	Int32 left;
 +	Int32 top;
 +	Int32 right;
 +	Int32 bottom;
 +	Boolean visible;
 +	const Boolean enabled;
 +	Char toolTip[128];
 +	Int32 hAlign | HORIZONTAL_ALIGN_LEFT "LEFT" | HORIZONTAL_ALIGN_CENTER "CENTER" | HORIZONTAL_ALIGN_RIGHT "RIGHT";
 +	Int32 vAlign | VERTICAL_ALIGN_TOP "TOP" | VERTICAL_ALIGN_CENTER "CENTER" | VERTICAL_ALIGN_BOTTOM "BOTTOM";
 +	BorderState borders [setter: if (!value.IsEmpty() && value->IsInt32())\n\ttmp->getBorders()->setAll(value->Int32Value()); ];
 +};
 +
 +struct ControlFieldState : FieldState
 +{
 +	Char text[1024];
 +	FontState font;
 +};
 +
 +struct LabelFieldState : ControlFieldState
 +{
 +};
 +
 +struct ButtonFieldState : ControlFieldState
 +{
 +};
 +
 +struct EditFieldState : ControlFieldState
 +{
 +};
 +
 +struct IconFieldState : FieldState
 +{
 +};
 +
 +struct ImageFieldState : FieldState
 +{
 +};
 +
 +struct TextFieldState : FieldState
 +{
 +	Char text[1024];
 +	FontState font;
 +};
 +
 +struct FontState
 +{
 +	Char face[32];
 +	Int32 size;
 +	Boolean italic;
 +	Boolean bold;
 +	Boolean underline;
 +	Boolean strikeOut;
 +	Int32 color;
 +};
 +
 +struct BorderState
 +{
 +	Int32 left;
 +	Int32 right;
 +	Int32 top;
 +	Int32 bottom;
 +};
 +
 +struct SkinOption
 +{
 +	Char description[128];
 +	Int32 min;
 +	Int32 max;
 +	Int32 type | CHECKBOX | NUMBER | TEXT;
 +};
 diff --git a/plugins/Skins/SkinLib/FieldState_v8_wrapper.cpp b/plugins/Skins/SkinLib/FieldState_v8_wrapper.cpp new file mode 100644 index 0000000000..937ad69a58 --- /dev/null +++ b/plugins/Skins/SkinLib/FieldState_v8_wrapper.cpp @@ -0,0 +1,539 @@ +#include "globals.h"
 +#include "FieldState_v8_wrapper.h"
 +#include <v8.h>
 +#include "FieldState.h"
 +#include <utf8_helpers.h>
 +
 +using namespace v8;
 +
 +
 +#ifdef UNICODE
 +# define V8_TCHAR uint16_t
 +#else
 +# define V8_TCHAR char
 +#endif
 +
 +
 +static Handle<Value> Get_FieldState_x(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getX()) );
 +}
 +
 +static void Set_FieldState_x(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setX(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_FieldState_y(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getY()) );
 +}
 +
 +static void Set_FieldState_y(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setY(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_FieldState_width(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getWidth()) );
 +}
 +
 +static void Set_FieldState_width(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setWidth(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_FieldState_height(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getHeight()) );
 +}
 +
 +static void Set_FieldState_height(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setHeight(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_FieldState_left(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getLeft()) );
 +}
 +
 +static void Set_FieldState_left(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setLeft(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_FieldState_top(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getTop()) );
 +}
 +
 +static void Set_FieldState_top(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setTop(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_FieldState_right(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getRight()) );
 +}
 +
 +static void Set_FieldState_right(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setRight(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_FieldState_bottom(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getBottom()) );
 +}
 +
 +static void Set_FieldState_bottom(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setBottom(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_FieldState_visible(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Boolean::New(tmp->isVisible()) );
 +}
 +
 +static void Set_FieldState_visible(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsBoolean())
 +		tmp->setVisible(value->BooleanValue());
 +}
 +
 +
 +static Handle<Value> Get_FieldState_enabled(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Boolean::New(tmp->isEnabled()) );
 +}
 +
 +
 +static Handle<Value> Get_FieldState_toolTip(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( String::New((const V8_TCHAR *) tmp->getToolTip()) );
 +}
 +
 +static void Set_FieldState_toolTip(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsString())
 +	{
 +		String::Utf8Value utf8_value(value);
 +		tmp->setToolTip(Utf8ToTchar(*utf8_value));
 +	}
 +}
 +
 +
 +static Handle<Value> Get_FieldState_hAlign(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	switch(tmp->getHAlign())
 +	{
 +		case HORIZONTAL_ALIGN_LEFT: return scope.Close( String::New((const V8_TCHAR *) _T("LEFT")) );
 +		case HORIZONTAL_ALIGN_CENTER: return scope.Close( String::New((const V8_TCHAR *) _T("CENTER")) );
 +		case HORIZONTAL_ALIGN_RIGHT: return scope.Close( String::New((const V8_TCHAR *) _T("RIGHT")) );
 +	}
 +	return scope.Close( Undefined() );
 +}
 +
 +static void Set_FieldState_hAlign(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsString())
 +	{
 +		String::Utf8Value utf8_value(value);
 +		Utf8ToTchar tval(*utf8_value);
 +		if ( lstrcmpi(_T("HORIZONTAL_ALIGN_LEFT"), tval) == 0 )
 +			tmp->setHAlign(HORIZONTAL_ALIGN_LEFT);
 +		else if ( lstrcmpi(_T("LEFT"), tval) == 0 )
 +			tmp->setHAlign(HORIZONTAL_ALIGN_LEFT);
 +		else if ( lstrcmpi(_T("HORIZONTAL_ALIGN_CENTER"), tval) == 0 )
 +			tmp->setHAlign(HORIZONTAL_ALIGN_CENTER);
 +		else if ( lstrcmpi(_T("CENTER"), tval) == 0 )
 +			tmp->setHAlign(HORIZONTAL_ALIGN_CENTER);
 +		else if ( lstrcmpi(_T("HORIZONTAL_ALIGN_RIGHT"), tval) == 0 )
 +			tmp->setHAlign(HORIZONTAL_ALIGN_RIGHT);
 +		else if ( lstrcmpi(_T("RIGHT"), tval) == 0 )
 +			tmp->setHAlign(HORIZONTAL_ALIGN_RIGHT);
 +	}
 +}
 +
 +
 +static Handle<Value> Get_FieldState_vAlign(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	switch(tmp->getVAlign())
 +	{
 +		case VERTICAL_ALIGN_TOP: return scope.Close( String::New((const V8_TCHAR *) _T("TOP")) );
 +		case VERTICAL_ALIGN_CENTER: return scope.Close( String::New((const V8_TCHAR *) _T("CENTER")) );
 +		case VERTICAL_ALIGN_BOTTOM: return scope.Close( String::New((const V8_TCHAR *) _T("BOTTOM")) );
 +	}
 +	return scope.Close( Undefined() );
 +}
 +
 +static void Set_FieldState_vAlign(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsString())
 +	{
 +		String::Utf8Value utf8_value(value);
 +		Utf8ToTchar tval(*utf8_value);
 +		if ( lstrcmpi(_T("VERTICAL_ALIGN_TOP"), tval) == 0 )
 +			tmp->setVAlign(VERTICAL_ALIGN_TOP);
 +		else if ( lstrcmpi(_T("TOP"), tval) == 0 )
 +			tmp->setVAlign(VERTICAL_ALIGN_TOP);
 +		else if ( lstrcmpi(_T("VERTICAL_ALIGN_CENTER"), tval) == 0 )
 +			tmp->setVAlign(VERTICAL_ALIGN_CENTER);
 +		else if ( lstrcmpi(_T("CENTER"), tval) == 0 )
 +			tmp->setVAlign(VERTICAL_ALIGN_CENTER);
 +		else if ( lstrcmpi(_T("VERTICAL_ALIGN_BOTTOM"), tval) == 0 )
 +			tmp->setVAlign(VERTICAL_ALIGN_BOTTOM);
 +		else if ( lstrcmpi(_T("BOTTOM"), tval) == 0 )
 +			tmp->setVAlign(VERTICAL_ALIGN_BOTTOM);
 +	}
 +}
 +
 +
 +static Handle<Value> Get_FieldState_borders(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +	
 +	return scope.Close( self->Get(String::New("bordersRaw")) );
 +}
 +
 +static void Set_FieldState_borders(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FieldState *tmp = (FieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsInt32())
 +		tmp->getBorders()->setAll(value->Int32Value()); 
 +}
 +
 +
 +void AddFieldStateAcessors(Handle<ObjectTemplate> &templ)
 +{
 +	HandleScope scope;
 +	
 +	templ->SetAccessor(String::New("x"), Get_FieldState_x, Set_FieldState_x);
 +	templ->SetAccessor(String::New("y"), Get_FieldState_y, Set_FieldState_y);
 +	templ->SetAccessor(String::New("width"), Get_FieldState_width, Set_FieldState_width);
 +	templ->SetAccessor(String::New("height"), Get_FieldState_height, Set_FieldState_height);
 +	templ->SetAccessor(String::New("left"), Get_FieldState_left, Set_FieldState_left);
 +	templ->SetAccessor(String::New("top"), Get_FieldState_top, Set_FieldState_top);
 +	templ->SetAccessor(String::New("right"), Get_FieldState_right, Set_FieldState_right);
 +	templ->SetAccessor(String::New("bottom"), Get_FieldState_bottom, Set_FieldState_bottom);
 +	templ->SetAccessor(String::New("visible"), Get_FieldState_visible, Set_FieldState_visible);
 +	templ->SetAccessor(String::New("enabled"), Get_FieldState_enabled, NULL, Handle<Value>(), DEFAULT, ReadOnly);
 +	templ->SetAccessor(String::New("toolTip"), Get_FieldState_toolTip, Set_FieldState_toolTip);
 +	templ->SetAccessor(String::New("hAlign"), Get_FieldState_hAlign, Set_FieldState_hAlign);
 +	templ->SetAccessor(String::New("vAlign"), Get_FieldState_vAlign, Set_FieldState_vAlign);
 +	templ->SetAccessor(String::New("borders"), Get_FieldState_borders, Set_FieldState_borders);
 +}
 diff --git a/plugins/Skins/SkinLib/FieldState_v8_wrapper.h b/plugins/Skins/SkinLib/FieldState_v8_wrapper.h new file mode 100644 index 0000000000..10c2a854b4 --- /dev/null +++ b/plugins/Skins/SkinLib/FieldState_v8_wrapper.h @@ -0,0 +1,10 @@ +#ifndef __FIELD_STATE_V8_WRAPPER_H__
 +# define __FIELD_STATE_V8_WRAPPER_H__
 +
 +#include <v8.h>
 +
 +void AddFieldStateAcessors(v8::Handle<v8::ObjectTemplate> &templ);
 +
 +
 +
 +#endif // __FIELD_STATE_V8_WRAPPER_H__
 diff --git a/plugins/Skins/SkinLib/FontState.cpp b/plugins/Skins/SkinLib/FontState.cpp new file mode 100644 index 0000000000..da9b4153d5 --- /dev/null +++ b/plugins/Skins/SkinLib/FontState.cpp @@ -0,0 +1,186 @@ +#include "globals.h"
 +#include "FontState.h"
 +
 +
 +FontState::FontState(HFONT hFont, COLORREF aColor) : hFont(NULL), externalFont(false), color(aColor)
 +{
 +	setHFONT(hFont);
 +}
 +
 +FontState::~FontState()
 +{
 +	releaseHFONT();
 +}
 +
 +void FontState::rebuildHFONT()
 +{
 +	releaseHFONT();
 +	buildHFONT();
 +}
 +
 +void FontState::buildAttribs()
 +{
 +	LOGFONT lf = {0};
 +	if (hFont == NULL || GetObject(hFont, sizeof(lf), &lf) == 0)
 +	{
 +		face = _T("Tahoma");
 +		size = 9;
 +		italic = false;
 +		bold = false;
 +		underline = false;
 +		strikeout = false;
 +
 +		rebuildHFONT();
 +
 +		return;
 +	}
 +
 +	face = lf.lfFaceName;
 +	italic = (lf.lfItalic != 0);
 +	bold = (lf.lfWeight > FW_NORMAL);
 +	underline = (lf.lfUnderline != 0);
 +	strikeout = (lf.lfStrikeOut != 0);
 +
 +	HDC hdc = GetDC(NULL);
 +	size = -MulDiv(lf.lfHeight, 72, GetDeviceCaps(hdc, LOGPIXELSY));
 +	ReleaseDC(NULL, hdc);
 +}
 +
 +void FontState::buildHFONT()
 +{
 +	if (hFont != NULL)
 +		return;
 +
 +	LOGFONT lf;
 +	
 +	_tcscpy(lf.lfFaceName, getFace());
 +
 +	lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
 +	lf.lfWeight = isBold() ? FW_BOLD : FW_NORMAL;
 +	lf.lfItalic = isItalic() ? 1 : 0;
 +	lf.lfUnderline = isUnderline() ? 1 : 0;
 +	lf.lfStrikeOut = isStrikeOut() ? 1 : 0;
 +	lf.lfCharSet = DEFAULT_CHARSET;
 +	lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
 +	lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
 +	lf.lfQuality = DEFAULT_QUALITY;
 +	lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
 +
 +	HDC hdc = GetDC(NULL);
 +	lf.lfHeight = -MulDiv(getSize(), GetDeviceCaps(hdc, LOGPIXELSY), 72);
 +	ReleaseDC(NULL, hdc);
 +
 +	hFont = CreateFontIndirect(&lf);
 +	externalFont = false;
 +}
 +
 +void FontState::releaseHFONT()
 +{
 +	if (hFont == NULL)
 +		return;
 +
 +	if (!externalFont)
 +		DeleteObject(hFont);
 +
 +	hFont = NULL;
 +}
 +
 +
 +HFONT FontState::getHFONT() const
 +{
 +	return hFont;
 +}
 +
 +
 +HFONT FontState::createHFONT() const
 +{
 +	LOGFONT lf;
 +	if (hFont == NULL || GetObject(hFont, sizeof(lf), &lf) == 0)
 +		return NULL;
 +	else
 +		return CreateFontIndirect(&lf);
 +}
 +
 +void FontState::setHFONT(HFONT hFont)
 +{
 +	releaseHFONT();
 +	this->hFont = hFont;
 +	externalFont = true;
 +	buildAttribs();
 +}
 +
 +const TCHAR * FontState::getFace() const
 +{
 +	return face.c_str();
 +}
 +
 +void FontState::setFace(const TCHAR * face)
 +{
 +	this->face = face;
 +	rebuildHFONT();
 +}
 +
 +int FontState::getSize() const
 +{
 +	return size;
 +}
 +
 +void FontState::setSize(int size)
 +{
 +	this->size = size;
 +	rebuildHFONT();
 +}
 +
 +COLORREF FontState::getColor() const
 +{
 +	return color;
 +}
 +
 +void FontState::setColor(COLORREF color)
 +{
 +	this->color = color;
 +}
 +
 +bool FontState::isItalic() const
 +{
 +	return italic;
 +}
 +
 +void FontState::setItalic(bool italic)
 +{
 +	this->italic = italic;
 +	rebuildHFONT();
 +}
 +
 +bool FontState::isBold() const
 +{
 +	return bold;
 +}
 +
 +void FontState::setBold(bool bold)
 +{
 +	this->bold = bold;
 +	rebuildHFONT();
 +}
 +
 +bool FontState::isUnderline() const
 +{
 +	return underline;
 +}
 +
 +void FontState::setUnderline(bool underline)
 +{
 +	this->underline = underline;
 +	rebuildHFONT();
 +}
 +
 +bool FontState::isStrikeOut() const
 +{
 +	return strikeout;
 +}
 +
 +void FontState::setStrikeOut(bool strikeout)
 +{
 +	this->strikeout = strikeout;
 +	rebuildHFONT();
 +}
 diff --git a/plugins/Skins/SkinLib/FontState.h b/plugins/Skins/SkinLib/FontState.h new file mode 100644 index 0000000000..de32bcdfb3 --- /dev/null +++ b/plugins/Skins/SkinLib/FontState.h @@ -0,0 +1,57 @@ +#ifndef __FONT_STATE_H__
 +# define __FONT_STATE_H__
 +
 +#include "Field.h"
 +
 +
 +class FontState
 +{
 +public:
 +	FontState(HFONT hFont, COLORREF aColor);
 +	~FontState();
 +
 +	HFONT getHFONT() const;
 +	void setHFONT(HFONT hFont);
 +	HFONT createHFONT() const; /// Return a copy of the internal HFONT. The caller must free it
 +
 +	const TCHAR * getFace() const;
 +	void setFace(const TCHAR * face);
 +
 +	int getSize() const;
 +	void setSize(int size);
 +
 +	COLORREF getColor() const;
 +	void setColor(COLORREF color);
 +
 +	bool isItalic() const;
 +	void setItalic(bool italic);
 +
 +	bool isBold() const;
 +	void setBold(bool bold);
 +
 +	bool isUnderline() const;
 +	void setUnderline(bool underline);
 +
 +	bool isStrikeOut() const;
 +	void setStrikeOut(bool strikeout);
 +
 +private:
 +	COLORREF color;
 +	HFONT hFont;
 +	bool externalFont;
 +	std::tstring face;
 +	int size;
 +	bool italic;
 +	bool bold;
 +	bool underline;
 +	bool strikeout;
 +
 +	void rebuildHFONT();
 +	void buildHFONT();
 +	void releaseHFONT();
 +	void buildAttribs();
 +};
 +
 +
 +
 +#endif // __FONT_STATE_H__
 diff --git a/plugins/Skins/SkinLib/FontState_v8_wrapper.cpp b/plugins/Skins/SkinLib/FontState_v8_wrapper.cpp new file mode 100644 index 0000000000..5226736b24 --- /dev/null +++ b/plugins/Skins/SkinLib/FontState_v8_wrapper.cpp @@ -0,0 +1,269 @@ +#include "globals.h"
 +#include "FontState_v8_wrapper.h"
 +#include <v8.h>
 +#include "FontState.h"
 +#include <utf8_helpers.h>
 +
 +using namespace v8;
 +
 +
 +#ifdef UNICODE
 +# define V8_TCHAR uint16_t
 +#else
 +# define V8_TCHAR char
 +#endif
 +
 +
 +static Handle<Value> Get_FontState_face(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FontState *tmp = (FontState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( String::New((const V8_TCHAR *) tmp->getFace()) );
 +}
 +
 +static void Set_FontState_face(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FontState *tmp = (FontState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsString())
 +	{
 +		String::Utf8Value utf8_value(value);
 +		tmp->setFace(Utf8ToTchar(*utf8_value));
 +	}
 +}
 +
 +
 +static Handle<Value> Get_FontState_size(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FontState *tmp = (FontState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getSize()) );
 +}
 +
 +static void Set_FontState_size(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FontState *tmp = (FontState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setSize(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_FontState_italic(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FontState *tmp = (FontState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Boolean::New(tmp->isItalic()) );
 +}
 +
 +static void Set_FontState_italic(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FontState *tmp = (FontState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsBoolean())
 +		tmp->setItalic(value->BooleanValue());
 +}
 +
 +
 +static Handle<Value> Get_FontState_bold(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FontState *tmp = (FontState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Boolean::New(tmp->isBold()) );
 +}
 +
 +static void Set_FontState_bold(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FontState *tmp = (FontState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsBoolean())
 +		tmp->setBold(value->BooleanValue());
 +}
 +
 +
 +static Handle<Value> Get_FontState_underline(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FontState *tmp = (FontState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Boolean::New(tmp->isUnderline()) );
 +}
 +
 +static void Set_FontState_underline(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FontState *tmp = (FontState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsBoolean())
 +		tmp->setUnderline(value->BooleanValue());
 +}
 +
 +
 +static Handle<Value> Get_FontState_strikeOut(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FontState *tmp = (FontState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Boolean::New(tmp->isStrikeOut()) );
 +}
 +
 +static void Set_FontState_strikeOut(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FontState *tmp = (FontState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsBoolean())
 +		tmp->setStrikeOut(value->BooleanValue());
 +}
 +
 +
 +static Handle<Value> Get_FontState_color(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	FontState *tmp = (FontState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getColor()) );
 +}
 +
 +static void Set_FontState_color(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	FontState *tmp = (FontState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setColor(value->Int32Value());
 +}
 +
 +
 +void AddFontStateAcessors(Handle<ObjectTemplate> &templ)
 +{
 +	HandleScope scope;
 +	
 +	templ->SetAccessor(String::New("face"), Get_FontState_face, Set_FontState_face);
 +	templ->SetAccessor(String::New("size"), Get_FontState_size, Set_FontState_size);
 +	templ->SetAccessor(String::New("italic"), Get_FontState_italic, Set_FontState_italic);
 +	templ->SetAccessor(String::New("bold"), Get_FontState_bold, Set_FontState_bold);
 +	templ->SetAccessor(String::New("underline"), Get_FontState_underline, Set_FontState_underline);
 +	templ->SetAccessor(String::New("strikeOut"), Get_FontState_strikeOut, Set_FontState_strikeOut);
 +	templ->SetAccessor(String::New("color"), Get_FontState_color, Set_FontState_color);
 +}
 diff --git a/plugins/Skins/SkinLib/FontState_v8_wrapper.h b/plugins/Skins/SkinLib/FontState_v8_wrapper.h new file mode 100644 index 0000000000..4b0483ffd9 --- /dev/null +++ b/plugins/Skins/SkinLib/FontState_v8_wrapper.h @@ -0,0 +1,10 @@ +#ifndef __FONT_STATE_V8_WRAPPER_H__
 +# define __FONT_STATE_V8_WRAPPER_H__
 +
 +#include <v8.h>
 +
 +void AddFontStateAcessors(v8::Handle<v8::ObjectTemplate> &templ);
 +
 +
 +
 +#endif // __FONT_STATE_V8_WRAPPER_H__
 diff --git a/plugins/Skins/SkinLib/IconField.cpp b/plugins/Skins/SkinLib/IconField.cpp new file mode 100644 index 0000000000..4cf1aaf532 --- /dev/null +++ b/plugins/Skins/SkinLib/IconField.cpp @@ -0,0 +1,38 @@ +#include "globals.h"
 +#include "IconField.h"
 +#include "IconFieldState.h"
 +
 +
 +IconField::IconField(Dialog *dlg, const char *name) 
 +		: Field(dlg, name), hIcon(NULL)
 +{
 +
 +}
 +
 +IconField::~IconField()
 +{
 +}
 +
 +FieldType IconField::getType() const
 +{
 +	return SIMPLE_ICON;
 +}
 +
 +HICON IconField::getIcon() const
 +{
 +	return hIcon;
 +}
 +
 +void IconField::setIcon(HICON hIcon)
 +{
 +	if (this->hIcon == hIcon)
 +		return;
 +
 +	this->hIcon = hIcon;
 +	fireOnChange();
 +}
 +
 +FieldState * IconField::createState(DialogState *dialogState)
 +{
 +	return new IconFieldState(dialogState, this);
 +}
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/IconField.h b/plugins/Skins/SkinLib/IconField.h new file mode 100644 index 0000000000..984b36b984 --- /dev/null +++ b/plugins/Skins/SkinLib/IconField.h @@ -0,0 +1,27 @@ +#ifndef __ICON_FIELD_H__
 +# define __ICON_FIELD_H__
 +
 +#include "Field.h"
 +
 +
 +class IconField : public Field
 +{
 +public:
 +	IconField(Dialog *dlg, const char *name);
 +	virtual ~IconField();
 +
 +	virtual FieldType getType() const;
 +
 +	virtual HICON getIcon() const;
 +	virtual void setIcon(HICON hIcon);
 +
 +	virtual FieldState * createState(DialogState *dialogState);
 +
 +private:
 +	HICON hIcon;
 +
 +};
 +
 +
 +
 +#endif // __ICON_FIELD_H__
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/IconFieldState.cpp b/plugins/Skins/SkinLib/IconFieldState.cpp new file mode 100644 index 0000000000..fad1d67084 --- /dev/null +++ b/plugins/Skins/SkinLib/IconFieldState.cpp @@ -0,0 +1,37 @@ +#include "globals.h"
 +#include "IconFieldState.h"
 +
 +#define ICON_SIZE 16
 +
 +
 +IconFieldState::IconFieldState(DialogState *dialog, IconField *field) 
 +		: FieldState(dialog, field)
 +{
 +}
 +
 +IconFieldState::~IconFieldState()
 +{
 +}
 +
 +IconField * IconFieldState::getField() const
 +{
 +	return (IconField *) FieldState::getField();
 +}
 +
 +Size IconFieldState::getPreferedSize() const
 +{
 +	if (getIcon() == NULL)
 +		return Size(0, 0);
 +
 +	return Size(ICON_SIZE, ICON_SIZE);
 +}
 +
 +HICON IconFieldState::getIcon() const
 +{
 +	return getField()->getIcon();
 +}
 +
 +bool IconFieldState::isEmpty() const
 +{
 +	return getIcon() == NULL;
 +}
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/IconFieldState.h b/plugins/Skins/SkinLib/IconFieldState.h new file mode 100644 index 0000000000..b69e3fe01f --- /dev/null +++ b/plugins/Skins/SkinLib/IconFieldState.h @@ -0,0 +1,28 @@ +#ifndef __ICON_FIELD_STATE_H__
 +# define __ICON_FIELD_STATE_H__
 +
 +#include "IconField.h"
 +#include "FieldState.h"
 +
 +
 +class IconFieldState : public FieldState
 +{
 +public:
 +	virtual ~IconFieldState();
 +
 +	virtual IconField * getField() const;
 +
 +	virtual Size getPreferedSize() const;
 +
 +	virtual HICON getIcon() const;
 +
 +	virtual bool isEmpty() const;
 +
 +private:
 +	IconFieldState(DialogState *dialog, IconField *field);
 +
 +	friend class IconField;
 +};
 +
 +
 +#endif // __ICON_FIELD_STATE_H__
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/IconFieldState_v8_wrapper.cpp b/plugins/Skins/SkinLib/IconFieldState_v8_wrapper.cpp new file mode 100644 index 0000000000..a955653652 --- /dev/null +++ b/plugins/Skins/SkinLib/IconFieldState_v8_wrapper.cpp @@ -0,0 +1,20 @@ +#include "globals.h"
 +#include "IconFieldState_v8_wrapper.h"
 +#include <v8.h>
 +#include "IconFieldState.h"
 +
 +using namespace v8;
 +
 +
 +#ifdef UNICODE
 +# define V8_TCHAR uint16_t
 +#else
 +# define V8_TCHAR char
 +#endif
 +
 +
 +void AddIconFieldStateAcessors(Handle<ObjectTemplate> &templ)
 +{
 +	HandleScope scope;
 +	
 +}
 diff --git a/plugins/Skins/SkinLib/IconFieldState_v8_wrapper.h b/plugins/Skins/SkinLib/IconFieldState_v8_wrapper.h new file mode 100644 index 0000000000..7b63f801bc --- /dev/null +++ b/plugins/Skins/SkinLib/IconFieldState_v8_wrapper.h @@ -0,0 +1,10 @@ +#ifndef __ICON_FIELD_STATE_V8_WRAPPER_H__
 +# define __ICON_FIELD_STATE_V8_WRAPPER_H__
 +
 +#include <v8.h>
 +
 +void AddIconFieldStateAcessors(v8::Handle<v8::ObjectTemplate> &templ);
 +
 +
 +
 +#endif // __ICON_FIELD_STATE_V8_WRAPPER_H__
 diff --git a/plugins/Skins/SkinLib/ImageField.cpp b/plugins/Skins/SkinLib/ImageField.cpp new file mode 100644 index 0000000000..c65cf99a0f --- /dev/null +++ b/plugins/Skins/SkinLib/ImageField.cpp @@ -0,0 +1,38 @@ +#include "globals.h"
 +#include "ImageField.h"
 +#include "ImageFieldState.h"
 +
 +
 +ImageField::ImageField(Dialog *dlg, const char *name) 
 +		: Field(dlg, name), hBmp(NULL)
 +{
 +
 +}
 +
 +ImageField::~ImageField()
 +{
 +}
 +
 +FieldType ImageField::getType() const
 +{
 +	return SIMPLE_IMAGE;
 +}
 +
 +HBITMAP ImageField::getImage() const
 +{
 +	return hBmp;
 +}
 +
 +void ImageField::setImage(HBITMAP hBmp)
 +{
 +	if (this->hBmp == hBmp)
 +		return;
 +
 +	this->hBmp = hBmp;
 +	fireOnChange();
 +}
 +
 +FieldState * ImageField::createState(DialogState *dialogState)
 +{
 +	return new ImageFieldState(dialogState, this);
 +}
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/ImageField.h b/plugins/Skins/SkinLib/ImageField.h new file mode 100644 index 0000000000..e2f08665ca --- /dev/null +++ b/plugins/Skins/SkinLib/ImageField.h @@ -0,0 +1,26 @@ +#ifndef __IMAGE_FIELD_H__
 +# define __IMAGE_FIELD_H__
 +
 +#include "Field.h"
 +
 +class ImageField : public Field
 +{
 +public:
 +	ImageField(Dialog *dlg, const char *name);
 +	virtual ~ImageField();
 +
 +	virtual FieldType getType() const;
 +
 +	virtual HBITMAP getImage() const;
 +	virtual void setImage(HBITMAP hBmp);
 +
 +	virtual FieldState * createState(DialogState *dialogState);
 +
 +private:
 +	HBITMAP hBmp;
 +
 +};
 +
 +
 +
 +#endif // __IMAGE_FIELD_H__
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/ImageFieldState.cpp b/plugins/Skins/SkinLib/ImageFieldState.cpp new file mode 100644 index 0000000000..f74d77e0f3 --- /dev/null +++ b/plugins/Skins/SkinLib/ImageFieldState.cpp @@ -0,0 +1,37 @@ +#include "globals.h"
 +#include "ImageFieldState.h"
 +
 +
 +ImageFieldState::ImageFieldState(DialogState *dialog, ImageField *field) 
 +		: FieldState(dialog, field)
 +{
 +}
 +
 +ImageFieldState::~ImageFieldState()
 +{
 +}
 +
 +ImageField * ImageFieldState::getField() const
 +{
 +	return (ImageField *) FieldState::getField();
 +}
 +
 +Size ImageFieldState::getPreferedSize() const
 +{
 +	HBITMAP hBmp = getImage();
 +	BITMAP bmp;
 +	if (hBmp == NULL || GetObject(hBmp, sizeof(bmp), &bmp) == 0)
 +		return Size(0, 0);
 +
 +	return Size(bmp.bmWidth, bmp.bmHeight);
 +}
 +
 +HBITMAP ImageFieldState::getImage() const
 +{
 +	return getField()->getImage();
 +}
 +
 +bool ImageFieldState::isEmpty() const
 +{
 +	return getImage() == NULL;
 +}
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/ImageFieldState.h b/plugins/Skins/SkinLib/ImageFieldState.h new file mode 100644 index 0000000000..493c4db16d --- /dev/null +++ b/plugins/Skins/SkinLib/ImageFieldState.h @@ -0,0 +1,28 @@ +#ifndef __IMAGE_FIELD_STATE_H__
 +# define __IMAGE_FIELD_STATE_H__
 +
 +#include "ImageField.h"
 +#include "FieldState.h"
 +
 +
 +class ImageFieldState : public FieldState
 +{
 +public:
 +	virtual ~ImageFieldState();
 +
 +	virtual ImageField * getField() const;
 +
 +	virtual Size getPreferedSize() const;
 +
 +	virtual HBITMAP getImage() const;
 +
 +	virtual bool isEmpty() const;
 +
 +private:
 +	ImageFieldState(DialogState *dialog, ImageField *field);
 +
 +	friend class ImageField;
 +};
 +
 +
 +#endif // __IMAGE_FIELD_STATE_H__
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/ImageFieldState_v8_wrapper.cpp b/plugins/Skins/SkinLib/ImageFieldState_v8_wrapper.cpp new file mode 100644 index 0000000000..1e4a9b6a54 --- /dev/null +++ b/plugins/Skins/SkinLib/ImageFieldState_v8_wrapper.cpp @@ -0,0 +1,20 @@ +#include "globals.h"
 +#include "ImageFieldState_v8_wrapper.h"
 +#include <v8.h>
 +#include "ImageFieldState.h"
 +
 +using namespace v8;
 +
 +
 +#ifdef UNICODE
 +# define V8_TCHAR uint16_t
 +#else
 +# define V8_TCHAR char
 +#endif
 +
 +
 +void AddImageFieldStateAcessors(Handle<ObjectTemplate> &templ)
 +{
 +	HandleScope scope;
 +	
 +}
 diff --git a/plugins/Skins/SkinLib/ImageFieldState_v8_wrapper.h b/plugins/Skins/SkinLib/ImageFieldState_v8_wrapper.h new file mode 100644 index 0000000000..ea5f343e03 --- /dev/null +++ b/plugins/Skins/SkinLib/ImageFieldState_v8_wrapper.h @@ -0,0 +1,10 @@ +#ifndef __IMAGE_FIELD_STATE_V8_WRAPPER_H__
 +# define __IMAGE_FIELD_STATE_V8_WRAPPER_H__
 +
 +#include <v8.h>
 +
 +void AddImageFieldStateAcessors(v8::Handle<v8::ObjectTemplate> &templ);
 +
 +
 +
 +#endif // __IMAGE_FIELD_STATE_V8_WRAPPER_H__
 diff --git a/plugins/Skins/SkinLib/LabelField.cpp b/plugins/Skins/SkinLib/LabelField.cpp new file mode 100644 index 0000000000..154ae2fce5 --- /dev/null +++ b/plugins/Skins/SkinLib/LabelField.cpp @@ -0,0 +1,23 @@ +#include "globals.h"
 +#include "LabelField.h"
 +#include "LabelFieldState.h"
 +
 +
 +LabelField::LabelField(Dialog *dlg, const char *name, HWND hwnd) 
 +		: ControlField(dlg, name, hwnd)
 +{
 +}
 +
 +LabelField::~LabelField()
 +{
 +}
 +
 +FieldType LabelField::getType() const
 +{
 +	return CONTROL_LABEL;
 +}
 +
 +FieldState * LabelField::createState(DialogState *dialogState)
 +{
 +	return new LabelFieldState(dialogState, this);
 +}
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/LabelField.h b/plugins/Skins/SkinLib/LabelField.h new file mode 100644 index 0000000000..8c4cb04a03 --- /dev/null +++ b/plugins/Skins/SkinLib/LabelField.h @@ -0,0 +1,20 @@ +#ifndef __LABEL_FIELD_H__
 +# define __LABEL_FIELD_H__
 +
 +#include "ControlField.h"
 +
 +
 +class LabelField : public ControlField
 +{
 +public:
 +	LabelField(Dialog *dlg, const char *name, HWND hwnd);
 +	virtual ~LabelField();
 +
 +	virtual FieldType getType() const;
 +
 +	virtual FieldState * createState(DialogState *dialogState);
 +};
 +
 +
 +
 +#endif // __LABEL_FIELD_H__
 diff --git a/plugins/Skins/SkinLib/LabelFieldState.cpp b/plugins/Skins/SkinLib/LabelFieldState.cpp new file mode 100644 index 0000000000..364611fbf7 --- /dev/null +++ b/plugins/Skins/SkinLib/LabelFieldState.cpp @@ -0,0 +1,35 @@ +#include "globals.h"
 +#include "LabelFieldState.h"
 +
 +
 +LabelFieldState::LabelFieldState(DialogState *dialog, LabelField *field) 
 +		: ControlFieldState(dialog, field)
 +{
 +}
 +
 +LabelFieldState::~LabelFieldState()
 +{
 +}
 +
 +Size LabelFieldState::getPreferedSize() const
 +{
 +	int style = GetWindowLong(getField()->getHWND(), GWL_STYLE);
 +
 +	int format = DT_EXPANDTABS | DT_EDITCONTROL;
 +	if ((style & SS_LEFTNOWORDWRAP) || (style & SS_SIMPLE))
 +		format |= DT_SINGLELINE;
 +	if (style & SS_NOPREFIX)
 +		format |= DT_NOPREFIX;
 +	Size ret = getTextPreferedSize(format);
 +
 +	int border = getField()->getBorderSize();
 +	ret.x += 2 * border;
 +	ret.y += 2 * border;
 +
 +	return ret;
 +}
 +
 +bool LabelFieldState::isEmpty() const
 +{
 +	return lstrlen(getText()) <= 0;
 +}
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/LabelFieldState.h b/plugins/Skins/SkinLib/LabelFieldState.h new file mode 100644 index 0000000000..dbbb3b04d3 --- /dev/null +++ b/plugins/Skins/SkinLib/LabelFieldState.h @@ -0,0 +1,25 @@ +#ifndef __LABEL_FIELD_STATE_H__
 +# define __LABEL_FIELD_STATE_H__
 +
 +#include "ControlFieldState.h"
 +#include "LabelField.h"
 +
 +
 +class LabelFieldState : public ControlFieldState
 +{
 +public:
 +	virtual ~LabelFieldState();
 +
 +	virtual Size getPreferedSize() const;
 +
 +	virtual bool isEmpty() const;
 +
 +private:
 +	LabelFieldState(DialogState *dialog, LabelField *field);
 +
 +	friend class LabelField;
 +};
 +
 +
 +
 +#endif // __LABEL_FIELD_STATE_H__
 diff --git a/plugins/Skins/SkinLib/LabelFieldState_v8_wrapper.cpp b/plugins/Skins/SkinLib/LabelFieldState_v8_wrapper.cpp new file mode 100644 index 0000000000..9105a7d878 --- /dev/null +++ b/plugins/Skins/SkinLib/LabelFieldState_v8_wrapper.cpp @@ -0,0 +1,20 @@ +#include "globals.h"
 +#include "LabelFieldState_v8_wrapper.h"
 +#include <v8.h>
 +#include "LabelFieldState.h"
 +
 +using namespace v8;
 +
 +
 +#ifdef UNICODE
 +# define V8_TCHAR uint16_t
 +#else
 +# define V8_TCHAR char
 +#endif
 +
 +
 +void AddLabelFieldStateAcessors(Handle<ObjectTemplate> &templ)
 +{
 +	HandleScope scope;
 +	
 +}
 diff --git a/plugins/Skins/SkinLib/LabelFieldState_v8_wrapper.h b/plugins/Skins/SkinLib/LabelFieldState_v8_wrapper.h new file mode 100644 index 0000000000..7d40de5bc2 --- /dev/null +++ b/plugins/Skins/SkinLib/LabelFieldState_v8_wrapper.h @@ -0,0 +1,10 @@ +#ifndef __LABEL_FIELD_STATE_V8_WRAPPER_H__
 +# define __LABEL_FIELD_STATE_V8_WRAPPER_H__
 +
 +#include <v8.h>
 +
 +void AddLabelFieldStateAcessors(v8::Handle<v8::ObjectTemplate> &templ);
 +
 +
 +
 +#endif // __LABEL_FIELD_STATE_V8_WRAPPER_H__
 diff --git a/plugins/Skins/SkinLib/Position.cpp b/plugins/Skins/SkinLib/Position.cpp new file mode 100644 index 0000000000..6c68881fce --- /dev/null +++ b/plugins/Skins/SkinLib/Position.cpp @@ -0,0 +1,9 @@ +#include "Position.h"
 +
 +Position::Position() : x(0), y(0)
 +{
 +}
 +
 +Position::Position(int aX, int aY) : x(aX), y(aY)
 +{
 +}
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/Position.h b/plugins/Skins/SkinLib/Position.h new file mode 100644 index 0000000000..ed43a1ece3 --- /dev/null +++ b/plugins/Skins/SkinLib/Position.h @@ -0,0 +1,16 @@ +#ifndef __POSITION_H__
 +# define __POSITION_H__
 +
 +
 +struct Position
 +{
 +	int x;
 +	int y;
 +
 +	Position();
 +	Position(int x, int y);
 +};
 +
 +
 +
 +#endif // __POSITION_H__
 diff --git a/plugins/Skins/SkinLib/Size.cpp b/plugins/Skins/SkinLib/Size.cpp new file mode 100644 index 0000000000..9c2eef5d5d --- /dev/null +++ b/plugins/Skins/SkinLib/Size.cpp @@ -0,0 +1,84 @@ +#include "globals.h"
 +#include "Size.h"
 +
 +Size::Size() : x(0), y(0)
 +{
 +}
 +
 +Size::Size(int aX, int aY) : x(aX), y(aY)
 +{
 +
 +}
 +
 +int Size::resizeTo(int newX, int newY)
 +{
 +	if (newX < 0 && newY < 0)
 +		return -1;
 +	
 +	if (newY < 0) 
 +	{
 +		if (x < 0 || y < 0)
 +			return -2;
 +
 +		y = (int) (y * (newX / (float) x));
 +		x = newX;
 +	}
 +	else if (newX < 0)
 +	{
 +		if (x < 0 || y < 0)
 +			return -2;
 +
 +		x = (int) (x * (newY / (float) y));
 +		y = newY;
 +	}
 +	else
 +	{
 +		x = newX;
 +		y = newY;
 +	}
 +	return 0;
 +}
 +
 +int Size::fitInside(int maxSize)
 +{
 +	if (x < 0 || y < 0)
 +		return -2;
 +	if (x <= maxSize && y <= maxSize)
 +		return 0;
 +
 +	if (x >= y)
 +	{
 +		y = (int) (y * (maxSize / (float) x));
 +		x = maxSize;
 +	}
 +	else
 +	{
 +		x = (int) (x * (maxSize / (float) y));
 +		y = maxSize;
 +	}
 +	return 0;
 +}
 +
 +int Size::scaleTo(int size)
 +{
 +	if (x < 0 || y < 0)
 +		return -2;
 +
 +	if (x >= y)
 +	{
 +		y = (int) (y * (size / (float) x));
 +		x = size;
 +	}
 +	else
 +	{
 +		x = (int) (x * (size / (float) y));
 +		y = size;
 +	}
 +
 +	return 0;
 +}
 +
 +bool Size::operator==(const Size &other) const
 +{
 +	return x == other.x && y == other.y;
 +}
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/Size.h b/plugins/Skins/SkinLib/Size.h new file mode 100644 index 0000000000..8c0a297aee --- /dev/null +++ b/plugins/Skins/SkinLib/Size.h @@ -0,0 +1,27 @@ +#ifndef __SIZE_H__
 +# define __SIZE_H__
 +
 +
 +struct Size 
 +{
 +	int x;
 +	int y;
 +
 +	Size();
 +	Size(int aX, int aY);
 +
 +	/// @return 0 on success
 +	int resizeTo(int x, int y);
 +
 +	/// @return 0 on success
 +	int fitInside(int maxSize);
 +
 +	/// @return 0 on success
 +	int scaleTo(int size);
 +
 +	bool operator==(const Size &other) const;
 +};
 +
 +
 +
 +#endif // __SIZE_H__
 diff --git a/plugins/Skins/SkinLib/SkinOption.h b/plugins/Skins/SkinLib/SkinOption.h new file mode 100644 index 0000000000..7812303327 --- /dev/null +++ b/plugins/Skins/SkinLib/SkinOption.h @@ -0,0 +1 @@ +#include "SkinOptions.h"
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/SkinOption_v8_wrapper.cpp b/plugins/Skins/SkinLib/SkinOption_v8_wrapper.cpp new file mode 100644 index 0000000000..11a401ad2e --- /dev/null +++ b/plugins/Skins/SkinLib/SkinOption_v8_wrapper.cpp @@ -0,0 +1,179 @@ +#include "globals.h"
 +#include "SkinOption_v8_wrapper.h"
 +#include <v8.h>
 +#include "SkinOption.h"
 +#include <utf8_helpers.h>
 +
 +using namespace v8;
 +
 +
 +#ifdef UNICODE
 +# define V8_TCHAR uint16_t
 +#else
 +# define V8_TCHAR char
 +#endif
 +
 +
 +static Handle<Value> Get_SkinOption_description(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	SkinOption *tmp = (SkinOption *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( String::New((const V8_TCHAR *) tmp->getDescription()) );
 +}
 +
 +static void Set_SkinOption_description(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	SkinOption *tmp = (SkinOption *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsString())
 +	{
 +		String::Utf8Value utf8_value(value);
 +		tmp->setDescription(Utf8ToTchar(*utf8_value));
 +	}
 +}
 +
 +
 +static Handle<Value> Get_SkinOption_min(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	SkinOption *tmp = (SkinOption *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getMin()) );
 +}
 +
 +static void Set_SkinOption_min(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	SkinOption *tmp = (SkinOption *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setMin(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_SkinOption_max(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	SkinOption *tmp = (SkinOption *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Int32::New(tmp->getMax()) );
 +}
 +
 +static void Set_SkinOption_max(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	SkinOption *tmp = (SkinOption *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsNumber())
 +		tmp->setMax(value->Int32Value());
 +}
 +
 +
 +static Handle<Value> Get_SkinOption_type(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	SkinOption *tmp = (SkinOption *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	switch(tmp->getType())
 +	{
 +		case CHECKBOX: return scope.Close( String::New((const V8_TCHAR *) _T("CHECKBOX")) );
 +		case NUMBER: return scope.Close( String::New((const V8_TCHAR *) _T("NUMBER")) );
 +		case TEXT: return scope.Close( String::New((const V8_TCHAR *) _T("TEXT")) );
 +	}
 +	return scope.Close( Undefined() );
 +}
 +
 +static void Set_SkinOption_type(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	SkinOption *tmp = (SkinOption *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsString())
 +	{
 +		String::Utf8Value utf8_value(value);
 +		Utf8ToTchar tval(*utf8_value);
 +		if ( lstrcmpi(_T("CHECKBOX"), tval) == 0 )
 +			tmp->setType(CHECKBOX);
 +		else if ( lstrcmpi(_T("NUMBER"), tval) == 0 )
 +			tmp->setType(NUMBER);
 +		else if ( lstrcmpi(_T("TEXT"), tval) == 0 )
 +			tmp->setType(TEXT);
 +	}
 +}
 +
 +
 +void AddSkinOptionAcessors(Handle<ObjectTemplate> &templ)
 +{
 +	HandleScope scope;
 +	
 +	templ->SetAccessor(String::New("description"), Get_SkinOption_description, Set_SkinOption_description);
 +	templ->SetAccessor(String::New("min"), Get_SkinOption_min, Set_SkinOption_min);
 +	templ->SetAccessor(String::New("max"), Get_SkinOption_max, Set_SkinOption_max);
 +	templ->SetAccessor(String::New("type"), Get_SkinOption_type, Set_SkinOption_type);
 +}
 diff --git a/plugins/Skins/SkinLib/SkinOption_v8_wrapper.h b/plugins/Skins/SkinLib/SkinOption_v8_wrapper.h new file mode 100644 index 0000000000..6aa05c2122 --- /dev/null +++ b/plugins/Skins/SkinLib/SkinOption_v8_wrapper.h @@ -0,0 +1,10 @@ +#ifndef __SKIN_OPTION_V8_WRAPPER_H__
 +# define __SKIN_OPTION_V8_WRAPPER_H__
 +
 +#include <v8.h>
 +
 +void AddSkinOptionAcessors(v8::Handle<v8::ObjectTemplate> &templ);
 +
 +
 +
 +#endif // __SKIN_OPTION_V8_WRAPPER_H__
 diff --git a/plugins/Skins/SkinLib/SkinOptions.cpp b/plugins/Skins/SkinLib/SkinOptions.cpp new file mode 100644 index 0000000000..51fb96cbdb --- /dev/null +++ b/plugins/Skins/SkinLib/SkinOptions.cpp @@ -0,0 +1,216 @@ +#include "globals.h"
 +#include "SkinOptions.h"
 +#include <utf8_helpers.h>
 +
 +
 +SkinOption::SkinOption(const char *aName) 
 +		: name(aName), type(CHECKBOX), valueCheckbox(false), valueNumber(0),
 +		  onChangeCallback(NULL), onChangeCallbackParam(NULL),
 +		  minValue(MININT), maxValue(MAXINT)
 +{
 +	description = Utf8ToTchar(aName);
 +}
 +
 +SkinOption::~SkinOption()
 +{
 +}
 +
 +const char * SkinOption::getName() const
 +{
 +	return name.c_str();
 +}
 +
 +SkinOptionType SkinOption::getType() const
 +{
 +	return type;
 +}
 +
 +void SkinOption::setType(SkinOptionType type)
 +{
 +	if (this->type == type)
 +		return;
 +
 +	this->type = type;
 +	fireOnChange();
 +}
 +
 +const TCHAR * SkinOption::getDescription() const
 +{
 +	return description.c_str();
 +}
 +
 +void SkinOption::setDescription(const TCHAR * description)
 +{
 +	if (this->description == description)
 +		return;
 +
 +	this->description = description;
 +	fireOnChange();
 +}
 +
 +int SkinOption::getMax() const
 +{
 +	return maxValue;
 +}
 +
 +void SkinOption::setMax(int max)
 +{
 +	this->maxValue = max;
 +	setValueNumber(valueNumber);
 +}
 +
 +int SkinOption::getMin() const
 +{
 +	return minValue;
 +}
 +
 +void SkinOption::setMin(int min)
 +{
 +	this->minValue = min;
 +	setValueNumber(valueNumber);
 +}
 +
 +bool SkinOption::getValueCheckbox() const
 +{
 +	return valueCheckbox;
 +}
 +
 +void SkinOption::setValueCheckbox(bool value)
 +{
 +	if (valueCheckbox == value)
 +		return;
 +
 +	valueCheckbox = value;
 +	fireOnChange();
 +}
 +
 +int SkinOption::getValueNumber() const
 +{
 +	return max(minValue, min(maxValue, valueNumber));
 +}
 +
 +void SkinOption::setValueNumber(int value)
 +{
 +	value = max(minValue, min(maxValue, value));
 +
 +	if (value == valueNumber)
 +		return;
 +
 +	valueNumber = value;
 +	fireOnChange();
 +}
 +
 +const TCHAR * SkinOption::getValueText() const
 +{
 +	return valueText.c_str();
 +}
 +
 +void SkinOption::setValueText(const TCHAR * value)
 +{
 +	if (valueText == value)
 +		return;
 +
 +	valueText = value;
 +	fireOnChange();
 +}
 +
 +void SkinOption::setOnChangeCallback(SkinOptionCallback cb, void *param /*= NULL*/)
 +{
 +	onChangeCallback = cb;
 +	onChangeCallbackParam = param;
 +}
 +
 +void SkinOption::fireOnChange()
 +{
 +	if (onChangeCallback != NULL)
 +		onChangeCallback(onChangeCallbackParam, this);
 +}
 +
 +
 +
 +SkinOptions::SkinOptions()
 +		: onAddRemoveCallback(NULL), onAddRemoveCallbackParam(NULL),
 +		  onChangeCallback(NULL), onChangeCallbackParam(NULL)
 +{
 +}
 +
 +SkinOptions::~SkinOptions()
 +{
 +	for(unsigned int i = 0; i < options.size(); i++)
 +		delete options[i];
 +	options.clear();
 +}
 +
 +bool SkinOptions::addOption(SkinOption *opt)
 +{
 +	_ASSERT(opt != NULL);
 +	_ASSERT(opt->getName() != NULL);
 +
 +	if (getOption(opt->getName()) != NULL)
 +		return false;
 +
 +	opt->setOnChangeCallback(onChangeCallback, onChangeCallbackParam);
 +	options.push_back(opt);
 +
 +	fireOnAddRemove(opt);
 +	return true;
 +}
 +
 +SkinOption * SkinOptions::getOption(const char *name) const
 +{
 +	_ASSERT(name != NULL);
 +
 +	for(unsigned int i = 0; i < options.size(); i++)
 +	{
 +		SkinOption *opt = options[i];
 +		if (strcmp(opt->getName(), name) == 0)
 +			return opt;
 +	}
 +	return NULL;
 +}
 +
 +SkinOption * SkinOptions::getOption(unsigned int pos) const
 +{
 +	if (pos >= options.size())
 +		return NULL;
 +	return options[pos];
 +}
 +
 +unsigned int SkinOptions::getNumOptions() const
 +{
 +	return options.size();
 +}
 +
 +void SkinOptions::clearOptions()
 +{
 +	if (options.size() <= 0)
 +		return;
 +
 +	for(unsigned int i = 0; i < options.size(); i++)
 +	{
 +		fireOnAddRemove(options[i]);
 +		delete options[i];
 +	}
 +	options.clear();
 +}
 +
 +void SkinOptions::setOnOptionAddRemoveCallback(SkinOptionCallback cb, void *param /*= NULL*/)
 +{
 +	onAddRemoveCallback = cb;
 +	onAddRemoveCallbackParam = param;
 +}
 +
 +void SkinOptions::setOnOptionChangeCallback(SkinOptionCallback cb, void *param /*= NULL*/)
 +{
 +	onChangeCallback = cb;
 +	onChangeCallbackParam = param;
 +
 +	for(unsigned int i = 0; i < options.size(); i++)
 +		options[i]->setOnChangeCallback(cb, param);
 +}
 +
 +void SkinOptions::fireOnAddRemove(SkinOption *opt)
 +{
 +	if (onAddRemoveCallback != NULL)
 +		onAddRemoveCallback(onAddRemoveCallbackParam, opt);
 +}
 diff --git a/plugins/Skins/SkinLib/SkinOptions.h b/plugins/Skins/SkinLib/SkinOptions.h new file mode 100644 index 0000000000..41d238a5a1 --- /dev/null +++ b/plugins/Skins/SkinLib/SkinOptions.h @@ -0,0 +1,98 @@ +#ifndef __SKINNED_DIALOG_OPTIONS_H__
 +# define __SKINNED_DIALOG_OPTIONS_H__
 +
 +#include <windows.h>
 +#include "tstring.h"
 +#include <vector>
 +
 +
 +enum SkinOptionType
 +{
 +	CHECKBOX,
 +	NUMBER,
 +	TEXT
 +};
 +
 +class SkinOption;
 +
 +typedef void (*SkinOptionCallback)(void *param, const SkinOption *opt);
 +
 +
 +class SkinOption
 +{
 +public:
 +	SkinOption(const char *name);
 +	~SkinOption();
 +
 +	const char * getName() const;
 +
 +	SkinOptionType getType() const;
 +	void setType(SkinOptionType type);
 +
 +	const TCHAR * getDescription() const;
 +	void setDescription(const TCHAR * description);
 +
 +	int getMax() const;
 +	void setMax(int max);
 +
 +	int getMin() const;
 +	void setMin(int min);
 +
 +	bool getValueCheckbox() const;
 +	void setValueCheckbox(bool value);
 +
 +	int getValueNumber() const;
 +	void setValueNumber(int value);
 +
 +	const TCHAR * getValueText() const;
 +	void setValueText(const TCHAR * value);
 +
 +	void setOnChangeCallback(SkinOptionCallback cb, void *param = NULL);
 +
 +private:
 +	std::string name;
 +	SkinOptionType type;
 +	std::tstring description;
 +	bool valueCheckbox;
 +	int valueNumber;
 +	int minValue;
 +	int maxValue;
 +	std::tstring valueText;
 +
 +	SkinOptionCallback onChangeCallback;
 +	void * onChangeCallbackParam;
 +
 +	void fireOnChange();
 +};
 +
 +
 +class SkinOptions
 +{
 +public:
 +	SkinOptions();
 +	~SkinOptions();
 +
 +	bool addOption(SkinOption *opt);
 +	SkinOption * getOption(const char *name) const;
 +	SkinOption * getOption(unsigned int pos) const;
 +	unsigned int getNumOptions() const;
 +	void clearOptions();
 +
 +	void setOnOptionAddRemoveCallback(SkinOptionCallback cb, void *param = NULL);
 +	void setOnOptionChangeCallback(SkinOptionCallback cb, void *param = NULL);
 +
 +private:
 +	std::vector<SkinOption *> options;
 +
 +	SkinOptionCallback onAddRemoveCallback;
 +	void * onAddRemoveCallbackParam;
 +
 +	SkinOptionCallback onChangeCallback;
 +	void * onChangeCallbackParam;
 +
 +	void fireOnAddRemove(SkinOption *opt);
 +};
 +
 +
 +
 +#endif // __SKINNED_DIALOG_OPTIONS_H__
 diff --git a/plugins/Skins/SkinLib/SkinnedDialog.cpp b/plugins/Skins/SkinLib/SkinnedDialog.cpp new file mode 100644 index 0000000000..917193ad94 --- /dev/null +++ b/plugins/Skins/SkinLib/SkinnedDialog.cpp @@ -0,0 +1,235 @@ +#include "globals.h"
 +#include "SkinnedDialog.h"
 +
 +#include <sys/stat.h>
 +#include "V8Script.h"
 +#include <utf8_helpers.h>
 +#include "SkinOptions.h"
 +
 +
 +SkinnedDialog::SkinnedDialog(const char *name) 
 +		: Dialog(name), fileChangedTime(0), 
 +		  script(NULL), state(NULL), opts(NULL), defaultState(NULL),
 +		  errorCallback(NULL), errorCallbackParam(NULL),
 +		  traceCallback(NULL), traceCallbackParam(NULL)
 +{
 +	V8Script::initializeEngine();
 +}
 +
 +SkinnedDialog::~SkinnedDialog()
 +{
 +	releaseState();
 +	releaseCompiledScript();
 +}
 +
 +const TCHAR * SkinnedDialog::getFilename() const
 +{
 +	return filename.c_str();
 +}
 +
 +void SkinnedDialog::setFilename(const TCHAR *filename)
 +{
 +	if (this->filename == filename)
 +		return;
 +
 +	this->filename = filename;
 +	releaseState();
 +	releaseCompiledScript();
 +}
 +
 +bool SkinnedDialog::addField(Field *field)
 +{
 +	if (Dialog::addField(field))
 +	{
 +		releaseCompiledScript();
 +		releaseState();
 +		field->setOnChangeCallback(SkinnedDialog::staticOnFieldChange, this);
 +		return true;
 +	}
 +	else
 +		return false;
 +}
 +
 +void SkinnedDialog::setSize(const Size &size)
 +{
 +	if (getSize() == size)
 +		return;
 +
 +	Dialog::setSize(size);
 +	releaseState();
 +}
 +
 +int SkinnedDialog::compile()
 +{
 +	if (!fileChanged())
 +		return 1;
 +
 +	releaseCompiledScript();
 +
 +	struct _stat st = {0};
 +	if (_tstat(filename.c_str(), &st) != 0)
 +		return 0;
 +
 +	std::tstring text;
 +	readFile(text);
 +	if (text.size() <= 0)
 +		return 0;
 +
 +	script = new V8Script();
 +	script->setExceptionCallback(errorCallback, errorCallbackParam);
 +
 +	if (!script->compile(text.c_str(), this))
 +	{
 +		releaseCompiledScript();
 +		return 0;
 +	}
 +
 +	std::pair<SkinOptions *,DialogState *> pair = script->configure(this);
 +	opts = pair.first;
 +	defaultState = pair.second;
 +	if (opts == NULL)
 +	{
 +		releaseCompiledScript();
 +		return 0;
 +	}
 +
 +	fileChangedTime = st.st_mtime;
 +
 +	return 2;
 +}
 +
 +DialogState * SkinnedDialog::getState()
 +{	
 +	if (state != NULL && !fileChanged())
 +		return state;
 +
 +	releaseState();
 +
 +	if (filename.size() <= 0)
 +		return NULL;
 +
 +	if (!compile())
 +		return NULL;
 +
 +	state = Dialog::createState();
 +	if (!script->run(state, opts, getInfo()))
 +	{
 +		releaseState();
 +		return NULL;
 +	}
 +
 +	return state;
 +}
 +
 +void SkinnedDialog::releaseCompiledScript()
 +{
 +	delete script;
 +	script = NULL;
 +	fileChangedTime = 0;
 +
 +	delete opts;
 +	opts = NULL;
 +
 +	delete defaultState;
 +	defaultState = NULL;
 +}
 +
 +void SkinnedDialog::releaseState()
 +{
 +	delete state;
 +	state = NULL;
 +}
 +
 +bool SkinnedDialog::fileChanged()
 +{
 +	if (filename.size() <= 0)
 +		return false;
 +
 +	struct _stat st = {0};
 +	if (_tstat(filename.c_str(), &st) != 0)
 +		return false;
 +
 +	return st.st_mtime > fileChangedTime;
 +}
 +
 +void SkinnedDialog::readFile(std::tstring &ret)
 +{
 +	FILE* file = _tfopen(filename.c_str(), _T("rb"));
 +	if (file == NULL) 
 +		return;
 +
 +	fseek(file, 0, SEEK_END);
 +	int size = ftell(file);
 +	rewind(file);
 +
 +	char* chars = new char[size + 1];
 +	chars[size] = '\0';
 +	for (int i = 0; i < size;) 
 +	{
 +		int read = fread(&chars[i], 1, size - i, file);
 +		i += read;
 +	}
 +	fclose(file);
 +
 +	ret = Utf8ToTchar(chars);
 +
 +	delete[] chars;
 +}
 +
 +void SkinnedDialog::onFieldChange(const Field *field)
 +{
 +	releaseState();
 +}
 +
 +
 +void SkinnedDialog::staticOnFieldChange(void *param, const Field *field)
 +{
 +	_ASSERT(param != NULL);
 +	_ASSERT(field != NULL);
 +
 +	SkinnedDialog *skdlg = (SkinnedDialog *) param;
 +	skdlg->onFieldChange(field);
 +}
 +
 +void SkinnedDialog::setErrorCallback(MessageCallback cb, void *param /*= NULL*/)
 +{
 +	errorCallback = cb;
 +	errorCallbackParam = param;
 +}
 +
 +void SkinnedDialog::setTraceCallback(MessageCallback cb, void *param /*= NULL*/)
 +{
 +	traceCallback = cb;
 +	traceCallbackParam = param;
 +}
 +
 +void SkinnedDialog::trace(TCHAR *msg, ...)
 +{
 +	if (traceCallback == NULL)
 +		return;
 +
 +	TCHAR buff[1024];
 +	memset(buff, 0, sizeof(buff));
 +
 +	va_list args;
 +	va_start(args, msg);
 +
 +	_vsntprintf(buff, MAX_REGS(buff) - 1, msg, args);
 +	buff[MAX_REGS(buff) - 1] = 0;
 +
 +	va_end(args);
 +
 +	traceCallback(traceCallbackParam, buff);
 +}
 +
 +SkinOptions * SkinnedDialog::getOpts()
 +{
 +	compile();
 +	return opts;
 +}
 +
 +DialogState * SkinnedDialog::getDefaultState()
 +{
 +	compile();
 +	return defaultState;
 +}
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/SkinnedDialog.h b/plugins/Skins/SkinLib/SkinnedDialog.h new file mode 100644 index 0000000000..1387082f44 --- /dev/null +++ b/plugins/Skins/SkinLib/SkinnedDialog.h @@ -0,0 +1,89 @@ +#ifndef __SKINNED_DIALOG_H__
 +# define __SKINNED_DIALOG_H__
 +
 +#include <windows.h>
 +#include <tchar.h>
 +#include "tstring.h"
 +
 +#include "Dialog.h"
 +#include "ButtonField.h"
 +#include "EditField.h"
 +#include "IconField.h"
 +#include "ImageField.h"
 +#include "LabelField.h"
 +#include "TextField.h"
 +
 +#include "DialogState.h"
 +#include "BorderState.h"
 +#include "ButtonFieldState.h"
 +#include "EditFieldState.h"
 +#include "FontState.h"
 +#include "IconFieldState.h"
 +#include "ImageFieldState.h"
 +#include "LabelFieldState.h"
 +#include "TextFieldState.h"
 +
 +#include "SkinOptions.h"
 +
 +class V8Script;
 +
 +
 +typedef void (*MessageCallback)(void *param, const TCHAR *err);
 +
 +
 +
 +class SkinnedDialog : public Dialog
 +{
 +public:
 +	SkinnedDialog(const char *name);
 +	virtual ~SkinnedDialog();
 +
 +	virtual const TCHAR * getFilename() const;
 +	virtual void setFilename(const TCHAR *filename);
 +
 +	virtual bool addField(Field *field);
 +
 +	virtual void setSize(const Size &size);
 +
 +	/// Return the cached state. Do not free the result. 
 +	/// Each call to this method can potentially create the state, so don't cache it.
 +	virtual DialogState * getState();
 +
 +	virtual void setErrorCallback(MessageCallback cb, void *param = NULL);
 +	virtual void setTraceCallback(MessageCallback cb, void *param = NULL);
 +
 +	virtual SkinOptions * getOpts();
 +	virtual DialogState * getDefaultState();
 +
 +protected:
 +	virtual bool fileChanged();
 +	virtual int compile(); /// @return 0 error, 1 no change, 2 compiled
 +
 +	virtual void trace(TCHAR *msg, ...);
 +
 +	virtual void onFieldChange(const Field *field);
 +
 +private:
 +	std::tstring filename;
 +	__time64_t fileChangedTime;
 +	V8Script *script;
 +	DialogState *state;
 +	SkinOptions *opts;
 +	DialogState *defaultState;
 +
 +	MessageCallback errorCallback;
 +	void *errorCallbackParam;
 +	MessageCallback traceCallback;
 +	void *traceCallbackParam;
 +
 +	void releaseCompiledScript();
 +	void releaseState();
 +	void readFile(std::tstring &ret);
 +
 +	static void staticOnFieldChange(void *param, const Field *field);
 +};
 +
 +
 +
 +
 +#endif // __SKINNED_DIALOG_H__
 diff --git a/plugins/Skins/SkinLib/TextField.cpp b/plugins/Skins/SkinLib/TextField.cpp new file mode 100644 index 0000000000..d3841b98fd --- /dev/null +++ b/plugins/Skins/SkinLib/TextField.cpp @@ -0,0 +1,78 @@ +#include "globals.h"
 +#include "TextField.h"
 +#include "TextFieldState.h"
 +
 +
 +TextField::TextField(Dialog *dlg, const char *name) 
 +		: Field(dlg, name), hFont(NULL), fontColor(RGB(0,0,0))
 +{
 +}
 +
 +
 +TextField::~TextField()
 +{
 +}
 +
 +
 +FieldType TextField::getType() const
 +{
 +	return SIMPLE_TEXT;
 +}
 +
 +
 +void TextField::setText(const TCHAR *text)
 +{
 +	if (this->text == text)
 +		return;
 +
 +	this->text = text;
 +	fireOnChange();
 +}
 +
 +
 +const TCHAR * TextField::getText() const
 +{
 +	return text.c_str();
 +}
 +
 +
 +void TextField::setFont(HFONT hFont)
 +{
 +	if (this->hFont == hFont)
 +		return;
 +
 +	this->hFont = hFont;
 +	fireOnChange();
 +}
 +
 +
 +HFONT TextField::getFont() const
 +{
 +	if (hFont != NULL)
 +		return hFont;
 +	
 +	// The default is the GUI font
 +	return (HFONT) GetStockObject(DEFAULT_GUI_FONT);
 +}
 +
 +
 +COLORREF TextField::getFontColor() const
 +{
 +	return fontColor;
 +}
 +
 +
 +void TextField::setFontColor(COLORREF color)
 +{
 +	if (fontColor == color)
 +		return;
 +
 +	fontColor = color;
 +	fireOnChange();
 +}
 +
 +
 +FieldState * TextField::createState(DialogState *dialogState)
 +{
 +	return new TextFieldState(dialogState, this);
 +}
 diff --git a/plugins/Skins/SkinLib/TextField.h b/plugins/Skins/SkinLib/TextField.h new file mode 100644 index 0000000000..8d2291f876 --- /dev/null +++ b/plugins/Skins/SkinLib/TextField.h @@ -0,0 +1,35 @@ +#ifndef __TEXT_FIELD_H__
 +# define __TEXT_FIELD_H__
 +
 +#include "Field.h"
 +
 +
 +class TextField : public Field
 +{
 +public:
 +	TextField(Dialog *dlg, const char *name);
 +	virtual ~TextField();
 +
 +	virtual FieldType getType() const;
 +
 +	virtual const TCHAR * getText() const;
 +	virtual void setText(const TCHAR *text);
 +
 +	virtual HFONT getFont() const;
 +	virtual void setFont(HFONT hFont);
 +
 +	virtual COLORREF getFontColor() const;
 +	virtual void setFontColor(COLORREF color);
 +
 +	virtual FieldState * createState(DialogState *dialogState);
 +
 +private:
 +	std::tstring text;
 +	HFONT hFont;
 +	COLORREF fontColor;
 +
 +};
 +
 +
 +
 +#endif // __TEXT_FIELD_H__
 diff --git a/plugins/Skins/SkinLib/TextFieldState.cpp b/plugins/Skins/SkinLib/TextFieldState.cpp new file mode 100644 index 0000000000..8e295d01ee --- /dev/null +++ b/plugins/Skins/SkinLib/TextFieldState.cpp @@ -0,0 +1,65 @@ +#include "globals.h"
 +#include "TextFieldState.h"
 +
 +
 +TextFieldState::TextFieldState(DialogState *dialog, TextField *field) 
 +		: FieldState(dialog, field), font(field->getFont(), field->getFontColor()), textSet(false)
 +{
 +}
 +
 +TextFieldState::~TextFieldState()
 +{
 +}
 +
 +TextField * TextFieldState::getField() const
 +{
 +	return (TextField *) FieldState::getField();
 +}
 +
 +
 +Size TextFieldState::getPreferedSize() const
 +{
 +	HDC hdc = CreateCompatibleDC(NULL);
 +
 +	HFONT newFont = getFont()->getHFONT();
 +	HFONT oldFont = (HFONT) SelectObject(hdc, newFont);
 +
 +	RECT rc = {0};
 +	const TCHAR *text = getText();
 +	DrawText(hdc, text, -1, &rc, DT_CALCRECT | DT_NOPREFIX | DT_EXPANDTABS | DT_SINGLELINE);
 +
 +	SelectObject(hdc, oldFont);
 +
 +	DeleteDC(hdc);
 +
 +	return Size(rc.right - rc.left, rc.bottom - rc.top);
 +}
 +
 +const TCHAR * TextFieldState::getText() const
 +{
 +	if (textSet)
 +		return text.c_str();
 +
 +	return getField()->getText();
 +}
 +
 +void TextFieldState::setText(const TCHAR *text)
 +{
 +	this->text = text;
 +	textSet = true;
 +}
 +
 +FontState * TextFieldState::getFont()
 +{
 +	return &font;
 +}
 +
 +const FontState * TextFieldState::getFont() const
 +{
 +	return &font;
 +}
 +
 +bool TextFieldState::isEmpty() const
 +{
 +	return lstrlen(getText()) <= 0;
 +}
 diff --git a/plugins/Skins/SkinLib/TextFieldState.h b/plugins/Skins/SkinLib/TextFieldState.h new file mode 100644 index 0000000000..9779cfa569 --- /dev/null +++ b/plugins/Skins/SkinLib/TextFieldState.h @@ -0,0 +1,38 @@ +#ifndef __TEXT_FIELD_STATE_H__
 +# define __TEXT_FIELD_STATE_H__
 +
 +#include "TextField.h"
 +#include "FieldState.h"
 +#include "FontState.h"
 +
 +
 +class TextFieldState : public FieldState
 +{
 +public:
 +	virtual ~TextFieldState();
 +
 +	virtual TextField * getField() const;
 +
 +	virtual Size getPreferedSize() const;
 +
 +	virtual const TCHAR * getText() const;
 +	virtual void setText(const TCHAR *text);
 +
 +	virtual FontState * getFont();
 +	virtual const FontState * getFont() const;
 +
 +	virtual bool isEmpty() const;
 +
 +private:
 +	TextFieldState(DialogState *dialog, TextField *field);
 +
 +	FontState font;
 +	BOOL textSet;
 +	std::tstring text;
 +
 +
 +	friend class TextField;
 +};
 +
 +
 +#endif // __TEXT_FIELD_STATE_H__
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/TextFieldState_v8_wrapper.cpp b/plugins/Skins/SkinLib/TextFieldState_v8_wrapper.cpp new file mode 100644 index 0000000000..cf11fdb01f --- /dev/null +++ b/plugins/Skins/SkinLib/TextFieldState_v8_wrapper.cpp @@ -0,0 +1,59 @@ +#include "globals.h"
 +#include "TextFieldState_v8_wrapper.h"
 +#include <v8.h>
 +#include "TextFieldState.h"
 +#include <utf8_helpers.h>
 +
 +using namespace v8;
 +
 +
 +#ifdef UNICODE
 +# define V8_TCHAR uint16_t
 +#else
 +# define V8_TCHAR char
 +#endif
 +
 +
 +static Handle<Value> Get_TextFieldState_text(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	TextFieldState *tmp = (TextFieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( String::New((const V8_TCHAR *) tmp->getText()) );
 +}
 +
 +static void Set_TextFieldState_text(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	TextFieldState *tmp = (TextFieldState *) wrap->Value();
 +	if (tmp == NULL)
 +		return;
 +
 +	if (!value.IsEmpty() && value->IsString())
 +	{
 +		String::Utf8Value utf8_value(value);
 +		tmp->setText(Utf8ToTchar(*utf8_value));
 +	}
 +}
 +
 +
 +void AddTextFieldStateAcessors(Handle<ObjectTemplate> &templ)
 +{
 +	HandleScope scope;
 +	
 +	templ->SetAccessor(String::New("text"), Get_TextFieldState_text, Set_TextFieldState_text);
 +}
 diff --git a/plugins/Skins/SkinLib/TextFieldState_v8_wrapper.h b/plugins/Skins/SkinLib/TextFieldState_v8_wrapper.h new file mode 100644 index 0000000000..c5d9e48a80 --- /dev/null +++ b/plugins/Skins/SkinLib/TextFieldState_v8_wrapper.h @@ -0,0 +1,10 @@ +#ifndef __TEXT_FIELD_STATE_V8_WRAPPER_H__
 +# define __TEXT_FIELD_STATE_V8_WRAPPER_H__
 +
 +#include <v8.h>
 +
 +void AddTextFieldStateAcessors(v8::Handle<v8::ObjectTemplate> &templ);
 +
 +
 +
 +#endif // __TEXT_FIELD_STATE_V8_WRAPPER_H__
 diff --git a/plugins/Skins/SkinLib/V8Script.cpp b/plugins/Skins/SkinLib/V8Script.cpp new file mode 100644 index 0000000000..c7619187a5 --- /dev/null +++ b/plugins/Skins/SkinLib/V8Script.cpp @@ -0,0 +1,236 @@ +#include "globals.h"
 +#include "V8Script.h"
 +#include "V8Wrappers.h"
 +
 +#include <utf8_helpers.h>
 +
 +using namespace v8;
 +
 +#ifdef UNICODE
 +# define V8_TCHAR uint16_t
 +#else
 +# define V8_TCHAR char
 +#endif
 +
 +
 +V8Wrappers *wrappers = NULL;
 +
 +
 +void V8Script::initializeEngine()
 +{
 +	if (wrappers != NULL)
 +		return;
 +
 +	wrappers = new V8Wrappers();
 +}
 +
 +
 +V8Script::V8Script() : exceptionCallback(NULL), exceptionCallbackParam(NULL)
 +{
 +}
 +
 +V8Script::~V8Script()
 +{
 +	dispose();
 +}
 +
 +bool V8Script::compile(const TCHAR *source, Dialog *dlg)
 +{
 +	dispose();
 +
 +	HandleScope handle_scope;
 +
 +	context = Context::New(NULL, wrappers->getGlobalTemplate());
 +
 +	Context::Scope context_scope(context);
 +
 +	context->Global()->Set(String::New("window"), wrappers->newDialogState(), ReadOnly);
 +	context->Global()->Set(String::New("opts"), wrappers->newOptions(), ReadOnly);
 +	context->Global()->Set(String::New("info"), wrappers->newDialogInfo(), ReadOnly);
 +	for(unsigned int i = 0; i < dlg->getFieldCount(); i++)
 +	{
 +		Field *field = dlg->getField(i);
 +		context->Global()->Set(String::New(field->getName()), wrappers->newState(field->getType()), ReadOnly);
 +	}
 +
 +	TryCatch try_catch;
 +	Local<Script> script = Script::Compile(String::New((const V8_TCHAR *) source), String::New(dlg->getName()));
 +	if (script.IsEmpty()) 
 +	{
 +		reportException(&try_catch);
 +		dispose();
 +		return false;
 +	}
 +
 +	// Run once to get the functions
 +	Handle<Value> result = script->Run();
 +	if (script.IsEmpty()) 
 +	{
 +		reportException(&try_catch);
 +		dispose();
 +		return false;
 +	}
 +
 +	Handle<Value> configureFunction = context->Global()->Get(String::New("configure"));
 +	if (!configureFunction.IsEmpty() && !configureFunction->IsFunction()) 
 +		configureFunction.Clear();
 +
 +	Handle<Value> drawFunction = context->Global()->Get(String::New("draw"));
 +	if (drawFunction.IsEmpty() || !drawFunction->IsFunction()) 
 +	{
 +		dispose();
 +		return false;
 +	}
 +
 +	this->configureFunction = Persistent<Function>::New(Handle<Function>::Cast(configureFunction));
 +	this->drawFunction = Persistent<Function>::New(Handle<Function>::Cast(drawFunction));
 +
 +	return true;
 +}
 +
 +void V8Script::dispose()
 +{
 +	context.Dispose();
 +	configureFunction.Dispose();
 +	drawFunction.Dispose();
 +
 +	context.Clear();
 +	configureFunction.Clear();
 +	drawFunction.Clear();
 +}
 +
 +bool V8Script::isValid()
 +{
 +	return !context.IsEmpty() && !drawFunction.IsEmpty();
 +}
 +
 +static Handle<Object> get(Handle<Object> obj, const char *field)
 +{
 +	HandleScope scope;
 +	
 +	Local<Value> v = obj->Get(String::New(field));
 +	_ASSERT(!v.IsEmpty());
 +	_ASSERT(!v->IsUndefined());
 +	_ASSERT(v->IsObject());
 +
 +	return scope.Close( Handle<Object>::Cast(v) );
 +}
 +
 +void V8Script::fillWrappers(DialogState *state, SkinOptions *opts, DialogInfo *info, bool configure)
 +{
 +	Local<Object> global = context->Global();
 +	wrappers->fillOptions(get(global, "opts"), opts, configure);
 +	wrappers->fillDialogState(get(global, "window"), state);
 +	wrappers->fillDialogInfo(get(global, "info"), info);
 +	for(unsigned int i = 0; i < state->fields.size(); i++)
 +	{
 +		FieldState *field = state->fields[i];
 +		wrappers->fillState(get(global, field->getField()->getName()), field);
 +	}
 +}
 +
 +std::pair<SkinOptions *,DialogState *> V8Script::configure(Dialog *dlg)
 +{
 +	if (!isValid())
 +		return std::pair<SkinOptions *,DialogState *>(NULL, NULL);
 +
 +	SkinOptions *opts = new SkinOptions();
 +	DialogState *state = dlg->createState();
 +
 +	if (!configureFunction.IsEmpty())
 +	{
 +		HandleScope handle_scope;
 +
 +		Context::Scope context_scope(context);
 +
 +		fillWrappers(state, opts, dlg->getInfo(), true);
 +
 +		TryCatch try_catch;
 +		Handle<Value> result = configureFunction->Call(context->Global(), 0, NULL);
 +		if (result.IsEmpty()) 
 +		{
 +			reportException(&try_catch);
 +			delete opts;
 +			delete state;
 +			return std::pair<SkinOptions *,DialogState *>(NULL, NULL);;
 +		}
 +	}
 +
 +	return std::pair<SkinOptions *,DialogState *>(opts, state);
 +}
 +
 +bool V8Script::run(DialogState * state, SkinOptions *opts, DialogInfo *info)
 +{
 +	if (!isValid())
 +		return false;
 +
 +	HandleScope handle_scope;
 +
 +	Context::Scope context_scope(context);
 +
 +	fillWrappers(state, opts, info, false);
 +
 +	TryCatch try_catch;
 +	Handle<Value> result = drawFunction->Call(context->Global(), 0, NULL);
 +	if (result.IsEmpty()) 
 +	{
 +		reportException(&try_catch);
 +		return false;
 +	}
 +
 +	return true;
 +}
 +
 +void V8Script::setExceptionCallback(ExceptionCallback cb, void *param)
 +{
 +	exceptionCallback = cb;
 +	exceptionCallbackParam = param;
 +}
 +
 +void V8Script::reportException(v8::TryCatch *try_catch)
 +{
 +	std::string err;
 +	char tmp[1024];
 +
 +	HandleScope handle_scope;
 +	String::Utf8Value exception(try_catch->Exception());
 +	Handle<Message> message = try_catch->Message();
 +	if (message.IsEmpty()) 
 +	{
 +		// V8 didn't provide any extra information about this error; just
 +		// print the exception.
 +		_snprintf(tmp, 1024, "%s\n", *exception);
 +		err += tmp;
 +	}
 +	else 
 +	{
 +		// Print (filename):(line number): (message).
 +		String::Utf8Value filename(message->GetScriptResourceName());
 +		int linenum = message->GetLineNumber();
 +		_snprintf(tmp, 1024, "%s:%i: %s\n", *filename, linenum, *exception);
 +		err += tmp;
 +
 +		// Print line of source code.
 +		String::Utf8Value sourceline(message->GetSourceLine());
 +		_snprintf(tmp, 1024, "%s\n", *sourceline);
 +		err += tmp;
 +
 +		// Print wavy underline (GetUnderline is deprecated).
 +		int start = message->GetStartColumn();
 +		for (int i = 0; i < start; i++) {
 +			err += " ";
 +		}
 +		int end = message->GetEndColumn();
 +		for (int i = start; i < end; i++) {
 +			err += "^";
 +		}
 +		err += "\n";
 +	}
 +
 +	Utf8ToTchar tcharErr(err.c_str());
 +
 +	OutputDebugString(tcharErr);
 +
 +	if (exceptionCallback != NULL)
 +		exceptionCallback(exceptionCallbackParam, tcharErr);
 +}
 diff --git a/plugins/Skins/SkinLib/V8Script.h b/plugins/Skins/SkinLib/V8Script.h new file mode 100644 index 0000000000..b7e1f3f2a6 --- /dev/null +++ b/plugins/Skins/SkinLib/V8Script.h @@ -0,0 +1,46 @@ +#ifndef __V8_SCRIPT_H__
 +# define __V8_SCRIPT_H__
 +
 +#include <v8.h>
 +#include <utility>
 +#include "V8Wrappers.h"
 +
 +
 +typedef void (*ExceptionCallback)(void *param, const TCHAR *err);
 +
 +
 +class V8Script
 +{
 +public:
 +	static void initializeEngine();
 +
 +
 +	V8Script();
 +	~V8Script();
 +
 +	bool compile(const TCHAR *source, Dialog *dlg);
 +	void dispose();
 +
 +	bool isValid();
 +
 +	std::pair<SkinOptions *,DialogState *> configure(Dialog *dlg);
 +
 +	bool run(DialogState * state, SkinOptions *opts, DialogInfo *info);
 +
 +	void setExceptionCallback(ExceptionCallback cb, void *param = NULL);
 +
 +private:
 +	v8::Persistent<v8::Context> context;
 +	v8::Persistent<v8::Function> configureFunction;
 +	v8::Persistent<v8::Function> drawFunction;
 +
 +	ExceptionCallback exceptionCallback;
 +	void *exceptionCallbackParam;
 +
 +	void reportException(v8::TryCatch *try_catch);
 +	void fillWrappers(DialogState *state, SkinOptions *opts, DialogInfo *info, bool configure);
 +};
 +
 +
 +
 +#endif // __V8_SCRIPT_H__
 diff --git a/plugins/Skins/SkinLib/V8Templates.cpp b/plugins/Skins/SkinLib/V8Templates.cpp new file mode 100644 index 0000000000..4900e13772 --- /dev/null +++ b/plugins/Skins/SkinLib/V8Templates.cpp @@ -0,0 +1,475 @@ +#include "globals.h"
 +#include <v8.h>
 +#include "V8Templates.h"
 +#include "DialogState_v8_wrapper.h"
 +#include "FieldState_v8_wrapper.h"
 +#include "ControlFieldState_v8_wrapper.h"
 +#include "TextFieldState_v8_wrapper.h"
 +#include "FontState_v8_wrapper.h"
 +#include "BorderState_v8_wrapper.h"
 +#include "SkinOption_v8_wrapper.h"
 +
 +using namespace v8;
 +
 +
 +V8Templates::V8Templates()
 +{
 +}
 +
 +V8Templates::~V8Templates()
 +{
 +	dialogStateTemplate.Dispose();
 +	fieldStateTemplate.Dispose();
 +	controlFieldStateTemplate.Dispose();
 +	textFieldStateTemplate.Dispose();
 +	fontStateTemplate.Dispose();
 +	borderStateTemplate.Dispose();
 +	skinOptionTemplate.Dispose();
 +}
 +
 +
 +Handle<ObjectTemplate> V8Templates::getGlobalTemplate()
 +{
 +	HandleScope scope;
 +	
 +	if (!globalTemplate.IsEmpty())
 +		return globalTemplate; 
 +	
 +	Handle<ObjectTemplate> templ = ObjectTemplate::New();
 +	templ->Set(String::New("HORIZONTAL_ALIGN_LEFT"), String::New("HORIZONTAL_ALIGN_LEFT"));
 +	templ->Set(String::New("LEFT"), String::New("HORIZONTAL_ALIGN_LEFT"));
 +	templ->Set(String::New("HORIZONTAL_ALIGN_CENTER"), String::New("HORIZONTAL_ALIGN_CENTER"));
 +	templ->Set(String::New("CENTER"), String::New("HORIZONTAL_ALIGN_CENTER"));
 +	templ->Set(String::New("HORIZONTAL_ALIGN_RIGHT"), String::New("HORIZONTAL_ALIGN_RIGHT"));
 +	templ->Set(String::New("RIGHT"), String::New("HORIZONTAL_ALIGN_RIGHT"));
 +	templ->Set(String::New("VERTICAL_ALIGN_TOP"), String::New("VERTICAL_ALIGN_TOP"));
 +	templ->Set(String::New("TOP"), String::New("VERTICAL_ALIGN_TOP"));
 +	templ->Set(String::New("VERTICAL_ALIGN_CENTER"), String::New("VERTICAL_ALIGN_CENTER"));
 +	templ->Set(String::New("CENTER"), String::New("VERTICAL_ALIGN_CENTER"));
 +	templ->Set(String::New("VERTICAL_ALIGN_BOTTOM"), String::New("VERTICAL_ALIGN_BOTTOM"));
 +	templ->Set(String::New("BOTTOM"), String::New("VERTICAL_ALIGN_BOTTOM"));
 +	templ->Set(String::New("CHECKBOX"), String::New("CHECKBOX"));
 +	templ->Set(String::New("NUMBER"), String::New("NUMBER"));
 +	templ->Set(String::New("TEXT"), String::New("TEXT"));
 +	addGlobalTemplateFields(templ);
 +	
 +	globalTemplate = Persistent<ObjectTemplate>::New(templ);
 +	
 +	return globalTemplate;
 +}
 +
 +
 +void V8Templates::addGlobalTemplateFields(Handle<ObjectTemplate> &templ)
 +{
 +}
 +
 +
 +int V8Templates::numOfDialogStateInternalFields()
 +{
 +	return 1;
 +}
 +
 +Handle<ObjectTemplate> V8Templates::getDialogStateTemplate()
 +{
 +	HandleScope scope;
 +	
 +	if (!dialogStateTemplate.IsEmpty())
 +		return dialogStateTemplate; 
 +	
 +	Handle<ObjectTemplate> templ = ObjectTemplate::New();
 +	templ->SetInternalFieldCount(numOfDialogStateInternalFields());
 +	AddDialogStateAcessors(templ);
 +	addDialogStateTemplateFields(templ);
 +	
 +	dialogStateTemplate = Persistent<ObjectTemplate>::New(templ);
 +	
 +	return dialogStateTemplate;
 +}
 +
 +void V8Templates::addDialogStateTemplateFields(Handle<ObjectTemplate> &templ)
 +{
 +}
 +
 +Handle<Object> V8Templates::newDialogState()
 +{
 +	HandleScope scope;
 +	
 +	Handle<Object> obj = getDialogStateTemplate()->NewInstance();
 +	obj->Set(String::New("bordersRaw"), newBorderState(), ReadOnly);
 +	
 +	return scope.Close(obj);
 +}
 +
 +void V8Templates::fillDialogState(Handle<Object> v8Obj, DialogState *obj)
 +{
 +	HandleScope scope;
 +	
 +	_ASSERT(!v8Obj.IsEmpty());
 +
 +	v8Obj->SetInternalField(0, External::New(obj));
 +	fillBorderState(Handle<Object>::Cast(v8Obj->Get(String::New("bordersRaw"))), obj->getBorders());
 +}
 +
 +	
 +int V8Templates::numOfFieldStateInternalFields()
 +{
 +	return 1;
 +}
 +
 +Handle<ObjectTemplate> V8Templates::getFieldStateTemplate()
 +{
 +	HandleScope scope;
 +	
 +	if (!fieldStateTemplate.IsEmpty())
 +		return fieldStateTemplate; 
 +	
 +	Handle<ObjectTemplate> templ = ObjectTemplate::New();
 +	templ->SetInternalFieldCount(numOfFieldStateInternalFields());
 +	AddFieldStateAcessors(templ);
 +	addFieldStateTemplateFields(templ);
 +	
 +	fieldStateTemplate = Persistent<ObjectTemplate>::New(templ);
 +	
 +	return fieldStateTemplate;
 +}
 +
 +void V8Templates::addFieldStateTemplateFields(Handle<ObjectTemplate> &templ)
 +{
 +}
 +
 +Handle<Object> V8Templates::newFieldState()
 +{
 +	HandleScope scope;
 +	
 +	Handle<Object> obj = getFieldStateTemplate()->NewInstance();
 +	obj->Set(String::New("bordersRaw"), newBorderState(), ReadOnly);
 +	
 +	return scope.Close(obj);
 +}
 +
 +void V8Templates::fillFieldState(Handle<Object> v8Obj, FieldState *obj)
 +{
 +	HandleScope scope;
 +	
 +	_ASSERT(!v8Obj.IsEmpty());
 +
 +	v8Obj->SetInternalField(0, External::New(obj));
 +	fillBorderState(Handle<Object>::Cast(v8Obj->Get(String::New("bordersRaw"))), obj->getBorders());
 +}
 +
 +	
 +int V8Templates::numOfControlFieldStateInternalFields()
 +{
 +	return 1;
 +}
 +
 +Handle<ObjectTemplate> V8Templates::getControlFieldStateTemplate()
 +{
 +	HandleScope scope;
 +	
 +	if (!controlFieldStateTemplate.IsEmpty())
 +		return controlFieldStateTemplate; 
 +	
 +	Handle<ObjectTemplate> templ = ObjectTemplate::New();
 +	templ->SetInternalFieldCount(numOfControlFieldStateInternalFields());
 +	AddFieldStateAcessors(templ);
 +	AddControlFieldStateAcessors(templ);
 +	addControlFieldStateTemplateFields(templ);
 +	
 +	controlFieldStateTemplate = Persistent<ObjectTemplate>::New(templ);
 +	
 +	return controlFieldStateTemplate;
 +}
 +
 +void V8Templates::addControlFieldStateTemplateFields(Handle<ObjectTemplate> &templ)
 +{
 +}
 +
 +Handle<Object> V8Templates::newControlFieldState()
 +{
 +	HandleScope scope;
 +	
 +	Handle<Object> obj = getControlFieldStateTemplate()->NewInstance();
 +	obj->Set(String::New("bordersRaw"), newBorderState(), ReadOnly);
 +	obj->Set(String::New("font"), newFontState(), ReadOnly);
 +	
 +	return scope.Close(obj);
 +}
 +
 +void V8Templates::fillControlFieldState(Handle<Object> v8Obj, ControlFieldState *obj)
 +{
 +	HandleScope scope;
 +	
 +	_ASSERT(!v8Obj.IsEmpty());
 +
 +	v8Obj->SetInternalField(0, External::New(obj));
 +	fillBorderState(Handle<Object>::Cast(v8Obj->Get(String::New("bordersRaw"))), obj->getBorders());
 +	fillFontState(Handle<Object>::Cast(v8Obj->Get(String::New("font"))), obj->getFont());
 +}
 +
 +	
 +Handle<ObjectTemplate> V8Templates::getLabelFieldStateTemplate()
 +{
 +	return getControlFieldStateTemplate();
 +}
 +
 +Handle<Object> V8Templates::newLabelFieldState()
 +{
 +	return newControlFieldState();
 +}
 +
 +void V8Templates::fillLabelFieldState(Handle<Object> v8Obj, LabelFieldState *obj)
 +{
 +	fillControlFieldState(v8Obj, obj);
 +}
 +
 +	
 +Handle<ObjectTemplate> V8Templates::getButtonFieldStateTemplate()
 +{
 +	return getControlFieldStateTemplate();
 +}
 +
 +Handle<Object> V8Templates::newButtonFieldState()
 +{
 +	return newControlFieldState();
 +}
 +
 +void V8Templates::fillButtonFieldState(Handle<Object> v8Obj, ButtonFieldState *obj)
 +{
 +	fillControlFieldState(v8Obj, obj);
 +}
 +
 +	
 +Handle<ObjectTemplate> V8Templates::getEditFieldStateTemplate()
 +{
 +	return getControlFieldStateTemplate();
 +}
 +
 +Handle<Object> V8Templates::newEditFieldState()
 +{
 +	return newControlFieldState();
 +}
 +
 +void V8Templates::fillEditFieldState(Handle<Object> v8Obj, EditFieldState *obj)
 +{
 +	fillControlFieldState(v8Obj, obj);
 +}
 +
 +	
 +Handle<ObjectTemplate> V8Templates::getIconFieldStateTemplate()
 +{
 +	return getFieldStateTemplate();
 +}
 +
 +Handle<Object> V8Templates::newIconFieldState()
 +{
 +	return newFieldState();
 +}
 +
 +void V8Templates::fillIconFieldState(Handle<Object> v8Obj, IconFieldState *obj)
 +{
 +	fillFieldState(v8Obj, obj);
 +}
 +
 +	
 +Handle<ObjectTemplate> V8Templates::getImageFieldStateTemplate()
 +{
 +	return getFieldStateTemplate();
 +}
 +
 +Handle<Object> V8Templates::newImageFieldState()
 +{
 +	return newFieldState();
 +}
 +
 +void V8Templates::fillImageFieldState(Handle<Object> v8Obj, ImageFieldState *obj)
 +{
 +	fillFieldState(v8Obj, obj);
 +}
 +
 +	
 +int V8Templates::numOfTextFieldStateInternalFields()
 +{
 +	return 1;
 +}
 +
 +Handle<ObjectTemplate> V8Templates::getTextFieldStateTemplate()
 +{
 +	HandleScope scope;
 +	
 +	if (!textFieldStateTemplate.IsEmpty())
 +		return textFieldStateTemplate; 
 +	
 +	Handle<ObjectTemplate> templ = ObjectTemplate::New();
 +	templ->SetInternalFieldCount(numOfTextFieldStateInternalFields());
 +	AddFieldStateAcessors(templ);
 +	AddTextFieldStateAcessors(templ);
 +	addTextFieldStateTemplateFields(templ);
 +	
 +	textFieldStateTemplate = Persistent<ObjectTemplate>::New(templ);
 +	
 +	return textFieldStateTemplate;
 +}
 +
 +void V8Templates::addTextFieldStateTemplateFields(Handle<ObjectTemplate> &templ)
 +{
 +}
 +
 +Handle<Object> V8Templates::newTextFieldState()
 +{
 +	HandleScope scope;
 +	
 +	Handle<Object> obj = getTextFieldStateTemplate()->NewInstance();
 +	obj->Set(String::New("bordersRaw"), newBorderState(), ReadOnly);
 +	obj->Set(String::New("font"), newFontState(), ReadOnly);
 +	
 +	return scope.Close(obj);
 +}
 +
 +void V8Templates::fillTextFieldState(Handle<Object> v8Obj, TextFieldState *obj)
 +{
 +	HandleScope scope;
 +	
 +	_ASSERT(!v8Obj.IsEmpty());
 +
 +	v8Obj->SetInternalField(0, External::New(obj));
 +	fillBorderState(Handle<Object>::Cast(v8Obj->Get(String::New("bordersRaw"))), obj->getBorders());
 +	fillFontState(Handle<Object>::Cast(v8Obj->Get(String::New("font"))), obj->getFont());
 +}
 +
 +	
 +int V8Templates::numOfFontStateInternalFields()
 +{
 +	return 1;
 +}
 +
 +Handle<ObjectTemplate> V8Templates::getFontStateTemplate()
 +{
 +	HandleScope scope;
 +	
 +	if (!fontStateTemplate.IsEmpty())
 +		return fontStateTemplate; 
 +	
 +	Handle<ObjectTemplate> templ = ObjectTemplate::New();
 +	templ->SetInternalFieldCount(numOfFontStateInternalFields());
 +	AddFontStateAcessors(templ);
 +	addFontStateTemplateFields(templ);
 +	
 +	fontStateTemplate = Persistent<ObjectTemplate>::New(templ);
 +	
 +	return fontStateTemplate;
 +}
 +
 +void V8Templates::addFontStateTemplateFields(Handle<ObjectTemplate> &templ)
 +{
 +}
 +
 +Handle<Object> V8Templates::newFontState()
 +{
 +	HandleScope scope;
 +	
 +	Handle<Object> obj = getFontStateTemplate()->NewInstance();
 +	
 +	return scope.Close(obj);
 +}
 +
 +void V8Templates::fillFontState(Handle<Object> v8Obj, FontState *obj)
 +{
 +	HandleScope scope;
 +	
 +	_ASSERT(!v8Obj.IsEmpty());
 +
 +	v8Obj->SetInternalField(0, External::New(obj));
 +}
 +
 +	
 +int V8Templates::numOfBorderStateInternalFields()
 +{
 +	return 1;
 +}
 +
 +Handle<ObjectTemplate> V8Templates::getBorderStateTemplate()
 +{
 +	HandleScope scope;
 +	
 +	if (!borderStateTemplate.IsEmpty())
 +		return borderStateTemplate; 
 +	
 +	Handle<ObjectTemplate> templ = ObjectTemplate::New();
 +	templ->SetInternalFieldCount(numOfBorderStateInternalFields());
 +	AddBorderStateAcessors(templ);
 +	addBorderStateTemplateFields(templ);
 +	
 +	borderStateTemplate = Persistent<ObjectTemplate>::New(templ);
 +	
 +	return borderStateTemplate;
 +}
 +
 +void V8Templates::addBorderStateTemplateFields(Handle<ObjectTemplate> &templ)
 +{
 +}
 +
 +Handle<Object> V8Templates::newBorderState()
 +{
 +	HandleScope scope;
 +	
 +	Handle<Object> obj = getBorderStateTemplate()->NewInstance();
 +	
 +	return scope.Close(obj);
 +}
 +
 +void V8Templates::fillBorderState(Handle<Object> v8Obj, BorderState *obj)
 +{
 +	HandleScope scope;
 +	
 +	_ASSERT(!v8Obj.IsEmpty());
 +
 +	v8Obj->SetInternalField(0, External::New(obj));
 +}
 +
 +	
 +int V8Templates::numOfSkinOptionInternalFields()
 +{
 +	return 1;
 +}
 +
 +Handle<ObjectTemplate> V8Templates::getSkinOptionTemplate()
 +{
 +	HandleScope scope;
 +	
 +	if (!skinOptionTemplate.IsEmpty())
 +		return skinOptionTemplate; 
 +	
 +	Handle<ObjectTemplate> templ = ObjectTemplate::New();
 +	templ->SetInternalFieldCount(numOfSkinOptionInternalFields());
 +	AddSkinOptionAcessors(templ);
 +	addSkinOptionTemplateFields(templ);
 +	
 +	skinOptionTemplate = Persistent<ObjectTemplate>::New(templ);
 +	
 +	return skinOptionTemplate;
 +}
 +
 +void V8Templates::addSkinOptionTemplateFields(Handle<ObjectTemplate> &templ)
 +{
 +}
 +
 +Handle<Object> V8Templates::newSkinOption()
 +{
 +	HandleScope scope;
 +	
 +	Handle<Object> obj = getSkinOptionTemplate()->NewInstance();
 +	
 +	return scope.Close(obj);
 +}
 +
 +void V8Templates::fillSkinOption(Handle<Object> v8Obj, SkinOption *obj)
 +{
 +	HandleScope scope;
 +	
 +	_ASSERT(!v8Obj.IsEmpty());
 +
 +	v8Obj->SetInternalField(0, External::New(obj));
 +}
 +
 +	
 diff --git a/plugins/Skins/SkinLib/V8Templates.h b/plugins/Skins/SkinLib/V8Templates.h new file mode 100644 index 0000000000..38590fe844 --- /dev/null +++ b/plugins/Skins/SkinLib/V8Templates.h @@ -0,0 +1,114 @@ +#ifndef __V8_TEMPLATES_H__
 +# define __V8_TEMPLATES_H__
 +
 +#include <v8.h>
 +#include "DialogState.h"
 +#include "FieldState.h"
 +#include "ControlFieldState.h"
 +#include "LabelFieldState.h"
 +#include "ButtonFieldState.h"
 +#include "EditFieldState.h"
 +#include "IconFieldState.h"
 +#include "ImageFieldState.h"
 +#include "TextFieldState.h"
 +#include "FontState.h"
 +#include "BorderState.h"
 +#include "SkinOption.h"
 +
 +
 +class V8Templates
 +{
 +public:
 +	V8Templates();
 +	virtual ~V8Templates();
 +	
 +	virtual v8::Handle<v8::ObjectTemplate> getGlobalTemplate();
 +	
 +	virtual v8::Handle<v8::ObjectTemplate> getDialogStateTemplate();
 +	virtual v8::Handle<v8::Object> newDialogState();
 +	virtual void fillDialogState(v8::Handle<v8::Object> v8Obj, DialogState *obj);
 +	
 +	virtual v8::Handle<v8::ObjectTemplate> getFieldStateTemplate();
 +	virtual v8::Handle<v8::Object> newFieldState();
 +	virtual void fillFieldState(v8::Handle<v8::Object> v8Obj, FieldState *obj);
 +	
 +	virtual v8::Handle<v8::ObjectTemplate> getControlFieldStateTemplate();
 +	virtual v8::Handle<v8::Object> newControlFieldState();
 +	virtual void fillControlFieldState(v8::Handle<v8::Object> v8Obj, ControlFieldState *obj);
 +	
 +	virtual v8::Handle<v8::ObjectTemplate> getLabelFieldStateTemplate();
 +	virtual v8::Handle<v8::Object> newLabelFieldState();
 +	virtual void fillLabelFieldState(v8::Handle<v8::Object> v8Obj, LabelFieldState *obj);
 +	
 +	virtual v8::Handle<v8::ObjectTemplate> getButtonFieldStateTemplate();
 +	virtual v8::Handle<v8::Object> newButtonFieldState();
 +	virtual void fillButtonFieldState(v8::Handle<v8::Object> v8Obj, ButtonFieldState *obj);
 +	
 +	virtual v8::Handle<v8::ObjectTemplate> getEditFieldStateTemplate();
 +	virtual v8::Handle<v8::Object> newEditFieldState();
 +	virtual void fillEditFieldState(v8::Handle<v8::Object> v8Obj, EditFieldState *obj);
 +	
 +	virtual v8::Handle<v8::ObjectTemplate> getIconFieldStateTemplate();
 +	virtual v8::Handle<v8::Object> newIconFieldState();
 +	virtual void fillIconFieldState(v8::Handle<v8::Object> v8Obj, IconFieldState *obj);
 +	
 +	virtual v8::Handle<v8::ObjectTemplate> getImageFieldStateTemplate();
 +	virtual v8::Handle<v8::Object> newImageFieldState();
 +	virtual void fillImageFieldState(v8::Handle<v8::Object> v8Obj, ImageFieldState *obj);
 +	
 +	virtual v8::Handle<v8::ObjectTemplate> getTextFieldStateTemplate();
 +	virtual v8::Handle<v8::Object> newTextFieldState();
 +	virtual void fillTextFieldState(v8::Handle<v8::Object> v8Obj, TextFieldState *obj);
 +	
 +	virtual v8::Handle<v8::ObjectTemplate> getFontStateTemplate();
 +	virtual v8::Handle<v8::Object> newFontState();
 +	virtual void fillFontState(v8::Handle<v8::Object> v8Obj, FontState *obj);
 +	
 +	virtual v8::Handle<v8::ObjectTemplate> getBorderStateTemplate();
 +	virtual v8::Handle<v8::Object> newBorderState();
 +	virtual void fillBorderState(v8::Handle<v8::Object> v8Obj, BorderState *obj);
 +	
 +	virtual v8::Handle<v8::ObjectTemplate> getSkinOptionTemplate();
 +	virtual v8::Handle<v8::Object> newSkinOption();
 +	virtual void fillSkinOption(v8::Handle<v8::Object> v8Obj, SkinOption *obj);
 +	
 +
 +private:
 +	v8::Persistent<v8::ObjectTemplate> globalTemplate;
 +	v8::Persistent<v8::ObjectTemplate> dialogStateTemplate;
 +	v8::Persistent<v8::ObjectTemplate> fieldStateTemplate;
 +	v8::Persistent<v8::ObjectTemplate> controlFieldStateTemplate;
 +	v8::Persistent<v8::ObjectTemplate> textFieldStateTemplate;
 +	v8::Persistent<v8::ObjectTemplate> fontStateTemplate;
 +	v8::Persistent<v8::ObjectTemplate> borderStateTemplate;
 +	v8::Persistent<v8::ObjectTemplate> skinOptionTemplate;
 +
 +protected:
 +	virtual void addGlobalTemplateFields(v8::Handle<v8::ObjectTemplate> &templ);
 +
 +	virtual int numOfDialogStateInternalFields();
 +	virtual void addDialogStateTemplateFields(v8::Handle<v8::ObjectTemplate> &templ);
 +	
 +	virtual int numOfFieldStateInternalFields();
 +	virtual void addFieldStateTemplateFields(v8::Handle<v8::ObjectTemplate> &templ);
 +	
 +	virtual int numOfControlFieldStateInternalFields();
 +	virtual void addControlFieldStateTemplateFields(v8::Handle<v8::ObjectTemplate> &templ);
 +	
 +	virtual int numOfTextFieldStateInternalFields();
 +	virtual void addTextFieldStateTemplateFields(v8::Handle<v8::ObjectTemplate> &templ);
 +	
 +	virtual int numOfFontStateInternalFields();
 +	virtual void addFontStateTemplateFields(v8::Handle<v8::ObjectTemplate> &templ);
 +	
 +	virtual int numOfBorderStateInternalFields();
 +	virtual void addBorderStateTemplateFields(v8::Handle<v8::ObjectTemplate> &templ);
 +	
 +	virtual int numOfSkinOptionInternalFields();
 +	virtual void addSkinOptionTemplateFields(v8::Handle<v8::ObjectTemplate> &templ);
 +	
 +};
 +
 +
 +
 +#endif // __V8_TEMPLATES_H__
 diff --git a/plugins/Skins/SkinLib/V8Wrappers.cpp b/plugins/Skins/SkinLib/V8Wrappers.cpp new file mode 100644 index 0000000000..9384e3c8ad --- /dev/null +++ b/plugins/Skins/SkinLib/V8Wrappers.cpp @@ -0,0 +1,385 @@ +#include "globals.h"
 +#include "V8Wrappers.h"
 +
 +#include <utf8_helpers.h>
 +
 +
 +using namespace v8;
 +
 +
 +#ifdef UNICODE
 +# define V8_TCHAR uint16_t
 +#else
 +# define V8_TCHAR char
 +#endif
 +
 +
 +
 +static Handle<Value> IsEmptyCallback(const Arguments& args)
 +{
 +	HandleScope scope;
 +	
 +	if (args.Length() < 1) 
 +		return scope.Close( Undefined() );
 +
 +	for(int i = 0; i < args.Length(); i++)
 +	{
 +		Local<Value> arg = args[0];
 +
 +		if (arg.IsEmpty() || arg->IsNull() || arg->IsUndefined())
 +		{
 +			return scope.Close( Boolean::New(true) );
 +		}
 +		else if (arg->IsObject())
 +		{
 +			Local<Object> self = Local<Object>::Cast(arg);
 +			if (self->InternalFieldCount() < 1)
 +				continue;
 +
 +			Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +			FieldState *field = (FieldState *) wrap->Value();
 +			if (field == NULL)
 +				continue;
 +
 +			if (field->isEmpty())
 +				return scope.Close( Boolean::New(true) );
 +		}
 +		else if (arg->IsString())
 +		{
 +			Local<String> str = Local<String>::Cast(arg);
 +			if (str->Length() <= 0)
 +				return scope.Close( Boolean::New(true) );
 +		}
 +	}
 +
 +	return scope.Close( Boolean::New(false) );
 +}
 +
 +static Handle<Value> RGBCallback(const Arguments& args)
 +{
 +	HandleScope scope;
 +	
 +	if (args.Length() != 3) 
 +		return scope.Close( Undefined() );
 +
 +	COLORREF color = RGB(args[0]->Int32Value(), args[1]->Int32Value(), args[2]->Int32Value());
 +	return scope.Close( Int32::New(color) );
 +}
 +
 +static Handle<Value> AlertCallback(const Arguments& args)
 +{
 +	HandleScope scope;
 +
 +	if (args.Length() < 1) 
 +		return scope.Close( Boolean::New(false) );
 +
 +	Local<Value> arg = args[0];
 +	String::Utf8Value utf8_value(arg->ToDetailString());
 +
 +	char *tmp = *utf8_value;
 +// TODO 	MessageBox(NULL, Utf8ToTchar(*utf8_value), _T("Skin alert"), MB_OK);
 +
 +	return scope.Close( Boolean::New(true) );
 +}
 +
 +void V8Wrappers::addGlobalTemplateFields(Handle<ObjectTemplate> &templ)
 +{
 +	HandleScope scope;
 +
 +	templ->Set(String::New("IsEmpty"), FunctionTemplate::New(&IsEmptyCallback));
 +	templ->Set(String::New("RGB"), FunctionTemplate::New(&RGBCallback));
 +	templ->Set(String::New("alert"), FunctionTemplate::New(&AlertCallback));
 +}
 +
 +
 +Handle<Object> V8Wrappers::newState(FieldType type)
 +{
 +	switch(type)
 +	{
 +		case SIMPLE_TEXT:
 +			return newTextFieldState();
 +		case SIMPLE_IMAGE:
 +			return newImageFieldState();
 +		case SIMPLE_ICON:
 +			return newIconFieldState();
 +		case CONTROL_LABEL:
 +			return newLabelFieldState();
 +		case CONTROL_BUTTON:
 +			return newButtonFieldState();
 +		case CONTROL_EDIT:
 +			return newEditFieldState();
 +	}
 +	throw "Unknown type";
 +}
 +
 +void V8Wrappers::fillState(Handle<Object> obj, FieldState *state)
 +{
 +	switch(state->getField()->getType())
 +	{
 +		case SIMPLE_TEXT:
 +			fillTextFieldState(obj, (TextFieldState *) state);
 +			break;
 +		case SIMPLE_IMAGE:
 +			fillImageFieldState(obj, (ImageFieldState *) state);
 +			break;
 +		case SIMPLE_ICON:
 +			fillIconFieldState(obj, (IconFieldState *) state);
 +			break;
 +		case CONTROL_LABEL:
 +			fillLabelFieldState(obj, (LabelFieldState *) state);
 +			break;
 +		case CONTROL_BUTTON:
 +			fillButtonFieldState(obj, (ButtonFieldState *) state);
 +			break;
 +		case CONTROL_EDIT:
 +			fillEditFieldState(obj, (EditFieldState *) state);
 +			break;
 +		default:
 +			throw "Unknown type";
 +	}
 +}
 +
 +static Handle<Value> Get_SkinOption_value(SkinOption *opt) 
 +{
 +	HandleScope scope;
 +	
 +	if (opt == NULL)
 +		return scope.Close( Undefined() );
 +
 +	switch (opt->getType())
 +	{
 +		case CHECKBOX:	return scope.Close( Boolean::New(opt->getValueCheckbox()) );
 +		case NUMBER:	return scope.Close( Int32::New(opt->getValueNumber()) );
 +		case TEXT:		return scope.Close( String::New((const V8_TCHAR *) opt->getValueText()) );
 +	}
 +
 +	return scope.Close( Undefined() );
 +}
 +
 +static Handle<Value> Get_Options_Fields(Local<String> aName, const AccessorInfo &info)
 +{
 +	HandleScope scope;
 +
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	SkinOptions *opts = (SkinOptions *) wrap->Value();
 +	if (opts == NULL)
 +		return scope.Close( Undefined() );
 +
 +	String::AsciiValue name(aName);
 +	if (name.length() <= 0)
 +		return scope.Close( Undefined() );
 +
 +	bool configure = self->GetInternalField(1)->BooleanValue();
 +	if (configure)
 +	{
 +		SkinOption * opt = opts->getOption(*name);
 +
 +		if (opt == NULL)
 +		{
 +			opt = new SkinOption(*name);
 +			opts->addOption(opt);
 +		}
 +
 +		wrap = Local<External>::Cast(info.Data());
 +		if (wrap.IsEmpty())
 +			return scope.Close( Undefined() );
 +
 +		V8Wrappers *wrappers = (V8Wrappers *) wrap->Value();
 +		if (wrappers == NULL)
 +			return scope.Close( Undefined() );
 +
 +		Handle<Object> ret = wrappers->newSkinOption();
 +		wrappers->fillSkinOption(ret, opt);
 +		return scope.Close( ret );
 +	}
 +	else
 +	{
 +		SkinOption * opt = opts->getOption(*name);
 +		return scope.Close( Get_SkinOption_value(opt) );
 +	}
 +}
 +
 +Handle<ObjectTemplate> V8Wrappers::getOptionsTemplate()
 +{
 +	HandleScope scope;
 +	
 +	if (!optionsTemplate.IsEmpty())
 +		return optionsTemplate; 
 +	
 +	Handle<ObjectTemplate> templ = ObjectTemplate::New();
 +	templ->SetInternalFieldCount(2);
 +	templ->SetNamedPropertyHandler(&Get_Options_Fields, 0, 0, 0, 0, External::New(this));
 +	
 +	optionsTemplate = Persistent<ObjectTemplate>::New(templ);
 +	
 +	return optionsTemplate;
 +}
 +
 +Handle<Object> V8Wrappers::newOptions()
 +{
 +	HandleScope scope;
 +	
 +	Handle<Object> obj = getOptionsTemplate()->NewInstance();
 +	
 +	return scope.Close(obj);
 +}
 +
 +void V8Wrappers::fillOptions(Handle<Object> v8Obj, SkinOptions *obj, bool configure)
 +{
 +	HandleScope scope;
 +	
 +	_ASSERT(!v8Obj.IsEmpty());
 +
 +	v8Obj->SetInternalField(0, External::New(obj));
 +	v8Obj->SetInternalField(1, Boolean::New(configure));
 +}
 +
 +
 +static Handle<Value> Get_SkinOption_value(Local<String> property, const AccessorInfo &info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	return scope.Close( Get_SkinOption_value((SkinOption *) wrap->Value()) );
 +}
 +
 +static void Set_SkinOption_value(Local<String> property, Local<Value> value, const AccessorInfo& info) 
 +{
 +	HandleScope scope;
 +	
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return;
 +
 +	SkinOption *opt = (SkinOption *) wrap->Value();
 +	if (opt == NULL)
 +		return;
 +
 +	switch (opt->getType())
 +	{
 +		case CHECKBOX:	
 +			if (!value.IsEmpty() && value->IsBoolean())
 +				opt->setValueCheckbox(value->BooleanValue());
 +			break;
 +		case NUMBER:
 +			if (!value.IsEmpty() && value->IsNumber())
 +				opt->setValueNumber(value->Int32Value());
 +			break;
 +		case TEXT:		
 +			if (!value.IsEmpty() && value->IsString())
 +				opt->setValueText(Utf8ToTchar(*String::Utf8Value(value)));
 +			break;
 +	}
 +}
 +
 +void V8Wrappers::addSkinOptionTemplateFields(Handle<ObjectTemplate> &templ)
 +{
 +	HandleScope scope;
 +	
 +	templ->SetAccessor(String::New("value"), Get_SkinOption_value, Set_SkinOption_value);
 +}
 +
 +
 +static Handle<Value> Get_DialogInfo_Fields(Local<String> aName, const AccessorInfo &info)
 +{
 +	HandleScope scope;
 +
 +	Local<Object> self = info.Holder();
 +	Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	DialogInfo *dialogInfo = (DialogInfo *) wrap->Value();
 +	if (dialogInfo == NULL)
 +		return scope.Close( Undefined() );
 +
 +	String::AsciiValue name(aName);
 +	if (name.length() <= 0)
 +		return scope.Close( Undefined() );
 +
 +	wrap = Local<External>::Cast(info.Data());
 +	if (wrap.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	V8Wrappers *wrappers = (V8Wrappers *) wrap->Value();
 +	if (wrappers == NULL)
 +		return scope.Close( Undefined() );
 +
 +	Local<String> aPrefix = Local<String>::Cast(self->GetInternalField(1));
 +	if (aPrefix.IsEmpty())
 +		return scope.Close( Undefined() );
 +
 +	String::AsciiValue prefix(aPrefix);
 +	
 +	std::string var;
 +	var += *prefix;
 +	var += *name;
 +
 +	switch(dialogInfo->getType(var.c_str()))
 +	{
 +		case TYPE_VARIABLE:
 +		{
 +			var += '.';
 +
 +			Handle<Object> ret = wrappers->newDialogInfo();
 +			wrappers->fillDialogInfo(ret, dialogInfo, var.c_str());
 +			return scope.Close( ret );
 +		}
 +		case TYPE_INT:
 +			return scope.Close( Int32::New(dialogInfo->getAsInt(var.c_str())) );
 +		case TYPE_DOUBLE:
 +			return scope.Close( Number::New(dialogInfo->getAsDouble(var.c_str())) );
 +		case TYPE_BOOL:
 +			return scope.Close( Boolean::New(dialogInfo->getAsBool(var.c_str())) );
 +		case TYPE_STRING:
 +			return scope.Close( String::New((const V8_TCHAR *) dialogInfo->getAsString(var.c_str())) );
 +		case UNKNOWN:
 +		default:
 +			return scope.Close( Undefined() );
 +	}
 +}
 +
 +Handle<ObjectTemplate> V8Wrappers::getDialogInfoTemplate()
 +{
 +	HandleScope scope;
 +	
 +	if (!dialogInfoTemplate.IsEmpty())
 +		return dialogInfoTemplate; 
 +	
 +	Handle<ObjectTemplate> templ = ObjectTemplate::New();
 +	templ->SetInternalFieldCount(2);
 +	templ->SetNamedPropertyHandler(&Get_DialogInfo_Fields, 0, 0, 0, 0, External::New(this));
 +	
 +	dialogInfoTemplate = Persistent<ObjectTemplate>::New(templ);
 +	
 +	return dialogInfoTemplate;
 +}
 +
 +Handle<Object> V8Wrappers::newDialogInfo()
 +{
 +	HandleScope scope;
 +	
 +	Handle<Object> obj = getDialogInfoTemplate()->NewInstance();
 +	
 +	return scope.Close(obj);
 +}
 +
 +void V8Wrappers::fillDialogInfo(Handle<Object> v8Obj, DialogInfo *obj, const char *prefix)
 +{
 +	HandleScope scope;
 +	
 +	_ASSERT(!v8Obj.IsEmpty());
 +
 +	v8Obj->SetInternalField(0, External::New(obj));
 +
 +	v8Obj->SetInternalField(1, String::New(prefix != NULL ? prefix : ""));
 +}
 diff --git a/plugins/Skins/SkinLib/V8Wrappers.h b/plugins/Skins/SkinLib/V8Wrappers.h new file mode 100644 index 0000000000..b2c5eb2b92 --- /dev/null +++ b/plugins/Skins/SkinLib/V8Wrappers.h @@ -0,0 +1,35 @@ +#ifndef __V8_WRAPPERS_H__
 +# define __V8_WRAPPERS_H__
 +
 +#include "V8Templates.h"
 +#include "SkinOptions.h"
 +
 +
 +class V8Wrappers : public V8Templates
 +{
 +public:
 +	virtual v8::Handle<v8::Object> newState(FieldType type);
 +	virtual void fillState(v8::Handle<v8::Object> obj, FieldState *state);
 +
 +	virtual v8::Handle<v8::ObjectTemplate> getOptionsTemplate();
 +	virtual v8::Handle<v8::Object> newOptions();
 +	virtual void fillOptions(v8::Handle<v8::Object> v8Obj, SkinOptions *obj, bool configure);
 +
 +	virtual v8::Handle<v8::ObjectTemplate> getDialogInfoTemplate();
 +	virtual v8::Handle<v8::Object> newDialogInfo();
 +	virtual void fillDialogInfo(v8::Handle<v8::Object> v8Obj, DialogInfo *obj, const char *prefix = NULL);
 +
 +private:
 +	v8::Persistent<v8::ObjectTemplate> optionsTemplate;
 +	v8::Persistent<v8::ObjectTemplate> dialogInfoTemplate;
 +
 +protected:
 +	virtual void addGlobalTemplateFields(v8::Handle<v8::ObjectTemplate> &templ);
 +
 +	virtual void addSkinOptionTemplateFields(v8::Handle<v8::ObjectTemplate> &templ);
 +
 +};
 +
 +
 +
 +#endif // __V8_WRAPPERS_H__
 diff --git a/plugins/Skins/SkinLib/globals.h b/plugins/Skins/SkinLib/globals.h new file mode 100644 index 0000000000..18d6ffdcfc --- /dev/null +++ b/plugins/Skins/SkinLib/globals.h @@ -0,0 +1,20 @@ +#ifndef __GLOBALS_H__
 +# define __GLOBALS_H__
 +
 +#ifdef DEBUG
 +#define _CRTDBG_MAP_ALLOC
 +#include <stdlib.h>
 +#include <crtdbg.h>
 +#endif
 +
 +#include <windows.h>
 +#include <newpluginapi.h>
 +#include <m_system.h>
 +#include <m_utils.h>
 +#include <utf8_helpers.h>
 +
 +
 +#define MAX_REGS(_X_) ( sizeof(_X_) / sizeof(_X_[0]) )
 +
 +
 +#endif // __GLOBALS_H__
\ No newline at end of file diff --git a/plugins/Skins/SkinLib/scope.h b/plugins/Skins/SkinLib/scope.h new file mode 100644 index 0000000000..2fad797b88 --- /dev/null +++ b/plugins/Skins/SkinLib/scope.h @@ -0,0 +1,37 @@ +#ifndef __PTR_H__
 +# define __PTR_H__
 +
 +
 +template<class T> 
 +class scope 
 +{
 +public:
 +	scope() : p(NULL) {}
 +	scope(T t) : p(t) {}
 +	~scope() { release(); }
 +
 +	void release()
 +	{
 +		if (p != NULL)
 +			delete p;
 +		p = NULL;
 +	}
 +
 +	T operator=(T t) { release(); p = t; return t; }
 +	T operator->() const { return p; }
 +	operator T() const { return p; }
 +
 +	T detach() 
 +	{ 
 +		T ret = p;
 +		p = NULL;
 +		return ret;
 +	}
 +
 +private:
 +	T p;
 +};
 +
 +
 +
 +#endif // __PTR_H__
 diff --git a/plugins/Skins/SkinLib/tstring.h b/plugins/Skins/SkinLib/tstring.h new file mode 100644 index 0000000000..e6017176c5 --- /dev/null +++ b/plugins/Skins/SkinLib/tstring.h @@ -0,0 +1,13 @@ +#ifndef __TSTRING_H__
 +# define __TSTRING_H__
 +
 +#include <tchar.h>
 +#include <string>
 +
 +
 +namespace std {
 +	typedef basic_string<TCHAR, char_traits<TCHAR>, allocator<TCHAR>> tstring;
 +}
 +
 +
 +#endif // __TSTRING_H__
 diff --git a/plugins/Skins/commons.h b/plugins/Skins/commons.h new file mode 100644 index 0000000000..b31dbbebd2 --- /dev/null +++ b/plugins/Skins/commons.h @@ -0,0 +1,119 @@ +/* 
 +Copyright (C) 2008 Ricardo Pescuma Domenecci
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt.  If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA.  
 +*/
 +
 +
 +#ifndef __COMMONS_H__
 +# define __COMMONS_H__
 +
 +
 +#define OEMRESOURCE 
 +#define _WIN32_WINNT 0x0400
 +#include <windows.h>
 +#include <tchar.h>
 +#include <stdio.h>
 +#include <time.h>
 +#include <commctrl.h>
 +
 +
 +// Disable "...truncated to '255' characters in the debug information" warnings
 +#pragma warning(disable: 4786)
 +
 +#include <vector>
 +#include <string>
 +using namespace std;
 +
 +
 +// Miranda headers
 +#define MIRANDA_VER 0x0800
 +#include <win2k.h>
 +#include <newpluginapi.h>
 +#include <m_system.h>
 +#include <m_system_cpp.h>
 +#include <m_protocols.h>
 +#include <m_protosvc.h>
 +#include <m_clist.h>
 +#include <m_contacts.h>
 +#include <m_langpack.h>
 +#include <m_database.h>
 +#include <m_options.h>
 +#include <m_utils.h>
 +#include <m_updater.h>
 +#include <m_metacontacts.h>
 +#include <m_popup.h>
 +#include <m_history.h>
 +#include <m_message.h>
 +#include <m_folders.h>
 +#include <m_icolib.h>
 +#include <m_imgsrvc.h>
 +#include <m_netlib.h>
 +#include <m_fontservice.h>
 +
 +#include <mir_memory.h>
 +#include <mir_options.h>
 +#include <mir_icons.h>
 +#include <mir_buffer.h>
 +#include <utf8_helpers.h>
 +
 +#include "resource.h"
 +#include "m_skins.h"
 +#include "m_skins_cpp.h"
 +#include "options.h"
 +#include "MirandaSkinnedDialog.h"
 +#include "MirandaField.h"
 +#include "MirandaTextField.h"
 +#include "MirandaIconField.h"
 +#include "MirandaImageField.h"
 +
 +
 +#define MODULE_NAME		"Skins"
 +
 +#define DEFAULT_SKIN_NAME "Default"
 +#define SKIN_EXTENSION "msk"
 +
 +
 +// Global Variables
 +extern HINSTANCE hInst;
 +extern PLUGINLINK *pluginLink;
 +extern FI_INTERFACE *fei;
 +extern HANDLE hChangedEvent;
 +
 +#define MAX_REGS(_A_) ( sizeof(_A_) / sizeof(_A_[0]) )
 +#define MIR_FREE(_X_) if (_X_ != NULL) { mir_free(_X_); _X_ = NULL; }
 +
 +
 +extern TCHAR skinsFolder[1024];
 +
 +extern std::vector<MirandaSkinnedDialog *> dlgs;
 +
 +void getSkinnedDialogFilename(std::tstring &ret, const TCHAR *skin, const char *dialogName);
 +void getAvaiableSkins(std::vector<std::tstring> &skins, MirandaSkinnedDialog *dlg = NULL);
 +
 +
 +// See if a protocol service exists
 +static __inline int ProtoServiceExists(const char *szModule,const char *szService)
 +{
 +	char str[MAXMODULELABELLENGTH];
 +	strcpy(str,szModule);
 +	strcat(str,szService);
 +	return ServiceExists(str);
 +}
 +
 +
 +
 +#endif // __COMMONS_H__
 diff --git a/plugins/Skins/libs/v8-debug.h b/plugins/Skins/libs/v8-debug.h new file mode 100644 index 0000000000..7da4f98a05 --- /dev/null +++ b/plugins/Skins/libs/v8-debug.h @@ -0,0 +1,384 @@ +// Copyright 2008 the V8 project authors. All rights reserved.
 +// Redistribution and use in source and binary forms, with or without
 +// modification, are permitted provided that the following conditions are
 +// met:
 +//
 +//     * Redistributions of source code must retain the above copyright
 +//       notice, this list of conditions and the following disclaimer.
 +//     * Redistributions in binary form must reproduce the above
 +//       copyright notice, this list of conditions and the following
 +//       disclaimer in the documentation and/or other materials provided
 +//       with the distribution.
 +//     * Neither the name of Google Inc. nor the names of its
 +//       contributors may be used to endorse or promote products derived
 +//       from this software without specific prior written permission.
 +//
 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 +
 +#ifndef V8_V8_DEBUG_H_
 +#define V8_V8_DEBUG_H_
 +
 +#include "v8.h"
 +
 +#ifdef _WIN32
 +typedef int int32_t;
 +typedef unsigned int uint32_t;
 +typedef unsigned short uint16_t;  // NOLINT
 +typedef long long int64_t;  // NOLINT
 +
 +// Setup for Windows DLL export/import. See v8.h in this directory for
 +// information on how to build/use V8 as a DLL.
 +#if defined(BUILDING_V8_SHARED) && defined(USING_V8_SHARED)
 +#error both BUILDING_V8_SHARED and USING_V8_SHARED are set - please check the\
 +  build configuration to ensure that at most one of these is set
 +#endif
 +
 +#ifdef BUILDING_V8_SHARED
 +#define EXPORT __declspec(dllexport)
 +#elif USING_V8_SHARED
 +#define EXPORT __declspec(dllimport)
 +#else
 +#define EXPORT
 +#endif
 +
 +#else  // _WIN32
 +
 +// Setup for Linux shared library export. See v8.h in this directory for
 +// information on how to build/use V8 as shared library.
 +#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(V8_SHARED)
 +#define EXPORT __attribute__ ((visibility("default")))
 +#else  // defined(__GNUC__) && (__GNUC__ >= 4)
 +#define EXPORT
 +#endif  // defined(__GNUC__) && (__GNUC__ >= 4)
 +
 +#endif  // _WIN32
 +
 +
 +/**
 + * Debugger support for the V8 JavaScript engine.
 + */
 +namespace v8 {
 +
 +// Debug events which can occur in the V8 JavaScript engine.
 +enum DebugEvent {
 +  Break = 1,
 +  Exception = 2,
 +  NewFunction = 3,
 +  BeforeCompile = 4,
 +  AfterCompile  = 5,
 +  ScriptCollected = 6,
 +  BreakForCommand = 7
 +};
 +
 +
 +class EXPORT Debug {
 + public:
 +  /**
 +   * A client object passed to the v8 debugger whose ownership will be taken by
 +   * it. v8 is always responsible for deleting the object.
 +   */
 +  class ClientData {
 +   public:
 +    virtual ~ClientData() {}
 +  };
 +
 +
 +  /**
 +   * A message object passed to the debug message handler.
 +   */
 +  class Message {
 +   public:
 +    /**
 +     * Check type of message.
 +     */
 +    virtual bool IsEvent() const = 0;
 +    virtual bool IsResponse() const = 0;
 +    virtual DebugEvent GetEvent() const = 0;
 +
 +    /**
 +     * Indicate whether this is a response to a continue command which will
 +     * start the VM running after this is processed.
 +     */
 +    virtual bool WillStartRunning() const = 0;
 +
 +    /**
 +     * Access to execution state and event data. Don't store these cross
 +     * callbacks as their content becomes invalid. These objects are from the
 +     * debugger event that started the debug message loop.
 +     */
 +    virtual Handle<Object> GetExecutionState() const = 0;
 +    virtual Handle<Object> GetEventData() const = 0;
 +
 +    /**
 +     * Get the debugger protocol JSON.
 +     */
 +    virtual Handle<String> GetJSON() const = 0;
 +
 +    /**
 +     * Get the context active when the debug event happened. Note this is not
 +     * the current active context as the JavaScript part of the debugger is
 +     * running in it's own context which is entered at this point.
 +     */
 +    virtual Handle<Context> GetEventContext() const = 0;
 +
 +    /**
 +     * Client data passed with the corresponding request if any. This is the
 +     * client_data data value passed into Debug::SendCommand along with the
 +     * request that led to the message or NULL if the message is an event. The
 +     * debugger takes ownership of the data and will delete it even if there is
 +     * no message handler.
 +     */
 +    virtual ClientData* GetClientData() const = 0;
 +
 +    virtual ~Message() {}
 +  };
 +  
 +
 +  /**
 +   * An event details object passed to the debug event listener.
 +   */
 +  class EventDetails {
 +   public:
 +    /**
 +     * Event type.
 +     */
 +    virtual DebugEvent GetEvent() const = 0;
 +
 +    /**
 +     * Access to execution state and event data of the debug event. Don't store
 +     * these cross callbacks as their content becomes invalid.
 +     */
 +    virtual Handle<Object> GetExecutionState() const = 0;
 +    virtual Handle<Object> GetEventData() const = 0;
 +
 +    /**
 +     * Get the context active when the debug event happened. Note this is not
 +     * the current active context as the JavaScript part of the debugger is
 +     * running in it's own context which is entered at this point.
 +     */
 +    virtual Handle<Context> GetEventContext() const = 0;
 +
 +    /**
 +     * Client data passed with the corresponding callbak whet it was registered.
 +     */
 +    virtual Handle<Value> GetCallbackData() const = 0;
 +
 +    /**
 +     * Client data passed to DebugBreakForCommand function. The
 +     * debugger takes ownership of the data and will delete it even if
 +     * there is no message handler.
 +     */
 +    virtual ClientData* GetClientData() const = 0;
 +
 +    virtual ~EventDetails() {}
 +  };
 +
 +
 +  /**
 +   * Debug event callback function.
 +   *
 +   * \param event the type of the debug event that triggered the callback
 +   *   (enum DebugEvent)
 +   * \param exec_state execution state (JavaScript object)
 +   * \param event_data event specific data (JavaScript object)
 +   * \param data value passed by the user to SetDebugEventListener
 +   */
 +  typedef void (*EventCallback)(DebugEvent event,
 +                                Handle<Object> exec_state,
 +                                Handle<Object> event_data,
 +                                Handle<Value> data);
 +
 +  /**
 +   * Debug event callback function.
 +   *
 +   * \param event_details object providing information about the debug event
 +   *
 +   * A EventCallback2 does not take possession of the event data,
 +   * and must not rely on the data persisting after the handler returns.
 +   */
 +  typedef void (*EventCallback2)(const EventDetails& event_details);
 +
 +  /**
 +   * Debug message callback function.
 +   *
 +   * \param message the debug message handler message object
 +   * \param length length of the message
 +   * \param client_data the data value passed when registering the message handler
 +
 +   * A MessageHandler does not take possession of the message string,
 +   * and must not rely on the data persisting after the handler returns.
 +   *
 +   * This message handler is deprecated. Use MessageHandler2 instead.
 +   */
 +  typedef void (*MessageHandler)(const uint16_t* message, int length,
 +                                 ClientData* client_data);
 +
 +  /**
 +   * Debug message callback function.
 +   *
 +   * \param message the debug message handler message object
 +
 +   * A MessageHandler does not take possession of the message data,
 +   * and must not rely on the data persisting after the handler returns.
 +   */
 +  typedef void (*MessageHandler2)(const Message& message);
 +
 +  /**
 +   * Debug host dispatch callback function.
 +   */
 +  typedef void (*HostDispatchHandler)();
 +
 +  /**
 +   * Callback function for the host to ensure debug messages are processed.
 +   */
 +  typedef void (*DebugMessageDispatchHandler)();
 +
 +  // Set a C debug event listener.
 +  static bool SetDebugEventListener(EventCallback that,
 +                                    Handle<Value> data = Handle<Value>());
 +  static bool SetDebugEventListener2(EventCallback2 that,
 +                                     Handle<Value> data = Handle<Value>());
 +
 +  // Set a JavaScript debug event listener.
 +  static bool SetDebugEventListener(v8::Handle<v8::Object> that,
 +                                    Handle<Value> data = Handle<Value>());
 +
 +  // Schedule a debugger break to happen when JavaScript code is run.
 +  static void DebugBreak();
 +
 +  // Remove scheduled debugger break if it has not happened yet.
 +  static void CancelDebugBreak();
 +
 +  // Break execution of JavaScript (this method can be invoked from a
 +  // non-VM thread) for further client command execution on a VM
 +  // thread. Client data is then passed in EventDetails to
 +  // EventCallback at the moment when the VM actually stops.
 +  static void DebugBreakForCommand(ClientData* data = NULL);
 +
 +  // Message based interface. The message protocol is JSON. NOTE the message
 +  // handler thread is not supported any more parameter must be false.
 +  static void SetMessageHandler(MessageHandler handler,
 +                                bool message_handler_thread = false);
 +  static void SetMessageHandler2(MessageHandler2 handler);
 +  static void SendCommand(const uint16_t* command, int length,
 +                          ClientData* client_data = NULL);
 +
 +  // Dispatch interface.
 +  static void SetHostDispatchHandler(HostDispatchHandler handler,
 +                                     int period = 100);
 +
 +  /**
 +   * Register a callback function to be called when a debug message has been
 +   * received and is ready to be processed. For the debug messages to be
 +   * processed V8 needs to be entered, and in certain embedding scenarios this
 +   * callback can be used to make sure V8 is entered for the debug message to
 +   * be processed. Note that debug messages will only be processed if there is
 +   * a V8 break. This can happen automatically by using the option
 +   * --debugger-auto-break.
 +   * \param provide_locker requires that V8 acquires v8::Locker for you before
 +   *        calling handler
 +   */
 +  static void SetDebugMessageDispatchHandler(
 +      DebugMessageDispatchHandler handler, bool provide_locker = false);
 +
 + /**
 +  * Run a JavaScript function in the debugger.
 +  * \param fun the function to call
 +  * \param data passed as second argument to the function
 +  * With this call the debugger is entered and the function specified is called
 +  * with the execution state as the first argument. This makes it possible to
 +  * get access to information otherwise not available during normal JavaScript
 +  * execution e.g. details on stack frames. Receiver of the function call will
 +  * be the debugger context global object, however this is a subject to change.
 +  * The following example show a JavaScript function which when passed to 
 +  * v8::Debug::Call will return the current line of JavaScript execution.
 +  *
 +  * \code
 +  *   function frame_source_line(exec_state) {
 +  *     return exec_state.frame(0).sourceLine();
 +  *   }
 +  * \endcode
 +  */
 +  static Local<Value> Call(v8::Handle<v8::Function> fun,
 +                            Handle<Value> data = Handle<Value>());
 +
 +  /**
 +   * Returns a mirror object for the given object.
 +   */
 +  static Local<Value> GetMirror(v8::Handle<v8::Value> obj);
 +
 + /**
 +  * Enable the V8 builtin debug agent. The debugger agent will listen on the
 +  * supplied TCP/IP port for remote debugger connection.
 +  * \param name the name of the embedding application
 +  * \param port the TCP/IP port to listen on
 +  * \param wait_for_connection whether V8 should pause on a first statement
 +  *   allowing remote debugger to connect before anything interesting happened
 +  */
 +  static bool EnableAgent(const char* name, int port,
 +                          bool wait_for_connection = false);
 +
 +  /**
 +   * Makes V8 process all pending debug messages.
 +   *
 +   * From V8 point of view all debug messages come asynchronously (e.g. from
 +   * remote debugger) but they all must be handled synchronously: V8 cannot
 +   * do 2 things at one time so normal script execution must be interrupted
 +   * for a while.
 +   *
 +   * Generally when message arrives V8 may be in one of 3 states:
 +   * 1. V8 is running script; V8 will automatically interrupt and process all
 +   * pending messages (however auto_break flag should be enabled);
 +   * 2. V8 is suspended on debug breakpoint; in this state V8 is dedicated
 +   * to reading and processing debug messages;
 +   * 3. V8 is not running at all or has called some long-working C++ function;
 +   * by default it means that processing of all debug message will be deferred
 +   * until V8 gets control again; however, embedding application may improve
 +   * this by manually calling this method.
 +   *
 +   * It makes sense to call this method whenever a new debug message arrived and
 +   * V8 is not already running. Method v8::Debug::SetDebugMessageDispatchHandler
 +   * should help with the former condition.
 +   *
 +   * Technically this method in many senses is equivalent to executing empty
 +   * script:
 +   * 1. It does nothing except for processing all pending debug messages.
 +   * 2. It should be invoked with the same precautions and from the same context
 +   * as V8 script would be invoked from, because:
 +   *   a. with "evaluate" command it can do whatever normal script can do,
 +   *   including all native calls;
 +   *   b. no other thread should call V8 while this method is running
 +   *   (v8::Locker may be used here).
 +   *
 +   * "Evaluate" debug command behavior currently is not specified in scope
 +   * of this method.
 +   */
 +  static void ProcessDebugMessages();
 +
 +  /**
 +   * Debugger is running in it's own context which is entered while debugger
 +   * messages are being dispatched. This is an explicit getter for this
 +   * debugger context. Note that the content of the debugger context is subject
 +   * to change.
 +   */
 +  static Local<Context> GetDebugContext();
 +};
 +
 +
 +}  // namespace v8
 +
 +
 +#undef EXPORT
 +
 +
 +#endif  // V8_V8_DEBUG_H_
 diff --git a/plugins/Skins/libs/v8.h b/plugins/Skins/libs/v8.h new file mode 100644 index 0000000000..9c9edf7292 --- /dev/null +++ b/plugins/Skins/libs/v8.h @@ -0,0 +1,3686 @@ +// Copyright 2007-2009 the V8 project authors. All rights reserved.
 +// Redistribution and use in source and binary forms, with or without
 +// modification, are permitted provided that the following conditions are
 +// met:
 +//
 +//     * Redistributions of source code must retain the above copyright
 +//       notice, this list of conditions and the following disclaimer.
 +//     * Redistributions in binary form must reproduce the above
 +//       copyright notice, this list of conditions and the following
 +//       disclaimer in the documentation and/or other materials provided
 +//       with the distribution.
 +//     * Neither the name of Google Inc. nor the names of its
 +//       contributors may be used to endorse or promote products derived
 +//       from this software without specific prior written permission.
 +//
 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 +
 +/** \mainpage V8 API Reference Guide
 + *
 + * V8 is Google's open source JavaScript engine.
 + *
 + * This set of documents provides reference material generated from the
 + * V8 header file, include/v8.h.
 + *
 + * For other documentation see http://code.google.com/apis/v8/
 + */
 +
 +#ifndef V8_H_
 +#define V8_H_
 +
 +#include <stdio.h>
 +
 +#ifdef _WIN32
 +// When compiling on MinGW stdint.h is available.
 +#ifdef __MINGW32__
 +#include <stdint.h>
 +#else  // __MINGW32__
 +typedef signed char int8_t;
 +typedef unsigned char uint8_t;
 +typedef short int16_t;  // NOLINT
 +typedef unsigned short uint16_t;  // NOLINT
 +typedef int int32_t;
 +typedef unsigned int uint32_t;
 +typedef __int64 int64_t;
 +typedef unsigned __int64 uint64_t;
 +// intptr_t and friends are defined in crtdefs.h through stdio.h.
 +#endif  // __MINGW32__
 +
 +// Setup for Windows DLL export/import. When building the V8 DLL the
 +// BUILDING_V8_SHARED needs to be defined. When building a program which uses
 +// the V8 DLL USING_V8_SHARED needs to be defined. When either building the V8
 +// static library or building a program which uses the V8 static library neither
 +// BUILDING_V8_SHARED nor USING_V8_SHARED should be defined.
 +#if defined(BUILDING_V8_SHARED) && defined(USING_V8_SHARED)
 +#error both BUILDING_V8_SHARED and USING_V8_SHARED are set - please check the\
 +  build configuration to ensure that at most one of these is set
 +#endif
 +
 +#ifdef BUILDING_V8_SHARED
 +#define V8EXPORT __declspec(dllexport)
 +#elif USING_V8_SHARED
 +#define V8EXPORT __declspec(dllimport)
 +#else
 +#define V8EXPORT
 +#endif  // BUILDING_V8_SHARED
 +
 +#else  // _WIN32
 +
 +#include <stdint.h>
 +
 +// Setup for Linux shared library export. There is no need to distinguish
 +// between building or using the V8 shared library, but we should not
 +// export symbols when we are building a static library.
 +#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(V8_SHARED)
 +#define V8EXPORT __attribute__ ((visibility("default")))
 +#else  // defined(__GNUC__) && (__GNUC__ >= 4)
 +#define V8EXPORT
 +#endif  // defined(__GNUC__) && (__GNUC__ >= 4)
 +
 +#endif  // _WIN32
 +
 +/**
 + * The v8 JavaScript engine.
 + */
 +namespace v8 {
 +
 +class Context;
 +class String;
 +class Value;
 +class Utils;
 +class Number;
 +class Object;
 +class Array;
 +class Int32;
 +class Uint32;
 +class External;
 +class Primitive;
 +class Boolean;
 +class Integer;
 +class Function;
 +class Date;
 +class ImplementationUtilities;
 +class Signature;
 +template <class T> class Handle;
 +template <class T> class Local;
 +template <class T> class Persistent;
 +class FunctionTemplate;
 +class ObjectTemplate;
 +class Data;
 +class AccessorInfo;
 +class StackTrace;
 +class StackFrame;
 +
 +namespace internal {
 +
 +class Arguments;
 +class Object;
 +class Heap;
 +class Top;
 +
 +}
 +
 +
 +// --- W e a k  H a n d l e s
 +
 +
 +/**
 + * A weak reference callback function.
 + *
 + * This callback should either explicitly invoke Dispose on |object| if
 + * V8 wrapper is not needed anymore, or 'revive' it by invocation of MakeWeak.
 + *
 + * \param object the weak global object to be reclaimed by the garbage collector
 + * \param parameter the value passed in when making the weak global object
 + */
 +typedef void (*WeakReferenceCallback)(Persistent<Value> object,
 +                                      void* parameter);
 +
 +
 +// --- H a n d l e s ---
 +
 +#define TYPE_CHECK(T, S)                                       \
 +  while (false) {                                              \
 +    *(static_cast<T* volatile*>(0)) = static_cast<S*>(0);      \
 +  }
 +
 +/**
 + * An object reference managed by the v8 garbage collector.
 + *
 + * All objects returned from v8 have to be tracked by the garbage
 + * collector so that it knows that the objects are still alive.  Also,
 + * because the garbage collector may move objects, it is unsafe to
 + * point directly to an object.  Instead, all objects are stored in
 + * handles which are known by the garbage collector and updated
 + * whenever an object moves.  Handles should always be passed by value
 + * (except in cases like out-parameters) and they should never be
 + * allocated on the heap.
 + *
 + * There are two types of handles: local and persistent handles.
 + * Local handles are light-weight and transient and typically used in
 + * local operations.  They are managed by HandleScopes.  Persistent
 + * handles can be used when storing objects across several independent
 + * operations and have to be explicitly deallocated when they're no
 + * longer used.
 + *
 + * It is safe to extract the object stored in the handle by
 + * dereferencing the handle (for instance, to extract the Object* from
 + * an Handle<Object>); the value will still be governed by a handle
 + * behind the scenes and the same rules apply to these values as to
 + * their handles.
 + */
 +template <class T> class Handle {
 + public:
 +
 +  /**
 +   * Creates an empty handle.
 +   */
 +  inline Handle();
 +
 +  /**
 +   * Creates a new handle for the specified value.
 +   */
 +  inline explicit Handle(T* val) : val_(val) { }
 +
 +  /**
 +   * Creates a handle for the contents of the specified handle.  This
 +   * constructor allows you to pass handles as arguments by value and
 +   * to assign between handles.  However, if you try to assign between
 +   * incompatible handles, for instance from a Handle<String> to a
 +   * Handle<Number> it will cause a compiletime error.  Assigning
 +   * between compatible handles, for instance assigning a
 +   * Handle<String> to a variable declared as Handle<Value>, is legal
 +   * because String is a subclass of Value.
 +   */
 +  template <class S> inline Handle(Handle<S> that)
 +      : val_(reinterpret_cast<T*>(*that)) {
 +    /**
 +     * This check fails when trying to convert between incompatible
 +     * handles. For example, converting from a Handle<String> to a
 +     * Handle<Number>.
 +     */
 +    TYPE_CHECK(T, S);
 +  }
 +
 +  /**
 +   * Returns true if the handle is empty.
 +   */
 +  inline bool IsEmpty() const { return val_ == 0; }
 +
 +  inline T* operator->() const { return val_; }
 +
 +  inline T* operator*() const { return val_; }
 +
 +  /**
 +   * Sets the handle to be empty. IsEmpty() will then return true.
 +   */
 +  inline void Clear() { this->val_ = 0; }
 +
 +  /**
 +   * Checks whether two handles are the same.
 +   * Returns true if both are empty, or if the objects
 +   * to which they refer are identical.
 +   * The handles' references are not checked.
 +   */
 +  template <class S> inline bool operator==(Handle<S> that) const {
 +    internal::Object** a = reinterpret_cast<internal::Object**>(**this);
 +    internal::Object** b = reinterpret_cast<internal::Object**>(*that);
 +    if (a == 0) return b == 0;
 +    if (b == 0) return false;
 +    return *a == *b;
 +  }
 +
 +  /**
 +   * Checks whether two handles are different.
 +   * Returns true if only one of the handles is empty, or if
 +   * the objects to which they refer are different.
 +   * The handles' references are not checked.
 +   */
 +  template <class S> inline bool operator!=(Handle<S> that) const {
 +    return !operator==(that);
 +  }
 +
 +  template <class S> static inline Handle<T> Cast(Handle<S> that) {
 +#ifdef V8_ENABLE_CHECKS
 +    // If we're going to perform the type check then we have to check
 +    // that the handle isn't empty before doing the checked cast.
 +    if (that.IsEmpty()) return Handle<T>();
 +#endif
 +    return Handle<T>(T::Cast(*that));
 +  }
 +
 +  template <class S> inline Handle<S> As() {
 +    return Handle<S>::Cast(*this);
 +  }
 +
 + private:
 +  T* val_;
 +};
 +
 +
 +/**
 + * A light-weight stack-allocated object handle.  All operations
 + * that return objects from within v8 return them in local handles.  They
 + * are created within HandleScopes, and all local handles allocated within a
 + * handle scope are destroyed when the handle scope is destroyed.  Hence it
 + * is not necessary to explicitly deallocate local handles.
 + */
 +template <class T> class Local : public Handle<T> {
 + public:
 +  inline Local();
 +  template <class S> inline Local(Local<S> that)
 +      : Handle<T>(reinterpret_cast<T*>(*that)) {
 +    /**
 +     * This check fails when trying to convert between incompatible
 +     * handles. For example, converting from a Handle<String> to a
 +     * Handle<Number>.
 +     */
 +    TYPE_CHECK(T, S);
 +  }
 +  template <class S> inline Local(S* that) : Handle<T>(that) { }
 +  template <class S> static inline Local<T> Cast(Local<S> that) {
 +#ifdef V8_ENABLE_CHECKS
 +    // If we're going to perform the type check then we have to check
 +    // that the handle isn't empty before doing the checked cast.
 +    if (that.IsEmpty()) return Local<T>();
 +#endif
 +    return Local<T>(T::Cast(*that));
 +  }
 +
 +  template <class S> inline Local<S> As() {
 +    return Local<S>::Cast(*this);
 +  }
 +
 +  /** Create a local handle for the content of another handle.
 +   *  The referee is kept alive by the local handle even when
 +   *  the original handle is destroyed/disposed.
 +   */
 +  inline static Local<T> New(Handle<T> that);
 +};
 +
 +
 +/**
 + * An object reference that is independent of any handle scope.  Where
 + * a Local handle only lives as long as the HandleScope in which it was
 + * allocated, a Persistent handle remains valid until it is explicitly
 + * disposed.
 + *
 + * A persistent handle contains a reference to a storage cell within
 + * the v8 engine which holds an object value and which is updated by
 + * the garbage collector whenever the object is moved.  A new storage
 + * cell can be created using Persistent::New and existing handles can
 + * be disposed using Persistent::Dispose.  Since persistent handles
 + * are passed by value you may have many persistent handle objects
 + * that point to the same storage cell.  For instance, if you pass a
 + * persistent handle as an argument to a function you will not get two
 + * different storage cells but rather two references to the same
 + * storage cell.
 + */
 +template <class T> class Persistent : public Handle<T> {
 + public:
 +
 +  /**
 +   * Creates an empty persistent handle that doesn't point to any
 +   * storage cell.
 +   */
 +  inline Persistent();
 +
 +  /**
 +   * Creates a persistent handle for the same storage cell as the
 +   * specified handle.  This constructor allows you to pass persistent
 +   * handles as arguments by value and to assign between persistent
 +   * handles.  However, attempting to assign between incompatible
 +   * persistent handles, for instance from a Persistent<String> to a
 +   * Persistent<Number> will cause a compiletime error.  Assigning
 +   * between compatible persistent handles, for instance assigning a
 +   * Persistent<String> to a variable declared as Persistent<Value>,
 +   * is allowed as String is a subclass of Value.
 +   */
 +  template <class S> inline Persistent(Persistent<S> that)
 +      : Handle<T>(reinterpret_cast<T*>(*that)) {
 +    /**
 +     * This check fails when trying to convert between incompatible
 +     * handles. For example, converting from a Handle<String> to a
 +     * Handle<Number>.
 +     */
 +    TYPE_CHECK(T, S);
 +  }
 +
 +  template <class S> inline Persistent(S* that) : Handle<T>(that) { }
 +
 +  /**
 +   * "Casts" a plain handle which is known to be a persistent handle
 +   * to a persistent handle.
 +   */
 +  template <class S> explicit inline Persistent(Handle<S> that)
 +      : Handle<T>(*that) { }
 +
 +  template <class S> static inline Persistent<T> Cast(Persistent<S> that) {
 +#ifdef V8_ENABLE_CHECKS
 +    // If we're going to perform the type check then we have to check
 +    // that the handle isn't empty before doing the checked cast.
 +    if (that.IsEmpty()) return Persistent<T>();
 +#endif
 +    return Persistent<T>(T::Cast(*that));
 +  }
 +
 +  template <class S> inline Persistent<S> As() {
 +    return Persistent<S>::Cast(*this);
 +  }
 +
 +  /**
 +   * Creates a new persistent handle for an existing local or
 +   * persistent handle.
 +   */
 +  inline static Persistent<T> New(Handle<T> that);
 +
 +  /**
 +   * Releases the storage cell referenced by this persistent handle.
 +   * Does not remove the reference to the cell from any handles.
 +   * This handle's reference, and any any other references to the storage
 +   * cell remain and IsEmpty will still return false.
 +   */
 +  inline void Dispose();
 +
 +  /**
 +   * Make the reference to this object weak.  When only weak handles
 +   * refer to the object, the garbage collector will perform a
 +   * callback to the given V8::WeakReferenceCallback function, passing
 +   * it the object reference and the given parameters.
 +   */
 +  inline void MakeWeak(void* parameters, WeakReferenceCallback callback);
 +
 +  /** Clears the weak reference to this object.*/
 +  inline void ClearWeak();
 +
 +  /**
 +   *Checks if the handle holds the only reference to an object.
 +   */
 +  inline bool IsNearDeath() const;
 +
 +  /**
 +   * Returns true if the handle's reference is weak.
 +   */
 +  inline bool IsWeak() const;
 +
 + private:
 +  friend class ImplementationUtilities;
 +  friend class ObjectTemplate;
 +};
 +
 +
 + /**
 + * A stack-allocated class that governs a number of local handles.
 + * After a handle scope has been created, all local handles will be
 + * allocated within that handle scope until either the handle scope is
 + * deleted or another handle scope is created.  If there is already a
 + * handle scope and a new one is created, all allocations will take
 + * place in the new handle scope until it is deleted.  After that,
 + * new handles will again be allocated in the original handle scope.
 + *
 + * After the handle scope of a local handle has been deleted the
 + * garbage collector will no longer track the object stored in the
 + * handle and may deallocate it.  The behavior of accessing a handle
 + * for which the handle scope has been deleted is undefined.
 + */
 +class V8EXPORT HandleScope {
 + public:
 +  HandleScope();
 +
 +  ~HandleScope();
 +
 +  /**
 +   * Closes the handle scope and returns the value as a handle in the
 +   * previous scope, which is the new current scope after the call.
 +   */
 +  template <class T> Local<T> Close(Handle<T> value);
 +
 +  /**
 +   * Counts the number of allocated handles.
 +   */
 +  static int NumberOfHandles();
 +
 +  /**
 +   * Creates a new handle with the given value.
 +   */
 +  static internal::Object** CreateHandle(internal::Object* value);
 +
 + private:
 +  // Make it impossible to create heap-allocated or illegal handle
 +  // scopes by disallowing certain operations.
 +  HandleScope(const HandleScope&);
 +  void operator=(const HandleScope&);
 +  void* operator new(size_t size);
 +  void operator delete(void*, size_t);
 +
 +  // This Data class is accessible internally as HandleScopeData through a
 +  // typedef in the ImplementationUtilities class.
 +  class V8EXPORT Data {
 +   public:
 +    int extensions;
 +    internal::Object** next;
 +    internal::Object** limit;
 +    inline void Initialize() {
 +      extensions = -1;
 +      next = limit = NULL;
 +    }
 +  };
 +
 +  Data previous_;
 +
 +  // Allow for the active closing of HandleScopes which allows to pass a handle
 +  // from the HandleScope being closed to the next top most HandleScope.
 +  bool is_closed_;
 +  internal::Object** RawClose(internal::Object** value);
 +
 +  friend class ImplementationUtilities;
 +};
 +
 +
 +// --- S p e c i a l   o b j e c t s ---
 +
 +
 +/**
 + * The superclass of values and API object templates.
 + */
 +class V8EXPORT Data {
 + private:
 +  Data();
 +};
 +
 +
 +/**
 + * Pre-compilation data that can be associated with a script.  This
 + * data can be calculated for a script in advance of actually
 + * compiling it, and can be stored between compilations.  When script
 + * data is given to the compile method compilation will be faster.
 + */
 +class V8EXPORT ScriptData {  // NOLINT
 + public:
 +  virtual ~ScriptData() { }
 +
 +  /**
 +   * Pre-compiles the specified script (context-independent).
 +   *
 +   * \param input Pointer to UTF-8 script source code.
 +   * \param length Length of UTF-8 script source code.
 +   */
 +  static ScriptData* PreCompile(const char* input, int length);
 +
 +  /**
 +   * Pre-compiles the specified script (context-independent).
 +   *
 +   * NOTE: Pre-compilation using this method cannot happen on another thread
 +   * without using Lockers.
 +   *
 +   * \param source Script source code.
 +   */
 +  static ScriptData* PreCompile(Handle<String> source);
 +
 +  /**
 +   * Load previous pre-compilation data.
 +   *
 +   * \param data Pointer to data returned by a call to Data() of a previous
 +   *   ScriptData. Ownership is not transferred.
 +   * \param length Length of data.
 +   */
 +  static ScriptData* New(const char* data, int length);
 +
 +  /**
 +   * Returns the length of Data().
 +   */
 +  virtual int Length() = 0;
 +
 +  /**
 +   * Returns a serialized representation of this ScriptData that can later be
 +   * passed to New(). NOTE: Serialized data is platform-dependent.
 +   */
 +  virtual const char* Data() = 0;
 +
 +  /**
 +   * Returns true if the source code could not be parsed.
 +   */
 +  virtual bool HasError() = 0;
 +};
 +
 +
 +/**
 + * The origin, within a file, of a script.
 + */
 +class ScriptOrigin {
 + public:
 +  inline ScriptOrigin(
 +      Handle<Value> resource_name,
 +      Handle<Integer> resource_line_offset = Handle<Integer>(),
 +      Handle<Integer> resource_column_offset = Handle<Integer>())
 +      : resource_name_(resource_name),
 +        resource_line_offset_(resource_line_offset),
 +        resource_column_offset_(resource_column_offset) { }
 +  inline Handle<Value> ResourceName() const;
 +  inline Handle<Integer> ResourceLineOffset() const;
 +  inline Handle<Integer> ResourceColumnOffset() const;
 + private:
 +  Handle<Value> resource_name_;
 +  Handle<Integer> resource_line_offset_;
 +  Handle<Integer> resource_column_offset_;
 +};
 +
 +
 +/**
 + * A compiled JavaScript script.
 + */
 +class V8EXPORT Script {
 + public:
 +
 +  /**
 +   * Compiles the specified script (context-independent).
 +   *
 +   * \param source Script source code.
 +   * \param origin Script origin, owned by caller, no references are kept
 +   *   when New() returns
 +   * \param pre_data Pre-parsing data, as obtained by ScriptData::PreCompile()
 +   *   using pre_data speeds compilation if it's done multiple times.
 +   *   Owned by caller, no references are kept when New() returns.
 +   * \param script_data Arbitrary data associated with script. Using
 +   *   this has same effect as calling SetData(), but allows data to be
 +   *   available to compile event handlers.
 +   * \return Compiled script object (context independent; when run it
 +   *   will use the currently entered context).
 +   */
 +  static Local<Script> New(Handle<String> source,
 +                           ScriptOrigin* origin = NULL,
 +                           ScriptData* pre_data = NULL,
 +                           Handle<String> script_data = Handle<String>());
 +
 +  /**
 +   * Compiles the specified script using the specified file name
 +   * object (typically a string) as the script's origin.
 +   *
 +   * \param source Script source code.
 +   * \param file_name file name object (typically a string) to be used
 +   *   as the script's origin.
 +   * \return Compiled script object (context independent; when run it
 +   *   will use the currently entered context).
 +   */
 +  static Local<Script> New(Handle<String> source,
 +                           Handle<Value> file_name);
 +
 +  /**
 +   * Compiles the specified script (bound to current context).
 +   *
 +   * \param source Script source code.
 +   * \param origin Script origin, owned by caller, no references are kept
 +   *   when Compile() returns
 +   * \param pre_data Pre-parsing data, as obtained by ScriptData::PreCompile()
 +   *   using pre_data speeds compilation if it's done multiple times.
 +   *   Owned by caller, no references are kept when Compile() returns.
 +   * \param script_data Arbitrary data associated with script. Using
 +   *   this has same effect as calling SetData(), but makes data available
 +   *   earlier (i.e. to compile event handlers).
 +   * \return Compiled script object, bound to the context that was active
 +   *   when this function was called.  When run it will always use this
 +   *   context.
 +   */
 +  static Local<Script> Compile(Handle<String> source,
 +                               ScriptOrigin* origin = NULL,
 +                               ScriptData* pre_data = NULL,
 +                               Handle<String> script_data = Handle<String>());
 +
 +  /**
 +   * Compiles the specified script using the specified file name
 +   * object (typically a string) as the script's origin.
 +   *
 +   * \param source Script source code.
 +   * \param file_name File name to use as script's origin
 +   * \param script_data Arbitrary data associated with script. Using
 +   *   this has same effect as calling SetData(), but makes data available
 +   *   earlier (i.e. to compile event handlers).
 +   * \return Compiled script object, bound to the context that was active
 +   *   when this function was called.  When run it will always use this
 +   *   context.
 +   */
 +  static Local<Script> Compile(Handle<String> source,
 +                               Handle<Value> file_name,
 +                               Handle<String> script_data = Handle<String>());
 +
 +  /**
 +   * Runs the script returning the resulting value.  If the script is
 +   * context independent (created using ::New) it will be run in the
 +   * currently entered context.  If it is context specific (created
 +   * using ::Compile) it will be run in the context in which it was
 +   * compiled.
 +   */
 +  Local<Value> Run();
 +
 +  /**
 +   * Returns the script id value.
 +   */
 +  Local<Value> Id();
 +
 +  /**
 +   * Associate an additional data object with the script. This is mainly used
 +   * with the debugger as this data object is only available through the
 +   * debugger API.
 +   */
 +  void SetData(Handle<String> data);
 +};
 +
 +
 +/**
 + * An error message.
 + */
 +class V8EXPORT Message {
 + public:
 +  Local<String> Get() const;
 +  Local<String> GetSourceLine() const;
 +
 +  /**
 +   * Returns the resource name for the script from where the function causing
 +   * the error originates.
 +   */
 +  Handle<Value> GetScriptResourceName() const;
 +
 +  /**
 +   * Returns the resource data for the script from where the function causing
 +   * the error originates.
 +   */
 +  Handle<Value> GetScriptData() const;
 +
 +  /**
 +   * Exception stack trace. By default stack traces are not captured for
 +   * uncaught exceptions. SetCaptureStackTraceForUncaughtExceptions allows
 +   * to change this option.
 +   */
 +  Handle<StackTrace> GetStackTrace() const;
 +
 +  /**
 +   * Returns the number, 1-based, of the line where the error occurred.
 +   */
 +  int GetLineNumber() const;
 +
 +  /**
 +   * Returns the index within the script of the first character where
 +   * the error occurred.
 +   */
 +  int GetStartPosition() const;
 +
 +  /**
 +   * Returns the index within the script of the last character where
 +   * the error occurred.
 +   */
 +  int GetEndPosition() const;
 +
 +  /**
 +   * Returns the index within the line of the first character where
 +   * the error occurred.
 +   */
 +  int GetStartColumn() const;
 +
 +  /**
 +   * Returns the index within the line of the last character where
 +   * the error occurred.
 +   */
 +  int GetEndColumn() const;
 +
 +  // TODO(1245381): Print to a string instead of on a FILE.
 +  static void PrintCurrentStackTrace(FILE* out);
 +
 +  static const int kNoLineNumberInfo = 0;
 +  static const int kNoColumnInfo = 0;
 +};
 +
 +
 +/**
 + * Representation of a JavaScript stack trace. The information collected is a
 + * snapshot of the execution stack and the information remains valid after
 + * execution continues.
 + */
 +class V8EXPORT StackTrace {
 + public:
 +  /**
 +   * Flags that determine what information is placed captured for each
 +   * StackFrame when grabbing the current stack trace.
 +   */
 +  enum StackTraceOptions {
 +    kLineNumber = 1,
 +    kColumnOffset = 1 << 1 | kLineNumber,
 +    kScriptName = 1 << 2,
 +    kFunctionName = 1 << 3,
 +    kIsEval = 1 << 4,
 +    kIsConstructor = 1 << 5,
 +    kOverview = kLineNumber | kColumnOffset | kScriptName | kFunctionName,
 +    kDetailed = kOverview | kIsEval | kIsConstructor
 +  };
 +
 +  /**
 +   * Returns a StackFrame at a particular index.
 +   */
 +  Local<StackFrame> GetFrame(uint32_t index) const;
 +
 +  /**
 +   * Returns the number of StackFrames.
 +   */
 +  int GetFrameCount() const;
 +
 +  /**
 +   * Returns StackTrace as a v8::Array that contains StackFrame objects.
 +   */
 +  Local<Array> AsArray();
 +
 +  /**
 +   * Grab a snapshot of the the current JavaScript execution stack.
 +   *
 +   * \param frame_limit The maximum number of stack frames we want to capture.
 +   * \param options Enumerates the set of things we will capture for each
 +   *   StackFrame.
 +   */
 +  static Local<StackTrace> CurrentStackTrace(
 +      int frame_limit,
 +      StackTraceOptions options = kOverview);
 +};
 +
 +
 +/**
 + * A single JavaScript stack frame.
 + */
 +class V8EXPORT StackFrame {
 + public:
 +  /**
 +   * Returns the number, 1-based, of the line for the associate function call.
 +   * This method will return Message::kNoLineNumberInfo if it is unable to
 +   * retrieve the line number, or if kLineNumber was not passed as an option
 +   * when capturing the StackTrace.
 +   */
 +  int GetLineNumber() const;
 +
 +  /**
 +   * Returns the 1-based column offset on the line for the associated function
 +   * call.
 +   * This method will return Message::kNoColumnInfo if it is unable to retrieve
 +   * the column number, or if kColumnOffset was not passed as an option when
 +   * capturing the StackTrace.
 +   */
 +  int GetColumn() const;
 +
 +  /**
 +   * Returns the name of the resource that contains the script for the
 +   * function for this StackFrame.
 +   */
 +  Local<String> GetScriptName() const;
 +
 +  /**
 +   * Returns the name of the function associated with this stack frame.
 +   */
 +  Local<String> GetFunctionName() const;
 +
 +  /**
 +   * Returns whether or not the associated function is compiled via a call to
 +   * eval().
 +   */
 +  bool IsEval() const;
 +
 +  /**
 +   * Returns whther or not the associated function is called as a
 +   * constructor via "new".
 +   */
 +  bool IsConstructor() const;
 +};
 +
 +
 +// --- V a l u e ---
 +
 +
 +/**
 + * The superclass of all JavaScript values and objects.
 + */
 +class Value : public Data {
 + public:
 +
 +  /**
 +   * Returns true if this value is the undefined value.  See ECMA-262
 +   * 4.3.10.
 +   */
 +  V8EXPORT bool IsUndefined() const;
 +
 +  /**
 +   * Returns true if this value is the null value.  See ECMA-262
 +   * 4.3.11.
 +   */
 +  V8EXPORT bool IsNull() const;
 +
 +   /**
 +   * Returns true if this value is true.
 +   */
 +  V8EXPORT bool IsTrue() const;
 +
 +  /**
 +   * Returns true if this value is false.
 +   */
 +  V8EXPORT bool IsFalse() const;
 +
 +  /**
 +   * Returns true if this value is an instance of the String type.
 +   * See ECMA-262 8.4.
 +   */
 +  inline bool IsString() const;
 +
 +  /**
 +   * Returns true if this value is a function.
 +   */
 +  V8EXPORT bool IsFunction() const;
 +
 +  /**
 +   * Returns true if this value is an array.
 +   */
 +  V8EXPORT bool IsArray() const;
 +
 +  /**
 +   * Returns true if this value is an object.
 +   */
 +  V8EXPORT bool IsObject() const;
 +
 +  /**
 +   * Returns true if this value is boolean.
 +   */
 +  V8EXPORT bool IsBoolean() const;
 +
 +  /**
 +   * Returns true if this value is a number.
 +   */
 +  V8EXPORT bool IsNumber() const;
 +
 +  /**
 +   * Returns true if this value is external.
 +   */
 +  V8EXPORT bool IsExternal() const;
 +
 +  /**
 +   * Returns true if this value is a 32-bit signed integer.
 +   */
 +  V8EXPORT bool IsInt32() const;
 +
 +  /**
 +   * Returns true if this value is a 32-bit unsigned integer.
 +   */
 +  V8EXPORT bool IsUint32() const;
 +
 +  /**
 +   * Returns true if this value is a Date.
 +   */
 +  V8EXPORT bool IsDate() const;
 +
 +  /**
 +   * Returns true if this value is a RegExp.
 +   */
 +  V8EXPORT bool IsRegExp() const;
 +
 +  V8EXPORT Local<Boolean> ToBoolean() const;
 +  V8EXPORT Local<Number> ToNumber() const;
 +  V8EXPORT Local<String> ToString() const;
 +  V8EXPORT Local<String> ToDetailString() const;
 +  V8EXPORT Local<Object> ToObject() const;
 +  V8EXPORT Local<Integer> ToInteger() const;
 +  V8EXPORT Local<Uint32> ToUint32() const;
 +  V8EXPORT Local<Int32> ToInt32() const;
 +
 +  /**
 +   * Attempts to convert a string to an array index.
 +   * Returns an empty handle if the conversion fails.
 +   */
 +  V8EXPORT Local<Uint32> ToArrayIndex() const;
 +
 +  V8EXPORT bool BooleanValue() const;
 +  V8EXPORT double NumberValue() const;
 +  V8EXPORT int64_t IntegerValue() const;
 +  V8EXPORT uint32_t Uint32Value() const;
 +  V8EXPORT int32_t Int32Value() const;
 +
 +  /** JS == */
 +  V8EXPORT bool Equals(Handle<Value> that) const;
 +  V8EXPORT bool StrictEquals(Handle<Value> that) const;
 +
 + private:
 +  inline bool QuickIsString() const;
 +  V8EXPORT bool FullIsString() const;
 +};
 +
 +
 +/**
 + * The superclass of primitive values.  See ECMA-262 4.3.2.
 + */
 +class Primitive : public Value { };
 +
 +
 +/**
 + * A primitive boolean value (ECMA-262, 4.3.14).  Either the true
 + * or false value.
 + */
 +class Boolean : public Primitive {
 + public:
 +  V8EXPORT bool Value() const;
 +  static inline Handle<Boolean> New(bool value);
 +};
 +
 +
 +/**
 + * A JavaScript string value (ECMA-262, 4.3.17).
 + */
 +class String : public Primitive {
 + public:
 +
 +  /**
 +   * Returns the number of characters in this string.
 +   */
 +  V8EXPORT int Length() const;
 +
 +  /**
 +   * Returns the number of bytes in the UTF-8 encoded
 +   * representation of this string.
 +   */
 +  V8EXPORT int Utf8Length() const;
 +
 +  /**
 +   * Write the contents of the string to an external buffer.
 +   * If no arguments are given, expects the buffer to be large
 +   * enough to hold the entire string and NULL terminator. Copies
 +   * the contents of the string and the NULL terminator into the
 +   * buffer.
 +   *
 +   * Copies up to length characters into the output buffer.
 +   * Only null-terminates if there is enough space in the buffer.
 +   *
 +   * \param buffer The buffer into which the string will be copied.
 +   * \param start The starting position within the string at which
 +   * copying begins.
 +   * \param length The number of bytes to copy from the string.
 +   * \param nchars_ref The number of characters written, can be NULL.
 +   * \param hints Various hints that might affect performance of this or
 +   *    subsequent operations.
 +   * \return The number of bytes copied to the buffer
 +   * excluding the NULL terminator.
 +   */
 +  enum WriteHints {
 +    NO_HINTS = 0,
 +    HINT_MANY_WRITES_EXPECTED = 1
 +  };
 +
 +  V8EXPORT int Write(uint16_t* buffer,
 +                     int start = 0,
 +                     int length = -1,
 +                     WriteHints hints = NO_HINTS) const;  // UTF-16
 +  V8EXPORT int WriteAscii(char* buffer,
 +                          int start = 0,
 +                          int length = -1,
 +                          WriteHints hints = NO_HINTS) const;  // ASCII
 +  V8EXPORT int WriteUtf8(char* buffer,
 +                         int length = -1,
 +                         int* nchars_ref = NULL,
 +                         WriteHints hints = NO_HINTS) const;  // UTF-8
 +
 +  /**
 +   * A zero length string.
 +   */
 +  V8EXPORT static v8::Local<v8::String> Empty();
 +
 +  /**
 +   * Returns true if the string is external
 +   */
 +  V8EXPORT bool IsExternal() const;
 +
 +  /**
 +   * Returns true if the string is both external and ascii
 +   */
 +  V8EXPORT bool IsExternalAscii() const;
 +
 +  class V8EXPORT ExternalStringResourceBase {
 +   public:
 +    virtual ~ExternalStringResourceBase() {}
 +
 +   protected:
 +    ExternalStringResourceBase() {}
 +
 +    /**
 +     * Internally V8 will call this Dispose method when the external string
 +     * resource is no longer needed. The default implementation will use the
 +     * delete operator. This method can be overridden in subclasses to
 +     * control how allocated external string resources are disposed.
 +     */
 +    virtual void Dispose() { delete this; }
 +
 +   private:
 +    // Disallow copying and assigning.
 +    ExternalStringResourceBase(const ExternalStringResourceBase&);
 +    void operator=(const ExternalStringResourceBase&);
 +
 +    friend class v8::internal::Heap;
 +  };
 +
 +  /**
 +   * An ExternalStringResource is a wrapper around a two-byte string
 +   * buffer that resides outside V8's heap. Implement an
 +   * ExternalStringResource to manage the life cycle of the underlying
 +   * buffer.  Note that the string data must be immutable.
 +   */
 +  class V8EXPORT ExternalStringResource
 +      : public ExternalStringResourceBase {
 +   public:
 +    /**
 +     * Override the destructor to manage the life cycle of the underlying
 +     * buffer.
 +     */
 +    virtual ~ExternalStringResource() {}
 +
 +    /**
 +     * The string data from the underlying buffer.
 +     */
 +    virtual const uint16_t* data() const = 0;
 +
 +    /**
 +     * The length of the string. That is, the number of two-byte characters.
 +     */
 +    virtual size_t length() const = 0;
 +
 +   protected:
 +    ExternalStringResource() {}
 +  };
 +
 +  /**
 +   * An ExternalAsciiStringResource is a wrapper around an ascii
 +   * string buffer that resides outside V8's heap. Implement an
 +   * ExternalAsciiStringResource to manage the life cycle of the
 +   * underlying buffer.  Note that the string data must be immutable
 +   * and that the data must be strict 7-bit ASCII, not Latin1 or
 +   * UTF-8, which would require special treatment internally in the
 +   * engine and, in the case of UTF-8, do not allow efficient indexing.
 +   * Use String::New or convert to 16 bit data for non-ASCII.
 +   */
 +
 +  class V8EXPORT ExternalAsciiStringResource
 +      : public ExternalStringResourceBase {
 +   public:
 +    /**
 +     * Override the destructor to manage the life cycle of the underlying
 +     * buffer.
 +     */
 +    virtual ~ExternalAsciiStringResource() {}
 +    /** The string data from the underlying buffer.*/
 +    virtual const char* data() const = 0;
 +    /** The number of ascii characters in the string.*/
 +    virtual size_t length() const = 0;
 +   protected:
 +    ExternalAsciiStringResource() {}
 +  };
 +
 +  /**
 +   * Get the ExternalStringResource for an external string.  Returns
 +   * NULL if IsExternal() doesn't return true.
 +   */
 +  inline ExternalStringResource* GetExternalStringResource() const;
 +
 +  /**
 +   * Get the ExternalAsciiStringResource for an external ascii string.
 +   * Returns NULL if IsExternalAscii() doesn't return true.
 +   */
 +  V8EXPORT ExternalAsciiStringResource* GetExternalAsciiStringResource() const;
 +
 +  static inline String* Cast(v8::Value* obj);
 +
 +  /**
 +   * Allocates a new string from either utf-8 encoded or ascii data.
 +   * The second parameter 'length' gives the buffer length.
 +   * If the data is utf-8 encoded, the caller must
 +   * be careful to supply the length parameter.
 +   * If it is not given, the function calls
 +   * 'strlen' to determine the buffer length, it might be
 +   * wrong if 'data' contains a null character.
 +   */
 +  V8EXPORT static Local<String> New(const char* data, int length = -1);
 +
 +  /** Allocates a new string from utf16 data.*/
 +  V8EXPORT static Local<String> New(const uint16_t* data, int length = -1);
 +
 +  /** Creates a symbol. Returns one if it exists already.*/
 +  V8EXPORT static Local<String> NewSymbol(const char* data, int length = -1);
 +
 +  /**
 +   * Creates a new string by concatenating the left and the right strings
 +   * passed in as parameters.
 +   */
 +  V8EXPORT static Local<String> Concat(Handle<String> left,
 +                                       Handle<String>right);
 +
 +  /**
 +   * Creates a new external string using the data defined in the given
 +   * resource. When the external string is no longer live on V8's heap the
 +   * resource will be disposed by calling its Dispose method. The caller of
 +   * this function should not otherwise delete or modify the resource. Neither
 +   * should the underlying buffer be deallocated or modified except through the
 +   * destructor of the external string resource.
 +   */
 +  V8EXPORT static Local<String> NewExternal(ExternalStringResource* resource);
 +
 +  /**
 +   * Associate an external string resource with this string by transforming it
 +   * in place so that existing references to this string in the JavaScript heap
 +   * will use the external string resource. The external string resource's
 +   * character contents needs to be equivalent to this string.
 +   * Returns true if the string has been changed to be an external string.
 +   * The string is not modified if the operation fails. See NewExternal for
 +   * information on the lifetime of the resource.
 +   */
 +  V8EXPORT bool MakeExternal(ExternalStringResource* resource);
 +
 +  /**
 +   * Creates a new external string using the ascii data defined in the given
 +   * resource. When the external string is no longer live on V8's heap the
 +   * resource will be disposed by calling its Dispose method. The caller of
 +   * this function should not otherwise delete or modify the resource. Neither
 +   * should the underlying buffer be deallocated or modified except through the
 +   * destructor of the external string resource.
 +   */
 +  V8EXPORT static Local<String> NewExternal(
 +      ExternalAsciiStringResource* resource);
 +
 +  /**
 +   * Associate an external string resource with this string by transforming it
 +   * in place so that existing references to this string in the JavaScript heap
 +   * will use the external string resource. The external string resource's
 +   * character contents needs to be equivalent to this string.
 +   * Returns true if the string has been changed to be an external string.
 +   * The string is not modified if the operation fails. See NewExternal for
 +   * information on the lifetime of the resource.
 +   */
 +  V8EXPORT bool MakeExternal(ExternalAsciiStringResource* resource);
 +
 +  /**
 +   * Returns true if this string can be made external.
 +   */
 +  V8EXPORT bool CanMakeExternal();
 +
 +  /** Creates an undetectable string from the supplied ascii or utf-8 data.*/
 +  V8EXPORT static Local<String> NewUndetectable(const char* data,
 +                                                int length = -1);
 +
 +  /** Creates an undetectable string from the supplied utf-16 data.*/
 +  V8EXPORT static Local<String> NewUndetectable(const uint16_t* data,
 +                                                int length = -1);
 +
 +  /**
 +   * Converts an object to a utf8-encoded character array.  Useful if
 +   * you want to print the object.  If conversion to a string fails
 +   * (eg. due to an exception in the toString() method of the object)
 +   * then the length() method returns 0 and the * operator returns
 +   * NULL.
 +   */
 +  class V8EXPORT Utf8Value {
 +   public:
 +    explicit Utf8Value(Handle<v8::Value> obj);
 +    ~Utf8Value();
 +    char* operator*() { return str_; }
 +    const char* operator*() const { return str_; }
 +    int length() const { return length_; }
 +   private:
 +    char* str_;
 +    int length_;
 +
 +    // Disallow copying and assigning.
 +    Utf8Value(const Utf8Value&);
 +    void operator=(const Utf8Value&);
 +  };
 +
 +  /**
 +   * Converts an object to an ascii string.
 +   * Useful if you want to print the object.
 +   * If conversion to a string fails (eg. due to an exception in the toString()
 +   * method of the object) then the length() method returns 0 and the * operator
 +   * returns NULL.
 +   */
 +  class V8EXPORT AsciiValue {
 +   public:
 +    explicit AsciiValue(Handle<v8::Value> obj);
 +    ~AsciiValue();
 +    char* operator*() { return str_; }
 +    const char* operator*() const { return str_; }
 +    int length() const { return length_; }
 +   private:
 +    char* str_;
 +    int length_;
 +
 +    // Disallow copying and assigning.
 +    AsciiValue(const AsciiValue&);
 +    void operator=(const AsciiValue&);
 +  };
 +
 +  /**
 +   * Converts an object to a two-byte string.
 +   * If conversion to a string fails (eg. due to an exception in the toString()
 +   * method of the object) then the length() method returns 0 and the * operator
 +   * returns NULL.
 +   */
 +  class V8EXPORT Value {
 +   public:
 +    explicit Value(Handle<v8::Value> obj);
 +    ~Value();
 +    uint16_t* operator*() { return str_; }
 +    const uint16_t* operator*() const { return str_; }
 +    int length() const { return length_; }
 +   private:
 +    uint16_t* str_;
 +    int length_;
 +
 +    // Disallow copying and assigning.
 +    Value(const Value&);
 +    void operator=(const Value&);
 +  };
 +
 + private:
 +  V8EXPORT void VerifyExternalStringResource(ExternalStringResource* val) const;
 +  V8EXPORT static void CheckCast(v8::Value* obj);
 +};
 +
 +
 +/**
 + * A JavaScript number value (ECMA-262, 4.3.20)
 + */
 +class Number : public Primitive {
 + public:
 +  V8EXPORT double Value() const;
 +  V8EXPORT static Local<Number> New(double value);
 +  static inline Number* Cast(v8::Value* obj);
 + private:
 +  V8EXPORT Number();
 +  static void CheckCast(v8::Value* obj);
 +};
 +
 +
 +/**
 + * A JavaScript value representing a signed integer.
 + */
 +class Integer : public Number {
 + public:
 +  V8EXPORT static Local<Integer> New(int32_t value);
 +  V8EXPORT static Local<Integer> NewFromUnsigned(uint32_t value);
 +  V8EXPORT int64_t Value() const;
 +  static inline Integer* Cast(v8::Value* obj);
 + private:
 +  V8EXPORT Integer();
 +  V8EXPORT static void CheckCast(v8::Value* obj);
 +};
 +
 +
 +/**
 + * A JavaScript value representing a 32-bit signed integer.
 + */
 +class Int32 : public Integer {
 + public:
 +  V8EXPORT int32_t Value() const;
 + private:
 +  V8EXPORT Int32();
 +};
 +
 +
 +/**
 + * A JavaScript value representing a 32-bit unsigned integer.
 + */
 +class Uint32 : public Integer {
 + public:
 +  V8EXPORT uint32_t Value() const;
 + private:
 +  V8EXPORT Uint32();
 +};
 +
 +
 +/**
 + * An instance of the built-in Date constructor (ECMA-262, 15.9).
 + */
 +class Date : public Value {
 + public:
 +  V8EXPORT static Local<Value> New(double time);
 +
 +  /**
 +   * A specialization of Value::NumberValue that is more efficient
 +   * because we know the structure of this object.
 +   */
 +  V8EXPORT double NumberValue() const;
 +
 +  static inline Date* Cast(v8::Value* obj);
 + private:
 +  V8EXPORT static void CheckCast(v8::Value* obj);
 +};
 +
 +
 +enum PropertyAttribute {
 +  None       = 0,
 +  ReadOnly   = 1 << 0,
 +  DontEnum   = 1 << 1,
 +  DontDelete = 1 << 2
 +};
 +
 +enum ExternalArrayType {
 +  kExternalByteArray = 1,
 +  kExternalUnsignedByteArray,
 +  kExternalShortArray,
 +  kExternalUnsignedShortArray,
 +  kExternalIntArray,
 +  kExternalUnsignedIntArray,
 +  kExternalFloatArray
 +};
 +
 +/**
 + * Accessor[Getter|Setter] are used as callback functions when
 + * setting|getting a particular property. See Object and ObjectTemplate's
 + * method SetAccessor.
 + */
 +typedef Handle<Value> (*AccessorGetter)(Local<String> property,
 +                                        const AccessorInfo& info);
 +
 +
 +typedef void (*AccessorSetter)(Local<String> property,
 +                               Local<Value> value,
 +                               const AccessorInfo& info);
 +
 +
 +/**
 + * Access control specifications.
 + *
 + * Some accessors should be accessible across contexts.  These
 + * accessors have an explicit access control parameter which specifies
 + * the kind of cross-context access that should be allowed.
 + *
 + * Additionally, for security, accessors can prohibit overwriting by
 + * accessors defined in JavaScript.  For objects that have such
 + * accessors either locally or in their prototype chain it is not
 + * possible to overwrite the accessor by using __defineGetter__ or
 + * __defineSetter__ from JavaScript code.
 + */
 +enum AccessControl {
 +  DEFAULT               = 0,
 +  ALL_CAN_READ          = 1,
 +  ALL_CAN_WRITE         = 1 << 1,
 +  PROHIBITS_OVERWRITING = 1 << 2
 +};
 +
 +
 +/**
 + * A JavaScript object (ECMA-262, 4.3.3)
 + */
 +class Object : public Value {
 + public:
 +  V8EXPORT bool Set(Handle<Value> key,
 +                    Handle<Value> value,
 +                    PropertyAttribute attribs = None);
 +
 +  V8EXPORT bool Set(uint32_t index,
 +                    Handle<Value> value);
 +
 +  // Sets a local property on this object bypassing interceptors and
 +  // overriding accessors or read-only properties.
 +  //
 +  // Note that if the object has an interceptor the property will be set
 +  // locally, but since the interceptor takes precedence the local property
 +  // will only be returned if the interceptor doesn't return a value.
 +  //
 +  // Note also that this only works for named properties.
 +  V8EXPORT bool ForceSet(Handle<Value> key,
 +                         Handle<Value> value,
 +                         PropertyAttribute attribs = None);
 +
 +  V8EXPORT Local<Value> Get(Handle<Value> key);
 +
 +  V8EXPORT Local<Value> Get(uint32_t index);
 +
 +  // TODO(1245389): Replace the type-specific versions of these
 +  // functions with generic ones that accept a Handle<Value> key.
 +  V8EXPORT bool Has(Handle<String> key);
 +
 +  V8EXPORT bool Delete(Handle<String> key);
 +
 +  // Delete a property on this object bypassing interceptors and
 +  // ignoring dont-delete attributes.
 +  V8EXPORT bool ForceDelete(Handle<Value> key);
 +
 +  V8EXPORT bool Has(uint32_t index);
 +
 +  V8EXPORT bool Delete(uint32_t index);
 +
 +  V8EXPORT bool SetAccessor(Handle<String> name,
 +                            AccessorGetter getter,
 +                            AccessorSetter setter = 0,
 +                            Handle<Value> data = Handle<Value>(),
 +                            AccessControl settings = DEFAULT,
 +                            PropertyAttribute attribute = None);
 +
 +  /**
 +   * Returns an array containing the names of the enumerable properties
 +   * of this object, including properties from prototype objects.  The
 +   * array returned by this method contains the same values as would
 +   * be enumerated by a for-in statement over this object.
 +   */
 +  V8EXPORT Local<Array> GetPropertyNames();
 +
 +  /**
 +   * Get the prototype object.  This does not skip objects marked to
 +   * be skipped by __proto__ and it does not consult the security
 +   * handler.
 +   */
 +  V8EXPORT Local<Value> GetPrototype();
 +
 +  /**
 +   * Set the prototype object.  This does not skip objects marked to
 +   * be skipped by __proto__ and it does not consult the security
 +   * handler.
 +   */
 +  V8EXPORT bool SetPrototype(Handle<Value> prototype);
 +
 +  /**
 +   * Finds an instance of the given function template in the prototype
 +   * chain.
 +   */
 +  V8EXPORT Local<Object> FindInstanceInPrototypeChain(
 +      Handle<FunctionTemplate> tmpl);
 +
 +  /**
 +   * Call builtin Object.prototype.toString on this object.
 +   * This is different from Value::ToString() that may call
 +   * user-defined toString function. This one does not.
 +   */
 +  V8EXPORT Local<String> ObjectProtoToString();
 +
 +  /** Gets the number of internal fields for this Object. */
 +  V8EXPORT int InternalFieldCount();
 +  /** Gets the value in an internal field. */
 +  inline Local<Value> GetInternalField(int index);
 +  /** Sets the value in an internal field. */
 +  V8EXPORT void SetInternalField(int index, Handle<Value> value);
 +
 +  /** Gets a native pointer from an internal field. */
 +  inline void* GetPointerFromInternalField(int index);
 +
 +  /** Sets a native pointer in an internal field. */
 +  V8EXPORT void SetPointerInInternalField(int index, void* value);
 +
 +  // Testers for local properties.
 +  V8EXPORT bool HasRealNamedProperty(Handle<String> key);
 +  V8EXPORT bool HasRealIndexedProperty(uint32_t index);
 +  V8EXPORT bool HasRealNamedCallbackProperty(Handle<String> key);
 +
 +  /**
 +   * If result.IsEmpty() no real property was located in the prototype chain.
 +   * This means interceptors in the prototype chain are not called.
 +   */
 +  V8EXPORT Local<Value> GetRealNamedPropertyInPrototypeChain(
 +      Handle<String> key);
 +
 +  /**
 +   * If result.IsEmpty() no real property was located on the object or
 +   * in the prototype chain.
 +   * This means interceptors in the prototype chain are not called.
 +   */
 +  V8EXPORT Local<Value> GetRealNamedProperty(Handle<String> key);
 +
 +  /** Tests for a named lookup interceptor.*/
 +  V8EXPORT bool HasNamedLookupInterceptor();
 +
 +  /** Tests for an index lookup interceptor.*/
 +  V8EXPORT bool HasIndexedLookupInterceptor();
 +
 +  /**
 +   * Turns on access check on the object if the object is an instance of
 +   * a template that has access check callbacks. If an object has no
 +   * access check info, the object cannot be accessed by anyone.
 +   */
 +  V8EXPORT void TurnOnAccessCheck();
 +
 +  /**
 +   * Returns the identity hash for this object. The current implemenation uses
 +   * a hidden property on the object to store the identity hash.
 +   *
 +   * The return value will never be 0. Also, it is not guaranteed to be
 +   * unique.
 +   */
 +  V8EXPORT int GetIdentityHash();
 +
 +  /**
 +   * Access hidden properties on JavaScript objects. These properties are
 +   * hidden from the executing JavaScript and only accessible through the V8
 +   * C++ API. Hidden properties introduced by V8 internally (for example the
 +   * identity hash) are prefixed with "v8::".
 +   */
 +  V8EXPORT bool SetHiddenValue(Handle<String> key, Handle<Value> value);
 +  V8EXPORT Local<Value> GetHiddenValue(Handle<String> key);
 +  V8EXPORT bool DeleteHiddenValue(Handle<String> key);
 +
 +  /**
 +   * Returns true if this is an instance of an api function (one
 +   * created from a function created from a function template) and has
 +   * been modified since it was created.  Note that this method is
 +   * conservative and may return true for objects that haven't actually
 +   * been modified.
 +   */
 +  V8EXPORT bool IsDirty();
 +
 +  /**
 +   * Clone this object with a fast but shallow copy.  Values will point
 +   * to the same values as the original object.
 +   */
 +  V8EXPORT Local<Object> Clone();
 +
 +  /**
 +   * Set the backing store of the indexed properties to be managed by the
 +   * embedding layer. Access to the indexed properties will follow the rules
 +   * spelled out in CanvasPixelArray.
 +   * Note: The embedding program still owns the data and needs to ensure that
 +   *       the backing store is preserved while V8 has a reference.
 +   */
 +  V8EXPORT void SetIndexedPropertiesToPixelData(uint8_t* data, int length);
 +  bool HasIndexedPropertiesInPixelData();
 +  uint8_t* GetIndexedPropertiesPixelData();
 +  int GetIndexedPropertiesPixelDataLength();
 +
 +  /**
 +   * Set the backing store of the indexed properties to be managed by the
 +   * embedding layer. Access to the indexed properties will follow the rules
 +   * spelled out for the CanvasArray subtypes in the WebGL specification.
 +   * Note: The embedding program still owns the data and needs to ensure that
 +   *       the backing store is preserved while V8 has a reference.
 +   */
 +  V8EXPORT void SetIndexedPropertiesToExternalArrayData(
 +      void* data,
 +      ExternalArrayType array_type,
 +      int number_of_elements);
 +  bool HasIndexedPropertiesInExternalArrayData();
 +  void* GetIndexedPropertiesExternalArrayData();
 +  ExternalArrayType GetIndexedPropertiesExternalArrayDataType();
 +  int GetIndexedPropertiesExternalArrayDataLength();
 +
 +  V8EXPORT static Local<Object> New();
 +  static inline Object* Cast(Value* obj);
 + private:
 +  V8EXPORT Object();
 +  V8EXPORT static void CheckCast(Value* obj);
 +  V8EXPORT Local<Value> CheckedGetInternalField(int index);
 +  V8EXPORT void* SlowGetPointerFromInternalField(int index);
 +
 +  /**
 +   * If quick access to the internal field is possible this method
 +   * returns the value.  Otherwise an empty handle is returned.
 +   */
 +  inline Local<Value> UncheckedGetInternalField(int index);
 +};
 +
 +
 +/**
 + * An instance of the built-in array constructor (ECMA-262, 15.4.2).
 + */
 +class Array : public Object {
 + public:
 +  V8EXPORT uint32_t Length() const;
 +
 +  /**
 +   * Clones an element at index |index|.  Returns an empty
 +   * handle if cloning fails (for any reason).
 +   */
 +  V8EXPORT Local<Object> CloneElementAt(uint32_t index);
 +
 +  V8EXPORT static Local<Array> New(int length = 0);
 +  static inline Array* Cast(Value* obj);
 + private:
 +  V8EXPORT Array();
 +  static void CheckCast(Value* obj);
 +};
 +
 +
 +/**
 + * A JavaScript function object (ECMA-262, 15.3).
 + */
 +class Function : public Object {
 + public:
 +  V8EXPORT Local<Object> NewInstance() const;
 +  V8EXPORT Local<Object> NewInstance(int argc, Handle<Value> argv[]) const;
 +  V8EXPORT Local<Value> Call(Handle<Object> recv,
 +                             int argc,
 +                             Handle<Value> argv[]);
 +  V8EXPORT void SetName(Handle<String> name);
 +  V8EXPORT Handle<Value> GetName() const;
 +
 +  /**
 +   * Returns zero based line number of function body and
 +   * kLineOffsetNotFound if no information available.
 +   */
 +  V8EXPORT int GetScriptLineNumber() const;
 +  V8EXPORT ScriptOrigin GetScriptOrigin() const;
 +  static inline Function* Cast(Value* obj);
 +  V8EXPORT static const int kLineOffsetNotFound;
 + private:
 +  V8EXPORT Function();
 +  V8EXPORT static void CheckCast(Value* obj);
 +};
 +
 +
 +/**
 + * A JavaScript value that wraps a C++ void*.  This type of value is
 + * mainly used to associate C++ data structures with JavaScript
 + * objects.
 + *
 + * The Wrap function V8 will return the most optimal Value object wrapping the
 + * C++ void*. The type of the value is not guaranteed to be an External object
 + * and no assumptions about its type should be made. To access the wrapped
 + * value Unwrap should be used, all other operations on that object will lead
 + * to unpredictable results.
 + */
 +class External : public Value {
 + public:
 +  V8EXPORT static Local<Value> Wrap(void* data);
 +  static inline void* Unwrap(Handle<Value> obj);
 +
 +  V8EXPORT static Local<External> New(void* value);
 +  static inline External* Cast(Value* obj);
 +  V8EXPORT void* Value() const;
 + private:
 +  V8EXPORT External();
 +  V8EXPORT static void CheckCast(v8::Value* obj);
 +  static inline void* QuickUnwrap(Handle<v8::Value> obj);
 +  V8EXPORT static void* FullUnwrap(Handle<v8::Value> obj);
 +};
 +
 +
 +// --- T e m p l a t e s ---
 +
 +
 +/**
 + * The superclass of object and function templates.
 + */
 +class V8EXPORT Template : public Data {
 + public:
 +  /** Adds a property to each instance created by this template.*/
 +  void Set(Handle<String> name, Handle<Data> value,
 +           PropertyAttribute attributes = None);
 +  inline void Set(const char* name, Handle<Data> value);
 + private:
 +  Template();
 +
 +  friend class ObjectTemplate;
 +  friend class FunctionTemplate;
 +};
 +
 +
 +/**
 + * The argument information given to function call callbacks.  This
 + * class provides access to information about the context of the call,
 + * including the receiver, the number and values of arguments, and
 + * the holder of the function.
 + */
 +class Arguments {
 + public:
 +  inline int Length() const;
 +  inline Local<Value> operator[](int i) const;
 +  inline Local<Function> Callee() const;
 +  inline Local<Object> This() const;
 +  inline Local<Object> Holder() const;
 +  inline bool IsConstructCall() const;
 +  inline Local<Value> Data() const;
 + private:
 +  friend class ImplementationUtilities;
 +  inline Arguments(Local<Value> data,
 +                   Local<Object> holder,
 +                   Local<Function> callee,
 +                   bool is_construct_call,
 +                   void** values, int length);
 +  Local<Value> data_;
 +  Local<Object> holder_;
 +  Local<Function> callee_;
 +  bool is_construct_call_;
 +  void** values_;
 +  int length_;
 +};
 +
 +
 +/**
 + * The information passed to an accessor callback about the context
 + * of the property access.
 + */
 +class V8EXPORT AccessorInfo {
 + public:
 +  inline AccessorInfo(internal::Object** args)
 +      : args_(args) { }
 +  inline Local<Value> Data() const;
 +  inline Local<Object> This() const;
 +  inline Local<Object> Holder() const;
 + private:
 +  internal::Object** args_;
 +};
 +
 +
 +typedef Handle<Value> (*InvocationCallback)(const Arguments& args);
 +
 +/**
 + * NamedProperty[Getter|Setter] are used as interceptors on object.
 + * See ObjectTemplate::SetNamedPropertyHandler.
 + */
 +typedef Handle<Value> (*NamedPropertyGetter)(Local<String> property,
 +                                             const AccessorInfo& info);
 +
 +
 +/**
 + * Returns the value if the setter intercepts the request.
 + * Otherwise, returns an empty handle.
 + */
 +typedef Handle<Value> (*NamedPropertySetter)(Local<String> property,
 +                                             Local<Value> value,
 +                                             const AccessorInfo& info);
 +
 +/**
 + * Returns a non-empty handle if the interceptor intercepts the request.
 + * The result is an integer encoding property attributes (like v8::None,
 + * v8::DontEnum, etc.)
 + */
 +typedef Handle<Integer> (*NamedPropertyQuery)(Local<String> property,
 +                                              const AccessorInfo& info);
 +
 +
 +/**
 + * Returns a non-empty handle if the deleter intercepts the request.
 + * The return value is true if the property could be deleted and false
 + * otherwise.
 + */
 +typedef Handle<Boolean> (*NamedPropertyDeleter)(Local<String> property,
 +                                                const AccessorInfo& info);
 +
 +/**
 + * Returns an array containing the names of the properties the named
 + * property getter intercepts.
 + */
 +typedef Handle<Array> (*NamedPropertyEnumerator)(const AccessorInfo& info);
 +
 +
 +/**
 + * Returns the value of the property if the getter intercepts the
 + * request.  Otherwise, returns an empty handle.
 + */
 +typedef Handle<Value> (*IndexedPropertyGetter)(uint32_t index,
 +                                               const AccessorInfo& info);
 +
 +
 +/**
 + * Returns the value if the setter intercepts the request.
 + * Otherwise, returns an empty handle.
 + */
 +typedef Handle<Value> (*IndexedPropertySetter)(uint32_t index,
 +                                               Local<Value> value,
 +                                               const AccessorInfo& info);
 +
 +
 +/**
 + * Returns a non-empty handle if the interceptor intercepts the request.
 + * The result is an integer encoding property attributes.
 + */
 +typedef Handle<Integer> (*IndexedPropertyQuery)(uint32_t index,
 +                                                const AccessorInfo& info);
 +
 +/**
 + * Returns a non-empty handle if the deleter intercepts the request.
 + * The return value is true if the property could be deleted and false
 + * otherwise.
 + */
 +typedef Handle<Boolean> (*IndexedPropertyDeleter)(uint32_t index,
 +                                                  const AccessorInfo& info);
 +
 +/**
 + * Returns an array containing the indices of the properties the
 + * indexed property getter intercepts.
 + */
 +typedef Handle<Array> (*IndexedPropertyEnumerator)(const AccessorInfo& info);
 +
 +
 +/**
 + * Access type specification.
 + */
 +enum AccessType {
 +  ACCESS_GET,
 +  ACCESS_SET,
 +  ACCESS_HAS,
 +  ACCESS_DELETE,
 +  ACCESS_KEYS
 +};
 +
 +
 +/**
 + * Returns true if cross-context access should be allowed to the named
 + * property with the given key on the host object.
 + */
 +typedef bool (*NamedSecurityCallback)(Local<Object> host,
 +                                      Local<Value> key,
 +                                      AccessType type,
 +                                      Local<Value> data);
 +
 +
 +/**
 + * Returns true if cross-context access should be allowed to the indexed
 + * property with the given index on the host object.
 + */
 +typedef bool (*IndexedSecurityCallback)(Local<Object> host,
 +                                        uint32_t index,
 +                                        AccessType type,
 +                                        Local<Value> data);
 +
 +
 +/**
 + * A FunctionTemplate is used to create functions at runtime. There
 + * can only be one function created from a FunctionTemplate in a
 + * context.  The lifetime of the created function is equal to the
 + * lifetime of the context.  So in case the embedder needs to create
 + * temporary functions that can be collected using Scripts is
 + * preferred.
 + *
 + * A FunctionTemplate can have properties, these properties are added to the
 + * function object when it is created.
 + *
 + * A FunctionTemplate has a corresponding instance template which is
 + * used to create object instances when the function is used as a
 + * constructor. Properties added to the instance template are added to
 + * each object instance.
 + *
 + * A FunctionTemplate can have a prototype template. The prototype template
 + * is used to create the prototype object of the function.
 + *
 + * The following example shows how to use a FunctionTemplate:
 + *
 + * \code
 + *    v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
 + *    t->Set("func_property", v8::Number::New(1));
 + *
 + *    v8::Local<v8::Template> proto_t = t->PrototypeTemplate();
 + *    proto_t->Set("proto_method", v8::FunctionTemplate::New(InvokeCallback));
 + *    proto_t->Set("proto_const", v8::Number::New(2));
 + *
 + *    v8::Local<v8::ObjectTemplate> instance_t = t->InstanceTemplate();
 + *    instance_t->SetAccessor("instance_accessor", InstanceAccessorCallback);
 + *    instance_t->SetNamedPropertyHandler(PropertyHandlerCallback, ...);
 + *    instance_t->Set("instance_property", Number::New(3));
 + *
 + *    v8::Local<v8::Function> function = t->GetFunction();
 + *    v8::Local<v8::Object> instance = function->NewInstance();
 + * \endcode
 + *
 + * Let's use "function" as the JS variable name of the function object
 + * and "instance" for the instance object created above.  The function
 + * and the instance will have the following properties:
 + *
 + * \code
 + *   func_property in function == true;
 + *   function.func_property == 1;
 + *
 + *   function.prototype.proto_method() invokes 'InvokeCallback'
 + *   function.prototype.proto_const == 2;
 + *
 + *   instance instanceof function == true;
 + *   instance.instance_accessor calls 'InstanceAccessorCallback'
 + *   instance.instance_property == 3;
 + * \endcode
 + *
 + * A FunctionTemplate can inherit from another one by calling the
 + * FunctionTemplate::Inherit method.  The following graph illustrates
 + * the semantics of inheritance:
 + *
 + * \code
 + *   FunctionTemplate Parent  -> Parent() . prototype -> { }
 + *     ^                                                  ^
 + *     | Inherit(Parent)                                  | .__proto__
 + *     |                                                  |
 + *   FunctionTemplate Child   -> Child()  . prototype -> { }
 + * \endcode
 + *
 + * A FunctionTemplate 'Child' inherits from 'Parent', the prototype
 + * object of the Child() function has __proto__ pointing to the
 + * Parent() function's prototype object. An instance of the Child
 + * function has all properties on Parent's instance templates.
 + *
 + * Let Parent be the FunctionTemplate initialized in the previous
 + * section and create a Child FunctionTemplate by:
 + *
 + * \code
 + *   Local<FunctionTemplate> parent = t;
 + *   Local<FunctionTemplate> child = FunctionTemplate::New();
 + *   child->Inherit(parent);
 + *
 + *   Local<Function> child_function = child->GetFunction();
 + *   Local<Object> child_instance = child_function->NewInstance();
 + * \endcode
 + *
 + * The Child function and Child instance will have the following
 + * properties:
 + *
 + * \code
 + *   child_func.prototype.__proto__ == function.prototype;
 + *   child_instance.instance_accessor calls 'InstanceAccessorCallback'
 + *   child_instance.instance_property == 3;
 + * \endcode
 + */
 +class V8EXPORT FunctionTemplate : public Template {
 + public:
 +  /** Creates a function template.*/
 +  static Local<FunctionTemplate> New(
 +      InvocationCallback callback = 0,
 +      Handle<Value> data = Handle<Value>(),
 +      Handle<Signature> signature = Handle<Signature>());
 +  /** Returns the unique function instance in the current execution context.*/
 +  Local<Function> GetFunction();
 +
 +  /**
 +   * Set the call-handler callback for a FunctionTemplate.  This
 +   * callback is called whenever the function created from this
 +   * FunctionTemplate is called.
 +   */
 +  void SetCallHandler(InvocationCallback callback,
 +                      Handle<Value> data = Handle<Value>());
 +
 +  /** Get the InstanceTemplate. */
 +  Local<ObjectTemplate> InstanceTemplate();
 +
 +  /** Causes the function template to inherit from a parent function template.*/
 +  void Inherit(Handle<FunctionTemplate> parent);
 +
 +  /**
 +   * A PrototypeTemplate is the template used to create the prototype object
 +   * of the function created by this template.
 +   */
 +  Local<ObjectTemplate> PrototypeTemplate();
 +
 +
 +  /**
 +   * Set the class name of the FunctionTemplate.  This is used for
 +   * printing objects created with the function created from the
 +   * FunctionTemplate as its constructor.
 +   */
 +  void SetClassName(Handle<String> name);
 +
 +  /**
 +   * Determines whether the __proto__ accessor ignores instances of
 +   * the function template.  If instances of the function template are
 +   * ignored, __proto__ skips all instances and instead returns the
 +   * next object in the prototype chain.
 +   *
 +   * Call with a value of true to make the __proto__ accessor ignore
 +   * instances of the function template.  Call with a value of false
 +   * to make the __proto__ accessor not ignore instances of the
 +   * function template.  By default, instances of a function template
 +   * are not ignored.
 +   */
 +  void SetHiddenPrototype(bool value);
 +
 +  /**
 +   * Returns true if the given object is an instance of this function
 +   * template.
 +   */
 +  bool HasInstance(Handle<Value> object);
 +
 + private:
 +  FunctionTemplate();
 +  void AddInstancePropertyAccessor(Handle<String> name,
 +                                   AccessorGetter getter,
 +                                   AccessorSetter setter,
 +                                   Handle<Value> data,
 +                                   AccessControl settings,
 +                                   PropertyAttribute attributes);
 +  void SetNamedInstancePropertyHandler(NamedPropertyGetter getter,
 +                                       NamedPropertySetter setter,
 +                                       NamedPropertyQuery query,
 +                                       NamedPropertyDeleter remover,
 +                                       NamedPropertyEnumerator enumerator,
 +                                       Handle<Value> data);
 +  void SetIndexedInstancePropertyHandler(IndexedPropertyGetter getter,
 +                                         IndexedPropertySetter setter,
 +                                         IndexedPropertyQuery query,
 +                                         IndexedPropertyDeleter remover,
 +                                         IndexedPropertyEnumerator enumerator,
 +                                         Handle<Value> data);
 +  void SetInstanceCallAsFunctionHandler(InvocationCallback callback,
 +                                        Handle<Value> data);
 +
 +  friend class Context;
 +  friend class ObjectTemplate;
 +};
 +
 +
 +/**
 + * An ObjectTemplate is used to create objects at runtime.
 + *
 + * Properties added to an ObjectTemplate are added to each object
 + * created from the ObjectTemplate.
 + */
 +class V8EXPORT ObjectTemplate : public Template {
 + public:
 +  /** Creates an ObjectTemplate. */
 +  static Local<ObjectTemplate> New();
 +
 +  /** Creates a new instance of this template.*/
 +  Local<Object> NewInstance();
 +
 +  /**
 +   * Sets an accessor on the object template.
 +   *
 +   * Whenever the property with the given name is accessed on objects
 +   * created from this ObjectTemplate the getter and setter callbacks
 +   * are called instead of getting and setting the property directly
 +   * on the JavaScript object.
 +   *
 +   * \param name The name of the property for which an accessor is added.
 +   * \param getter The callback to invoke when getting the property.
 +   * \param setter The callback to invoke when setting the property.
 +   * \param data A piece of data that will be passed to the getter and setter
 +   *   callbacks whenever they are invoked.
 +   * \param settings Access control settings for the accessor. This is a bit
 +   *   field consisting of one of more of
 +   *   DEFAULT = 0, ALL_CAN_READ = 1, or ALL_CAN_WRITE = 2.
 +   *   The default is to not allow cross-context access.
 +   *   ALL_CAN_READ means that all cross-context reads are allowed.
 +   *   ALL_CAN_WRITE means that all cross-context writes are allowed.
 +   *   The combination ALL_CAN_READ | ALL_CAN_WRITE can be used to allow all
 +   *   cross-context access.
 +   * \param attribute The attributes of the property for which an accessor
 +   *   is added.
 +   */
 +  void SetAccessor(Handle<String> name,
 +                   AccessorGetter getter,
 +                   AccessorSetter setter = 0,
 +                   Handle<Value> data = Handle<Value>(),
 +                   AccessControl settings = DEFAULT,
 +                   PropertyAttribute attribute = None);
 +
 +  /**
 +   * Sets a named property handler on the object template.
 +   *
 +   * Whenever a named property is accessed on objects created from
 +   * this object template, the provided callback is invoked instead of
 +   * accessing the property directly on the JavaScript object.
 +   *
 +   * \param getter The callback to invoke when getting a property.
 +   * \param setter The callback to invoke when setting a property.
 +   * \param query The callback to invoke to check if a property is present,
 +   *   and if present, get its attributes.
 +   * \param deleter The callback to invoke when deleting a property.
 +   * \param enumerator The callback to invoke to enumerate all the named
 +   *   properties of an object.
 +   * \param data A piece of data that will be passed to the callbacks
 +   *   whenever they are invoked.
 +   */
 +  void SetNamedPropertyHandler(NamedPropertyGetter getter,
 +                               NamedPropertySetter setter = 0,
 +                               NamedPropertyQuery query = 0,
 +                               NamedPropertyDeleter deleter = 0,
 +                               NamedPropertyEnumerator enumerator = 0,
 +                               Handle<Value> data = Handle<Value>());
 +
 +  /**
 +   * Sets an indexed property handler on the object template.
 +   *
 +   * Whenever an indexed property is accessed on objects created from
 +   * this object template, the provided callback is invoked instead of
 +   * accessing the property directly on the JavaScript object.
 +   *
 +   * \param getter The callback to invoke when getting a property.
 +   * \param setter The callback to invoke when setting a property.
 +   * \param query The callback to invoke to check is an object has a property.
 +   * \param deleter The callback to invoke when deleting a property.
 +   * \param enumerator The callback to invoke to enumerate all the indexed
 +   *   properties of an object.
 +   * \param data A piece of data that will be passed to the callbacks
 +   *   whenever they are invoked.
 +   */
 +  void SetIndexedPropertyHandler(IndexedPropertyGetter getter,
 +                                 IndexedPropertySetter setter = 0,
 +                                 IndexedPropertyQuery query = 0,
 +                                 IndexedPropertyDeleter deleter = 0,
 +                                 IndexedPropertyEnumerator enumerator = 0,
 +                                 Handle<Value> data = Handle<Value>());
 +
 +  /**
 +   * Sets the callback to be used when calling instances created from
 +   * this template as a function.  If no callback is set, instances
 +   * behave like normal JavaScript objects that cannot be called as a
 +   * function.
 +   */
 +  void SetCallAsFunctionHandler(InvocationCallback callback,
 +                                Handle<Value> data = Handle<Value>());
 +
 +  /**
 +   * Mark object instances of the template as undetectable.
 +   *
 +   * In many ways, undetectable objects behave as though they are not
 +   * there.  They behave like 'undefined' in conditionals and when
 +   * printed.  However, properties can be accessed and called as on
 +   * normal objects.
 +   */
 +  void MarkAsUndetectable();
 +
 +  /**
 +   * Sets access check callbacks on the object template.
 +   *
 +   * When accessing properties on instances of this object template,
 +   * the access check callback will be called to determine whether or
 +   * not to allow cross-context access to the properties.
 +   * The last parameter specifies whether access checks are turned
 +   * on by default on instances. If access checks are off by default,
 +   * they can be turned on on individual instances by calling
 +   * Object::TurnOnAccessCheck().
 +   */
 +  void SetAccessCheckCallbacks(NamedSecurityCallback named_handler,
 +                               IndexedSecurityCallback indexed_handler,
 +                               Handle<Value> data = Handle<Value>(),
 +                               bool turned_on_by_default = true);
 +
 +  /**
 +   * Gets the number of internal fields for objects generated from
 +   * this template.
 +   */
 +  int InternalFieldCount();
 +
 +  /**
 +   * Sets the number of internal fields for objects generated from
 +   * this template.
 +   */
 +  void SetInternalFieldCount(int value);
 +
 + private:
 +  ObjectTemplate();
 +  static Local<ObjectTemplate> New(Handle<FunctionTemplate> constructor);
 +  friend class FunctionTemplate;
 +};
 +
 +
 +/**
 + * A Signature specifies which receivers and arguments a function can
 + * legally be called with.
 + */
 +class V8EXPORT Signature : public Data {
 + public:
 +  static Local<Signature> New(Handle<FunctionTemplate> receiver =
 +                                  Handle<FunctionTemplate>(),
 +                              int argc = 0,
 +                              Handle<FunctionTemplate> argv[] = 0);
 + private:
 +  Signature();
 +};
 +
 +
 +/**
 + * A utility for determining the type of objects based on the template
 + * they were constructed from.
 + */
 +class V8EXPORT TypeSwitch : public Data {
 + public:
 +  static Local<TypeSwitch> New(Handle<FunctionTemplate> type);
 +  static Local<TypeSwitch> New(int argc, Handle<FunctionTemplate> types[]);
 +  int match(Handle<Value> value);
 + private:
 +  TypeSwitch();
 +};
 +
 +
 +// --- E x t e n s i o n s ---
 +
 +
 +/**
 + * Ignore
 + */
 +class V8EXPORT Extension {  // NOLINT
 + public:
 +  Extension(const char* name,
 +            const char* source = 0,
 +            int dep_count = 0,
 +            const char** deps = 0);
 +  virtual ~Extension() { }
 +  virtual v8::Handle<v8::FunctionTemplate>
 +      GetNativeFunction(v8::Handle<v8::String> name) {
 +    return v8::Handle<v8::FunctionTemplate>();
 +  }
 +
 +  const char* name() { return name_; }
 +  const char* source() { return source_; }
 +  int dependency_count() { return dep_count_; }
 +  const char** dependencies() { return deps_; }
 +  void set_auto_enable(bool value) { auto_enable_ = value; }
 +  bool auto_enable() { return auto_enable_; }
 +
 + private:
 +  const char* name_;
 +  const char* source_;
 +  int dep_count_;
 +  const char** deps_;
 +  bool auto_enable_;
 +
 +  // Disallow copying and assigning.
 +  Extension(const Extension&);
 +  void operator=(const Extension&);
 +};
 +
 +
 +void V8EXPORT RegisterExtension(Extension* extension);
 +
 +
 +/**
 + * Ignore
 + */
 +class V8EXPORT DeclareExtension {
 + public:
 +  inline DeclareExtension(Extension* extension) {
 +    RegisterExtension(extension);
 +  }
 +};
 +
 +
 +// --- S t a t i c s ---
 +
 +
 +Handle<Primitive> V8EXPORT Undefined();
 +Handle<Primitive> V8EXPORT Null();
 +Handle<Boolean> V8EXPORT True();
 +Handle<Boolean> V8EXPORT False();
 +
 +
 +/**
 + * A set of constraints that specifies the limits of the runtime's memory use.
 + * You must set the heap size before initializing the VM - the size cannot be
 + * adjusted after the VM is initialized.
 + *
 + * If you are using threads then you should hold the V8::Locker lock while
 + * setting the stack limit and you must set a non-default stack limit separately
 + * for each thread.
 + */
 +class V8EXPORT ResourceConstraints {
 + public:
 +  ResourceConstraints();
 +  int max_young_space_size() const { return max_young_space_size_; }
 +  void set_max_young_space_size(int value) { max_young_space_size_ = value; }
 +  int max_old_space_size() const { return max_old_space_size_; }
 +  void set_max_old_space_size(int value) { max_old_space_size_ = value; }
 +  uint32_t* stack_limit() const { return stack_limit_; }
 +  // Sets an address beyond which the VM's stack may not grow.
 +  void set_stack_limit(uint32_t* value) { stack_limit_ = value; }
 + private:
 +  int max_young_space_size_;
 +  int max_old_space_size_;
 +  uint32_t* stack_limit_;
 +};
 +
 +
 +bool V8EXPORT SetResourceConstraints(ResourceConstraints* constraints);
 +
 +
 +// --- E x c e p t i o n s ---
 +
 +
 +typedef void (*FatalErrorCallback)(const char* location, const char* message);
 +
 +
 +typedef void (*MessageCallback)(Handle<Message> message, Handle<Value> data);
 +
 +
 +/**
 + * Schedules an exception to be thrown when returning to JavaScript.  When an
 + * exception has been scheduled it is illegal to invoke any JavaScript
 + * operation; the caller must return immediately and only after the exception
 + * has been handled does it become legal to invoke JavaScript operations.
 + */
 +Handle<Value> V8EXPORT ThrowException(Handle<Value> exception);
 +
 +/**
 + * Create new error objects by calling the corresponding error object
 + * constructor with the message.
 + */
 +class V8EXPORT Exception {
 + public:
 +  static Local<Value> RangeError(Handle<String> message);
 +  static Local<Value> ReferenceError(Handle<String> message);
 +  static Local<Value> SyntaxError(Handle<String> message);
 +  static Local<Value> TypeError(Handle<String> message);
 +  static Local<Value> Error(Handle<String> message);
 +};
 +
 +
 +// --- C o u n t e r s  C a l l b a c k s ---
 +
 +typedef int* (*CounterLookupCallback)(const char* name);
 +
 +typedef void* (*CreateHistogramCallback)(const char* name,
 +                                         int min,
 +                                         int max,
 +                                         size_t buckets);
 +
 +typedef void (*AddHistogramSampleCallback)(void* histogram, int sample);
 +
 +// --- M e m o r y  A l l o c a t i o n   C a l l b a c k ---
 +  enum ObjectSpace {
 +    kObjectSpaceNewSpace = 1 << 0,
 +    kObjectSpaceOldPointerSpace = 1 << 1,
 +    kObjectSpaceOldDataSpace = 1 << 2,
 +    kObjectSpaceCodeSpace = 1 << 3,
 +    kObjectSpaceMapSpace = 1 << 4,
 +    kObjectSpaceLoSpace = 1 << 5,
 +
 +    kObjectSpaceAll = kObjectSpaceNewSpace | kObjectSpaceOldPointerSpace |
 +      kObjectSpaceOldDataSpace | kObjectSpaceCodeSpace | kObjectSpaceMapSpace |
 +      kObjectSpaceLoSpace
 +  };
 +
 +  enum AllocationAction {
 +    kAllocationActionAllocate = 1 << 0,
 +    kAllocationActionFree = 1 << 1,
 +    kAllocationActionAll = kAllocationActionAllocate | kAllocationActionFree
 +  };
 +
 +typedef void (*MemoryAllocationCallback)(ObjectSpace space,
 +                                         AllocationAction action,
 +                                         int size);
 +
 +// --- F a i l e d A c c e s s C h e c k C a l l b a c k ---
 +typedef void (*FailedAccessCheckCallback)(Local<Object> target,
 +                                          AccessType type,
 +                                          Local<Value> data);
 +
 +// --- G a r b a g e C o l l e c t i o n  C a l l b a c k s
 +
 +/**
 + * Applications can register callback functions which will be called
 + * before and after a garbage collection.  Allocations are not
 + * allowed in the callback functions, you therefore cannot manipulate
 + * objects (set or delete properties for example) since it is possible
 + * such operations will result in the allocation of objects.
 + */
 +enum GCType {
 +  kGCTypeScavenge = 1 << 0,
 +  kGCTypeMarkSweepCompact = 1 << 1,
 +  kGCTypeAll = kGCTypeScavenge | kGCTypeMarkSweepCompact
 +};
 +
 +enum GCCallbackFlags {
 +  kNoGCCallbackFlags = 0,
 +  kGCCallbackFlagCompacted = 1 << 0
 +};
 +
 +typedef void (*GCPrologueCallback)(GCType type, GCCallbackFlags flags);
 +typedef void (*GCEpilogueCallback)(GCType type, GCCallbackFlags flags);
 +
 +typedef void (*GCCallback)();
 +
 +
 +/**
 + * Profiler modules.
 + *
 + * In V8, profiler consists of several modules: CPU profiler, and different
 + * kinds of heap profiling. Each can be turned on / off independently.
 + * When PROFILER_MODULE_HEAP_SNAPSHOT flag is passed to ResumeProfilerEx,
 + * modules are enabled only temporarily for making a snapshot of the heap.
 + */
 +enum ProfilerModules {
 +  PROFILER_MODULE_NONE            = 0,
 +  PROFILER_MODULE_CPU             = 1,
 +  PROFILER_MODULE_HEAP_STATS      = 1 << 1,
 +  PROFILER_MODULE_JS_CONSTRUCTORS = 1 << 2,
 +  PROFILER_MODULE_HEAP_SNAPSHOT   = 1 << 16
 +};
 +
 +
 +/**
 + * Collection of V8 heap information.
 + *
 + * Instances of this class can be passed to v8::V8::HeapStatistics to
 + * get heap statistics from V8.
 + */
 +class V8EXPORT HeapStatistics {
 + public:
 +  HeapStatistics();
 +  size_t total_heap_size() { return total_heap_size_; }
 +  size_t used_heap_size() { return used_heap_size_; }
 +
 + private:
 +  void set_total_heap_size(size_t size) { total_heap_size_ = size; }
 +  void set_used_heap_size(size_t size) { used_heap_size_ = size; }
 +
 +  size_t total_heap_size_;
 +  size_t used_heap_size_;
 +
 +  friend class V8;
 +};
 +
 +
 +/**
 + * Container class for static utility functions.
 + */
 +class V8EXPORT V8 {
 + public:
 +  /** Set the callback to invoke in case of fatal errors. */
 +  static void SetFatalErrorHandler(FatalErrorCallback that);
 +
 +  /**
 +   * Ignore out-of-memory exceptions.
 +   *
 +   * V8 running out of memory is treated as a fatal error by default.
 +   * This means that the fatal error handler is called and that V8 is
 +   * terminated.
 +   *
 +   * IgnoreOutOfMemoryException can be used to not treat a
 +   * out-of-memory situation as a fatal error.  This way, the contexts
 +   * that did not cause the out of memory problem might be able to
 +   * continue execution.
 +   */
 +  static void IgnoreOutOfMemoryException();
 +
 +  /**
 +   * Check if V8 is dead and therefore unusable.  This is the case after
 +   * fatal errors such as out-of-memory situations.
 +   */
 +  static bool IsDead();
 +
 +  /**
 +   * Adds a message listener.
 +   *
 +   * The same message listener can be added more than once and it that
 +   * case it will be called more than once for each message.
 +   */
 +  static bool AddMessageListener(MessageCallback that,
 +                                 Handle<Value> data = Handle<Value>());
 +
 +  /**
 +   * Remove all message listeners from the specified callback function.
 +   */
 +  static void RemoveMessageListeners(MessageCallback that);
 +
 +  /**
 +   * Tells V8 to capture current stack trace when uncaught exception occurs
 +   * and report it to the message listeners. The option is off by default.
 +   */
 +  static void SetCaptureStackTraceForUncaughtExceptions(
 +      bool capture,
 +      int frame_limit = 10,
 +      StackTrace::StackTraceOptions options = StackTrace::kOverview);
 +
 +  /**
 +   * Sets V8 flags from a string.
 +   */
 +  static void SetFlagsFromString(const char* str, int length);
 +
 +  /**
 +   * Sets V8 flags from the command line.
 +   */
 +  static void SetFlagsFromCommandLine(int* argc,
 +                                      char** argv,
 +                                      bool remove_flags);
 +
 +  /** Get the version string. */
 +  static const char* GetVersion();
 +
 +  /**
 +   * Enables the host application to provide a mechanism for recording
 +   * statistics counters.
 +   */
 +  static void SetCounterFunction(CounterLookupCallback);
 +
 +  /**
 +   * Enables the host application to provide a mechanism for recording
 +   * histograms. The CreateHistogram function returns a
 +   * histogram which will later be passed to the AddHistogramSample
 +   * function.
 +   */
 +  static void SetCreateHistogramFunction(CreateHistogramCallback);
 +  static void SetAddHistogramSampleFunction(AddHistogramSampleCallback);
 +
 +  /**
 +   * Enables the computation of a sliding window of states. The sliding
 +   * window information is recorded in statistics counters.
 +   */
 +  static void EnableSlidingStateWindow();
 +
 +  /** Callback function for reporting failed access checks.*/
 +  static void SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback);
 +
 +  /**
 +   * Enables the host application to receive a notification before a
 +   * garbage collection.  Allocations are not allowed in the
 +   * callback function, you therefore cannot manipulate objects (set
 +   * or delete properties for example) since it is possible such
 +   * operations will result in the allocation of objects. It is possible
 +   * to specify the GCType filter for your callback. But it is not possible to
 +   * register the same callback function two times with different
 +   * GCType filters.
 +   */
 +  static void AddGCPrologueCallback(
 +      GCPrologueCallback callback, GCType gc_type_filter = kGCTypeAll);
 +
 +  /**
 +   * This function removes callback which was installed by
 +   * AddGCPrologueCallback function.
 +   */
 +  static void RemoveGCPrologueCallback(GCPrologueCallback callback);
 +
 +  /**
 +   * The function is deprecated. Please use AddGCPrologueCallback instead.
 +   * Enables the host application to receive a notification before a
 +   * garbage collection.  Allocations are not allowed in the
 +   * callback function, you therefore cannot manipulate objects (set
 +   * or delete properties for example) since it is possible such
 +   * operations will result in the allocation of objects.
 +   */
 +  static void SetGlobalGCPrologueCallback(GCCallback);
 +
 +  /**
 +   * Enables the host application to receive a notification after a
 +   * garbage collection.  Allocations are not allowed in the
 +   * callback function, you therefore cannot manipulate objects (set
 +   * or delete properties for example) since it is possible such
 +   * operations will result in the allocation of objects. It is possible
 +   * to specify the GCType filter for your callback. But it is not possible to
 +   * register the same callback function two times with different
 +   * GCType filters.
 +   */
 +  static void AddGCEpilogueCallback(
 +      GCEpilogueCallback callback, GCType gc_type_filter = kGCTypeAll);
 +
 +  /**
 +   * This function removes callback which was installed by
 +   * AddGCEpilogueCallback function.
 +   */
 +  static void RemoveGCEpilogueCallback(GCEpilogueCallback callback);
 +
 +  /**
 +   * The function is deprecated. Please use AddGCEpilogueCallback instead.
 +   * Enables the host application to receive a notification after a
 +   * major garbage collection.  Allocations are not allowed in the
 +   * callback function, you therefore cannot manipulate objects (set
 +   * or delete properties for example) since it is possible such
 +   * operations will result in the allocation of objects.
 +   */
 +  static void SetGlobalGCEpilogueCallback(GCCallback);
 +
 +  /**
 +   * Enables the host application to provide a mechanism to be notified
 +   * and perform custom logging when V8 Allocates Executable Memory.
 +   */
 +  static void AddMemoryAllocationCallback(MemoryAllocationCallback callback,
 +                                          ObjectSpace space,
 +                                          AllocationAction action);
 +
 +  /**
 +   * This function removes callback which was installed by
 +   * AddMemoryAllocationCallback function.
 +   */
 +  static void RemoveMemoryAllocationCallback(MemoryAllocationCallback callback);
 +
 +  /**
 +   * Allows the host application to group objects together. If one
 +   * object in the group is alive, all objects in the group are alive.
 +   * After each garbage collection, object groups are removed. It is
 +   * intended to be used in the before-garbage-collection callback
 +   * function, for instance to simulate DOM tree connections among JS
 +   * wrapper objects.
 +   */
 +  static void AddObjectGroup(Persistent<Value>* objects, size_t length);
 +
 +  /**
 +   * Initializes from snapshot if possible. Otherwise, attempts to
 +   * initialize from scratch.  This function is called implicitly if
 +   * you use the API without calling it first.
 +   */
 +  static bool Initialize();
 +
 +  /**
 +   * Adjusts the amount of registered external memory.  Used to give
 +   * V8 an indication of the amount of externally allocated memory
 +   * that is kept alive by JavaScript objects.  V8 uses this to decide
 +   * when to perform global garbage collections.  Registering
 +   * externally allocated memory will trigger global garbage
 +   * collections more often than otherwise in an attempt to garbage
 +   * collect the JavaScript objects keeping the externally allocated
 +   * memory alive.
 +   *
 +   * \param change_in_bytes the change in externally allocated memory
 +   *   that is kept alive by JavaScript objects.
 +   * \returns the adjusted value.
 +   */
 +  static int AdjustAmountOfExternalAllocatedMemory(int change_in_bytes);
 +
 +  /**
 +   * Suspends recording of tick samples in the profiler.
 +   * When the V8 profiling mode is enabled (usually via command line
 +   * switches) this function suspends recording of tick samples.
 +   * Profiling ticks are discarded until ResumeProfiler() is called.
 +   *
 +   * See also the --prof and --prof_auto command line switches to
 +   * enable V8 profiling.
 +   */
 +  static void PauseProfiler();
 +
 +  /**
 +   * Resumes recording of tick samples in the profiler.
 +   * See also PauseProfiler().
 +   */
 +  static void ResumeProfiler();
 +
 +  /**
 +   * Return whether profiler is currently paused.
 +   */
 +  static bool IsProfilerPaused();
 +
 +  /**
 +   * Resumes specified profiler modules. Can be called several times to
 +   * mark the opening of a profiler events block with the given tag.
 +   *
 +   * "ResumeProfiler" is equivalent to "ResumeProfilerEx(PROFILER_MODULE_CPU)".
 +   * See ProfilerModules enum.
 +   *
 +   * \param flags Flags specifying profiler modules.
 +   * \param tag Profile tag.
 +   */
 +  static void ResumeProfilerEx(int flags, int tag = 0);
 +
 +  /**
 +   * Pauses specified profiler modules. Each call to "PauseProfilerEx" closes
 +   * a block of profiler events opened by a call to "ResumeProfilerEx" with the
 +   * same tag value. There is no need for blocks to be properly nested.
 +   * The profiler is paused when the last opened block is closed.
 +   *
 +   * "PauseProfiler" is equivalent to "PauseProfilerEx(PROFILER_MODULE_CPU)".
 +   * See ProfilerModules enum.
 +   *
 +   * \param flags Flags specifying profiler modules.
 +   * \param tag Profile tag.
 +   */
 +  static void PauseProfilerEx(int flags, int tag = 0);
 +
 +  /**
 +   * Returns active (resumed) profiler modules.
 +   * See ProfilerModules enum.
 +   *
 +   * \returns active profiler modules.
 +   */
 +  static int GetActiveProfilerModules();
 +
 +  /**
 +   * If logging is performed into a memory buffer (via --logfile=*), allows to
 +   * retrieve previously written messages. This can be used for retrieving
 +   * profiler log data in the application. This function is thread-safe.
 +   *
 +   * Caller provides a destination buffer that must exist during GetLogLines
 +   * call. Only whole log lines are copied into the buffer.
 +   *
 +   * \param from_pos specified a point in a buffer to read from, 0 is the
 +   *   beginning of a buffer. It is assumed that caller updates its current
 +   *   position using returned size value from the previous call.
 +   * \param dest_buf destination buffer for log data.
 +   * \param max_size size of the destination buffer.
 +   * \returns actual size of log data copied into buffer.
 +   */
 +  static int GetLogLines(int from_pos, char* dest_buf, int max_size);
 +
 +  /**
 +   * The minimum allowed size for a log lines buffer.  If the size of
 +   * the buffer given will not be enough to hold a line of the maximum
 +   * length, an attempt to find a log line end in GetLogLines will
 +   * fail, and an empty result will be returned.
 +   */
 +  static const int kMinimumSizeForLogLinesBuffer = 2048;
 +
 +  /**
 +   * Retrieve the V8 thread id of the calling thread.
 +   *
 +   * The thread id for a thread should only be retrieved after the V8
 +   * lock has been acquired with a Locker object with that thread.
 +   */
 +  static int GetCurrentThreadId();
 +
 +  /**
 +   * Forcefully terminate execution of a JavaScript thread.  This can
 +   * be used to terminate long-running scripts.
 +   *
 +   * TerminateExecution should only be called when then V8 lock has
 +   * been acquired with a Locker object.  Therefore, in order to be
 +   * able to terminate long-running threads, preemption must be
 +   * enabled to allow the user of TerminateExecution to acquire the
 +   * lock.
 +   *
 +   * The termination is achieved by throwing an exception that is
 +   * uncatchable by JavaScript exception handlers.  Termination
 +   * exceptions act as if they were caught by a C++ TryCatch exception
 +   * handlers.  If forceful termination is used, any C++ TryCatch
 +   * exception handler that catches an exception should check if that
 +   * exception is a termination exception and immediately return if
 +   * that is the case.  Returning immediately in that case will
 +   * continue the propagation of the termination exception if needed.
 +   *
 +   * The thread id passed to TerminateExecution must have been
 +   * obtained by calling GetCurrentThreadId on the thread in question.
 +   *
 +   * \param thread_id The thread id of the thread to terminate.
 +   */
 +  static void TerminateExecution(int thread_id);
 +
 +  /**
 +   * Forcefully terminate the current thread of JavaScript execution.
 +   *
 +   * This method can be used by any thread even if that thread has not
 +   * acquired the V8 lock with a Locker object.
 +   */
 +  static void TerminateExecution();
 +
 +  /**
 +   * Is V8 terminating JavaScript execution.
 +   *
 +   * Returns true if JavaScript execution is currently terminating
 +   * because of a call to TerminateExecution.  In that case there are
 +   * still JavaScript frames on the stack and the termination
 +   * exception is still active.
 +   */
 +  static bool IsExecutionTerminating();
 +
 +  /**
 +   * Releases any resources used by v8 and stops any utility threads
 +   * that may be running.  Note that disposing v8 is permanent, it
 +   * cannot be reinitialized.
 +   *
 +   * It should generally not be necessary to dispose v8 before exiting
 +   * a process, this should happen automatically.  It is only necessary
 +   * to use if the process needs the resources taken up by v8.
 +   */
 +  static bool Dispose();
 +
 +  /**
 +   * Get statistics about the heap memory usage.
 +   */
 +  static void GetHeapStatistics(HeapStatistics* heap_statistics);
 +
 +  /**
 +   * Optional notification that the embedder is idle.
 +   * V8 uses the notification to reduce memory footprint.
 +   * This call can be used repeatedly if the embedder remains idle.
 +   * Returns true if the embedder should stop calling IdleNotification
 +   * until real work has been done.  This indicates that V8 has done
 +   * as much cleanup as it will be able to do.
 +   */
 +  static bool IdleNotification();
 +
 +  /**
 +   * Optional notification that the system is running low on memory.
 +   * V8 uses these notifications to attempt to free memory.
 +   */
 +  static void LowMemoryNotification();
 +
 +  /**
 +   * Optional notification that a context has been disposed. V8 uses
 +   * these notifications to guide the GC heuristic. Returns the number
 +   * of context disposals - including this one - since the last time
 +   * V8 had a chance to clean up.
 +   */
 +  static int ContextDisposedNotification();
 +
 + private:
 +  V8();
 +
 +  static internal::Object** GlobalizeReference(internal::Object** handle);
 +  static void DisposeGlobal(internal::Object** global_handle);
 +  static void MakeWeak(internal::Object** global_handle,
 +                       void* data,
 +                       WeakReferenceCallback);
 +  static void ClearWeak(internal::Object** global_handle);
 +  static bool IsGlobalNearDeath(internal::Object** global_handle);
 +  static bool IsGlobalWeak(internal::Object** global_handle);
 +
 +  template <class T> friend class Handle;
 +  template <class T> friend class Local;
 +  template <class T> friend class Persistent;
 +  friend class Context;
 +};
 +
 +
 +/**
 + * An external exception handler.
 + */
 +class V8EXPORT TryCatch {
 + public:
 +
 +  /**
 +   * Creates a new try/catch block and registers it with v8.
 +   */
 +  TryCatch();
 +
 +  /**
 +   * Unregisters and deletes this try/catch block.
 +   */
 +  ~TryCatch();
 +
 +  /**
 +   * Returns true if an exception has been caught by this try/catch block.
 +   */
 +  bool HasCaught() const;
 +
 +  /**
 +   * For certain types of exceptions, it makes no sense to continue
 +   * execution.
 +   *
 +   * Currently, the only type of exception that can be caught by a
 +   * TryCatch handler and for which it does not make sense to continue
 +   * is termination exception.  Such exceptions are thrown when the
 +   * TerminateExecution methods are called to terminate a long-running
 +   * script.
 +   *
 +   * If CanContinue returns false, the correct action is to perform
 +   * any C++ cleanup needed and then return.
 +   */
 +  bool CanContinue() const;
 +
 +  /**
 +   * Throws the exception caught by this TryCatch in a way that avoids
 +   * it being caught again by this same TryCatch.  As with ThrowException
 +   * it is illegal to execute any JavaScript operations after calling
 +   * ReThrow; the caller must return immediately to where the exception
 +   * is caught.
 +   */
 +  Handle<Value> ReThrow();
 +
 +  /**
 +   * Returns the exception caught by this try/catch block.  If no exception has
 +   * been caught an empty handle is returned.
 +   *
 +   * The returned handle is valid until this TryCatch block has been destroyed.
 +   */
 +  Local<Value> Exception() const;
 +
 +  /**
 +   * Returns the .stack property of the thrown object.  If no .stack
 +   * property is present an empty handle is returned.
 +   */
 +  Local<Value> StackTrace() const;
 +
 +  /**
 +   * Returns the message associated with this exception.  If there is
 +   * no message associated an empty handle is returned.
 +   *
 +   * The returned handle is valid until this TryCatch block has been
 +   * destroyed.
 +   */
 +  Local<v8::Message> Message() const;
 +
 +  /**
 +   * Clears any exceptions that may have been caught by this try/catch block.
 +   * After this method has been called, HasCaught() will return false.
 +   *
 +   * It is not necessary to clear a try/catch block before using it again; if
 +   * another exception is thrown the previously caught exception will just be
 +   * overwritten.  However, it is often a good idea since it makes it easier
 +   * to determine which operation threw a given exception.
 +   */
 +  void Reset();
 +
 +  /**
 +   * Set verbosity of the external exception handler.
 +   *
 +   * By default, exceptions that are caught by an external exception
 +   * handler are not reported.  Call SetVerbose with true on an
 +   * external exception handler to have exceptions caught by the
 +   * handler reported as if they were not caught.
 +   */
 +  void SetVerbose(bool value);
 +
 +  /**
 +   * Set whether or not this TryCatch should capture a Message object
 +   * which holds source information about where the exception
 +   * occurred.  True by default.
 +   */
 +  void SetCaptureMessage(bool value);
 +
 + private:
 +  void* next_;
 +  void* exception_;
 +  void* message_;
 +  bool is_verbose_ : 1;
 +  bool can_continue_ : 1;
 +  bool capture_message_ : 1;
 +  bool rethrow_ : 1;
 +
 +  friend class v8::internal::Top;
 +};
 +
 +
 +// --- C o n t e x t ---
 +
 +
 +/**
 + * Ignore
 + */
 +class V8EXPORT ExtensionConfiguration {
 + public:
 +  ExtensionConfiguration(int name_count, const char* names[])
 +      : name_count_(name_count), names_(names) { }
 + private:
 +  friend class ImplementationUtilities;
 +  int name_count_;
 +  const char** names_;
 +};
 +
 +
 +/**
 + * A sandboxed execution context with its own set of built-in objects
 + * and functions.
 + */
 +class V8EXPORT Context {
 + public:
 +  /** Returns the global object of the context. */
 +  Local<Object> Global();
 +
 +  /**
 +   * Detaches the global object from its context before
 +   * the global object can be reused to create a new context.
 +   */
 +  void DetachGlobal();
 +
 +  /**
 +   * Reattaches a global object to a context.  This can be used to
 +   * restore the connection between a global object and a context
 +   * after DetachGlobal has been called.
 +   *
 +   * \param global_object The global object to reattach to the
 +   *   context.  For this to work, the global object must be the global
 +   *   object that was associated with this context before a call to
 +   *   DetachGlobal.
 +   */
 +  void ReattachGlobal(Handle<Object> global_object);
 +
 +  /** Creates a new context.
 +   *
 +   * Returns a persistent handle to the newly allocated context. This
 +   * persistent handle has to be disposed when the context is no
 +   * longer used so the context can be garbage collected.
 +   */
 +  static Persistent<Context> New(
 +      ExtensionConfiguration* extensions = NULL,
 +      Handle<ObjectTemplate> global_template = Handle<ObjectTemplate>(),
 +      Handle<Value> global_object = Handle<Value>());
 +
 +  /** Returns the last entered context. */
 +  static Local<Context> GetEntered();
 +
 +  /** Returns the context that is on the top of the stack. */
 +  static Local<Context> GetCurrent();
 +
 +  /**
 +   * Returns the context of the calling JavaScript code.  That is the
 +   * context of the top-most JavaScript frame.  If there are no
 +   * JavaScript frames an empty handle is returned.
 +   */
 +  static Local<Context> GetCalling();
 +
 +  /**
 +   * Sets the security token for the context.  To access an object in
 +   * another context, the security tokens must match.
 +   */
 +  void SetSecurityToken(Handle<Value> token);
 +
 +  /** Restores the security token to the default value. */
 +  void UseDefaultSecurityToken();
 +
 +  /** Returns the security token of this context.*/
 +  Handle<Value> GetSecurityToken();
 +
 +  /**
 +   * Enter this context.  After entering a context, all code compiled
 +   * and run is compiled and run in this context.  If another context
 +   * is already entered, this old context is saved so it can be
 +   * restored when the new context is exited.
 +   */
 +  void Enter();
 +
 +  /**
 +   * Exit this context.  Exiting the current context restores the
 +   * context that was in place when entering the current context.
 +   */
 +  void Exit();
 +
 +  /** Returns true if the context has experienced an out of memory situation. */
 +  bool HasOutOfMemoryException();
 +
 +  /** Returns true if V8 has a current context. */
 +  static bool InContext();
 +
 +  /**
 +   * Associate an additional data object with the context. This is mainly used
 +   * with the debugger to provide additional information on the context through
 +   * the debugger API.
 +   */
 +  void SetData(Handle<String> data);
 +  Local<Value> GetData();
 +
 +  /**
 +   * Stack-allocated class which sets the execution context for all
 +   * operations executed within a local scope.
 +   */
 +  class Scope {
 +   public:
 +    inline Scope(Handle<Context> context) : context_(context) {
 +      context_->Enter();
 +    }
 +    inline ~Scope() { context_->Exit(); }
 +   private:
 +    Handle<Context> context_;
 +  };
 +
 + private:
 +  friend class Value;
 +  friend class Script;
 +  friend class Object;
 +  friend class Function;
 +};
 +
 +
 +/**
 + * Multiple threads in V8 are allowed, but only one thread at a time
 + * is allowed to use V8.  The definition of 'using V8' includes
 + * accessing handles or holding onto object pointers obtained from V8
 + * handles.  It is up to the user of V8 to ensure (perhaps with
 + * locking) that this constraint is not violated.
 + *
 + * If you wish to start using V8 in a thread you can do this by constructing
 + * a v8::Locker object.  After the code using V8 has completed for the
 + * current thread you can call the destructor.  This can be combined
 + * with C++ scope-based construction as follows:
 + *
 + * \code
 + * ...
 + * {
 + *   v8::Locker locker;
 + *   ...
 + *   // Code using V8 goes here.
 + *   ...
 + * } // Destructor called here
 + * \endcode
 + *
 + * If you wish to stop using V8 in a thread A you can do this by either
 + * by destroying the v8::Locker object as above or by constructing a
 + * v8::Unlocker object:
 + *
 + * \code
 + * {
 + *   v8::Unlocker unlocker;
 + *   ...
 + *   // Code not using V8 goes here while V8 can run in another thread.
 + *   ...
 + * } // Destructor called here.
 + * \endcode
 + *
 + * The Unlocker object is intended for use in a long-running callback
 + * from V8, where you want to release the V8 lock for other threads to
 + * use.
 + *
 + * The v8::Locker is a recursive lock.  That is, you can lock more than
 + * once in a given thread.  This can be useful if you have code that can
 + * be called either from code that holds the lock or from code that does
 + * not.  The Unlocker is not recursive so you can not have several
 + * Unlockers on the stack at once, and you can not use an Unlocker in a
 + * thread that is not inside a Locker's scope.
 + *
 + * An unlocker will unlock several lockers if it has to and reinstate
 + * the correct depth of locking on its destruction. eg.:
 + *
 + * \code
 + * // V8 not locked.
 + * {
 + *   v8::Locker locker;
 + *   // V8 locked.
 + *   {
 + *     v8::Locker another_locker;
 + *     // V8 still locked (2 levels).
 + *     {
 + *       v8::Unlocker unlocker;
 + *       // V8 not locked.
 + *     }
 + *     // V8 locked again (2 levels).
 + *   }
 + *   // V8 still locked (1 level).
 + * }
 + * // V8 Now no longer locked.
 + * \endcode
 + */
 +class V8EXPORT Unlocker {
 + public:
 +  Unlocker();
 +  ~Unlocker();
 +};
 +
 +
 +class V8EXPORT Locker {
 + public:
 +  Locker();
 +  ~Locker();
 +
 +  /**
 +   * Start preemption.
 +   *
 +   * When preemption is started, a timer is fired every n milli seconds
 +   * that will switch between multiple threads that are in contention
 +   * for the V8 lock.
 +   */
 +  static void StartPreemption(int every_n_ms);
 +
 +  /**
 +   * Stop preemption.
 +   */
 +  static void StopPreemption();
 +
 +  /**
 +   * Returns whether or not the locker is locked by the current thread.
 +   */
 +  static bool IsLocked();
 +
 +  /**
 +   * Returns whether v8::Locker is being used by this V8 instance.
 +   */
 +  static bool IsActive() { return active_; }
 +
 + private:
 +  bool has_lock_;
 +  bool top_level_;
 +
 +  static bool active_;
 +
 +  // Disallow copying and assigning.
 +  Locker(const Locker&);
 +  void operator=(const Locker&);
 +};
 +
 +
 +/**
 + * An interface for exporting data from V8, using "push" model.
 + */
 +class V8EXPORT OutputStream {
 +public:
 +  enum OutputEncoding {
 +    kAscii = 0  // 7-bit ASCII.
 +  };
 +  enum WriteResult {
 +    kContinue = 0,
 +    kAbort = 1
 +  };
 +  virtual ~OutputStream() {}
 +  /** Notify about the end of stream. */
 +  virtual void EndOfStream() = 0;
 +  /** Get preferred output chunk size. Called only once. */
 +  virtual int GetChunkSize() { return 1024; }
 +  /** Get preferred output encoding. Called only once. */
 +  virtual OutputEncoding GetOutputEncoding() { return kAscii; }
 +  /**
 +   * Writes the next chunk of snapshot data into the stream. Writing
 +   * can be stopped by returning kAbort as function result. EndOfStream
 +   * will not be called in case writing was aborted.
 +   */
 +  virtual WriteResult WriteAsciiChunk(char* data, int size) = 0;
 +};
 +
 +
 +
 +// --- I m p l e m e n t a t i o n ---
 +
 +
 +namespace internal {
 +
 +
 +// Tag information for HeapObject.
 +const int kHeapObjectTag = 1;
 +const int kHeapObjectTagSize = 2;
 +const intptr_t kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1;
 +
 +// Tag information for Smi.
 +const int kSmiTag = 0;
 +const int kSmiTagSize = 1;
 +const intptr_t kSmiTagMask = (1 << kSmiTagSize) - 1;
 +
 +template <size_t ptr_size> struct SmiConstants;
 +
 +// Smi constants for 32-bit systems.
 +template <> struct SmiConstants<4> {
 +  static const int kSmiShiftSize = 0;
 +  static const int kSmiValueSize = 31;
 +  static inline int SmiToInt(internal::Object* value) {
 +    int shift_bits = kSmiTagSize + kSmiShiftSize;
 +    // Throw away top 32 bits and shift down (requires >> to be sign extending).
 +    return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> shift_bits;
 +  }
 +};
 +
 +// Smi constants for 64-bit systems.
 +template <> struct SmiConstants<8> {
 +  static const int kSmiShiftSize = 31;
 +  static const int kSmiValueSize = 32;
 +  static inline int SmiToInt(internal::Object* value) {
 +    int shift_bits = kSmiTagSize + kSmiShiftSize;
 +    // Shift down and throw away top 32 bits.
 +    return static_cast<int>(reinterpret_cast<intptr_t>(value) >> shift_bits);
 +  }
 +};
 +
 +const int kSmiShiftSize = SmiConstants<sizeof(void*)>::kSmiShiftSize;
 +const int kSmiValueSize = SmiConstants<sizeof(void*)>::kSmiValueSize;
 +
 +template <size_t ptr_size> struct InternalConstants;
 +
 +// Internal constants for 32-bit systems.
 +template <> struct InternalConstants<4> {
 +  static const int kStringResourceOffset = 3 * sizeof(void*);
 +};
 +
 +// Internal constants for 64-bit systems.
 +template <> struct InternalConstants<8> {
 +  static const int kStringResourceOffset = 3 * sizeof(void*);
 +};
 +
 +/**
 + * This class exports constants and functionality from within v8 that
 + * is necessary to implement inline functions in the v8 api.  Don't
 + * depend on functions and constants defined here.
 + */
 +class Internals {
 + public:
 +
 +  // These values match non-compiler-dependent values defined within
 +  // the implementation of v8.
 +  static const int kHeapObjectMapOffset = 0;
 +  static const int kMapInstanceTypeOffset = sizeof(void*) + sizeof(int);
 +  static const int kStringResourceOffset =
 +      InternalConstants<sizeof(void*)>::kStringResourceOffset;
 +
 +  static const int kProxyProxyOffset = sizeof(void*);
 +  static const int kJSObjectHeaderSize = 3 * sizeof(void*);
 +  static const int kFullStringRepresentationMask = 0x07;
 +  static const int kExternalTwoByteRepresentationTag = 0x02;
 +
 +  static const int kJSObjectType = 0x9f;
 +  static const int kFirstNonstringType = 0x80;
 +  static const int kProxyType = 0x85;
 +
 +  static inline bool HasHeapObjectTag(internal::Object* value) {
 +    return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) ==
 +            kHeapObjectTag);
 +  }
 +
 +  static inline bool HasSmiTag(internal::Object* value) {
 +    return ((reinterpret_cast<intptr_t>(value) & kSmiTagMask) == kSmiTag);
 +  }
 +
 +  static inline int SmiValue(internal::Object* value) {
 +    return SmiConstants<sizeof(void*)>::SmiToInt(value);
 +  }
 +
 +  static inline int GetInstanceType(internal::Object* obj) {
 +    typedef internal::Object O;
 +    O* map = ReadField<O*>(obj, kHeapObjectMapOffset);
 +    return ReadField<uint8_t>(map, kMapInstanceTypeOffset);
 +  }
 +
 +  static inline void* GetExternalPointer(internal::Object* obj) {
 +    if (HasSmiTag(obj)) {
 +      return obj;
 +    } else if (GetInstanceType(obj) == kProxyType) {
 +      return ReadField<void*>(obj, kProxyProxyOffset);
 +    } else {
 +      return NULL;
 +    }
 +  }
 +
 +  static inline bool IsExternalTwoByteString(int instance_type) {
 +    int representation = (instance_type & kFullStringRepresentationMask);
 +    return representation == kExternalTwoByteRepresentationTag;
 +  }
 +
 +  template <typename T>
 +  static inline T ReadField(Object* ptr, int offset) {
 +    uint8_t* addr = reinterpret_cast<uint8_t*>(ptr) + offset - kHeapObjectTag;
 +    return *reinterpret_cast<T*>(addr);
 +  }
 +
 +};
 +
 +}
 +
 +
 +template <class T>
 +Handle<T>::Handle() : val_(0) { }
 +
 +
 +template <class T>
 +Local<T>::Local() : Handle<T>() { }
 +
 +
 +template <class T>
 +Local<T> Local<T>::New(Handle<T> that) {
 +  if (that.IsEmpty()) return Local<T>();
 +  internal::Object** p = reinterpret_cast<internal::Object**>(*that);
 +  return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(*p)));
 +}
 +
 +
 +template <class T>
 +Persistent<T> Persistent<T>::New(Handle<T> that) {
 +  if (that.IsEmpty()) return Persistent<T>();
 +  internal::Object** p = reinterpret_cast<internal::Object**>(*that);
 +  return Persistent<T>(reinterpret_cast<T*>(V8::GlobalizeReference(p)));
 +}
 +
 +
 +template <class T>
 +bool Persistent<T>::IsNearDeath() const {
 +  if (this->IsEmpty()) return false;
 +  return V8::IsGlobalNearDeath(reinterpret_cast<internal::Object**>(**this));
 +}
 +
 +
 +template <class T>
 +bool Persistent<T>::IsWeak() const {
 +  if (this->IsEmpty()) return false;
 +  return V8::IsGlobalWeak(reinterpret_cast<internal::Object**>(**this));
 +}
 +
 +
 +template <class T>
 +void Persistent<T>::Dispose() {
 +  if (this->IsEmpty()) return;
 +  V8::DisposeGlobal(reinterpret_cast<internal::Object**>(**this));
 +}
 +
 +
 +template <class T>
 +Persistent<T>::Persistent() : Handle<T>() { }
 +
 +template <class T>
 +void Persistent<T>::MakeWeak(void* parameters, WeakReferenceCallback callback) {
 +  V8::MakeWeak(reinterpret_cast<internal::Object**>(**this),
 +               parameters,
 +               callback);
 +}
 +
 +template <class T>
 +void Persistent<T>::ClearWeak() {
 +  V8::ClearWeak(reinterpret_cast<internal::Object**>(**this));
 +}
 +
 +
 +Arguments::Arguments(v8::Local<v8::Value> data,
 +                     v8::Local<v8::Object> holder,
 +                     v8::Local<v8::Function> callee,
 +                     bool is_construct_call,
 +                     void** values, int length)
 +    : data_(data), holder_(holder), callee_(callee),
 +      is_construct_call_(is_construct_call),
 +      values_(values), length_(length) { }
 +
 +
 +Local<Value> Arguments::operator[](int i) const {
 +  if (i < 0 || length_ <= i) return Local<Value>(*Undefined());
 +  return Local<Value>(reinterpret_cast<Value*>(values_ - i));
 +}
 +
 +
 +Local<Function> Arguments::Callee() const {
 +  return callee_;
 +}
 +
 +
 +Local<Object> Arguments::This() const {
 +  return Local<Object>(reinterpret_cast<Object*>(values_ + 1));
 +}
 +
 +
 +Local<Object> Arguments::Holder() const {
 +  return holder_;
 +}
 +
 +
 +Local<Value> Arguments::Data() const {
 +  return data_;
 +}
 +
 +
 +bool Arguments::IsConstructCall() const {
 +  return is_construct_call_;
 +}
 +
 +
 +int Arguments::Length() const {
 +  return length_;
 +}
 +
 +
 +template <class T>
 +Local<T> HandleScope::Close(Handle<T> value) {
 +  internal::Object** before = reinterpret_cast<internal::Object**>(*value);
 +  internal::Object** after = RawClose(before);
 +  return Local<T>(reinterpret_cast<T*>(after));
 +}
 +
 +Handle<Value> ScriptOrigin::ResourceName() const {
 +  return resource_name_;
 +}
 +
 +
 +Handle<Integer> ScriptOrigin::ResourceLineOffset() const {
 +  return resource_line_offset_;
 +}
 +
 +
 +Handle<Integer> ScriptOrigin::ResourceColumnOffset() const {
 +  return resource_column_offset_;
 +}
 +
 +
 +Handle<Boolean> Boolean::New(bool value) {
 +  return value ? True() : False();
 +}
 +
 +
 +void Template::Set(const char* name, v8::Handle<Data> value) {
 +  Set(v8::String::New(name), value);
 +}
 +
 +
 +Local<Value> Object::GetInternalField(int index) {
 +#ifndef V8_ENABLE_CHECKS
 +  Local<Value> quick_result = UncheckedGetInternalField(index);
 +  if (!quick_result.IsEmpty()) return quick_result;
 +#endif
 +  return CheckedGetInternalField(index);
 +}
 +
 +
 +Local<Value> Object::UncheckedGetInternalField(int index) {
 +  typedef internal::Object O;
 +  typedef internal::Internals I;
 +  O* obj = *reinterpret_cast<O**>(this);
 +  if (I::GetInstanceType(obj) == I::kJSObjectType) {
 +    // If the object is a plain JSObject, which is the common case,
 +    // we know where to find the internal fields and can return the
 +    // value directly.
 +    int offset = I::kJSObjectHeaderSize + (sizeof(void*) * index);
 +    O* value = I::ReadField<O*>(obj, offset);
 +    O** result = HandleScope::CreateHandle(value);
 +    return Local<Value>(reinterpret_cast<Value*>(result));
 +  } else {
 +    return Local<Value>();
 +  }
 +}
 +
 +
 +void* External::Unwrap(Handle<v8::Value> obj) {
 +#ifdef V8_ENABLE_CHECKS
 +  return FullUnwrap(obj);
 +#else
 +  return QuickUnwrap(obj);
 +#endif
 +}
 +
 +
 +void* External::QuickUnwrap(Handle<v8::Value> wrapper) {
 +  typedef internal::Object O;
 +  O* obj = *reinterpret_cast<O**>(const_cast<v8::Value*>(*wrapper));
 +  return internal::Internals::GetExternalPointer(obj);
 +}
 +
 +
 +void* Object::GetPointerFromInternalField(int index) {
 +  typedef internal::Object O;
 +  typedef internal::Internals I;
 +
 +  O* obj = *reinterpret_cast<O**>(this);
 +
 +  if (I::GetInstanceType(obj) == I::kJSObjectType) {
 +    // If the object is a plain JSObject, which is the common case,
 +    // we know where to find the internal fields and can return the
 +    // value directly.
 +    int offset = I::kJSObjectHeaderSize + (sizeof(void*) * index);
 +    O* value = I::ReadField<O*>(obj, offset);
 +    return I::GetExternalPointer(value);
 +  }
 +
 +  return SlowGetPointerFromInternalField(index);
 +}
 +
 +
 +String* String::Cast(v8::Value* value) {
 +#ifdef V8_ENABLE_CHECKS
 +  CheckCast(value);
 +#endif
 +  return static_cast<String*>(value);
 +}
 +
 +
 +String::ExternalStringResource* String::GetExternalStringResource() const {
 +  typedef internal::Object O;
 +  typedef internal::Internals I;
 +  O* obj = *reinterpret_cast<O**>(const_cast<String*>(this));
 +  String::ExternalStringResource* result;
 +  if (I::IsExternalTwoByteString(I::GetInstanceType(obj))) {
 +    void* value = I::ReadField<void*>(obj, I::kStringResourceOffset);
 +    result = reinterpret_cast<String::ExternalStringResource*>(value);
 +  } else {
 +    result = NULL;
 +  }
 +#ifdef V8_ENABLE_CHECKS
 +  VerifyExternalStringResource(result);
 +#endif
 +  return result;
 +}
 +
 +
 +bool Value::IsString() const {
 +#ifdef V8_ENABLE_CHECKS
 +  return FullIsString();
 +#else
 +  return QuickIsString();
 +#endif
 +}
 +
 +bool Value::QuickIsString() const {
 +  typedef internal::Object O;
 +  typedef internal::Internals I;
 +  O* obj = *reinterpret_cast<O**>(const_cast<Value*>(this));
 +  if (!I::HasHeapObjectTag(obj)) return false;
 +  return (I::GetInstanceType(obj) < I::kFirstNonstringType);
 +}
 +
 +
 +Number* Number::Cast(v8::Value* value) {
 +#ifdef V8_ENABLE_CHECKS
 +  CheckCast(value);
 +#endif
 +  return static_cast<Number*>(value);
 +}
 +
 +
 +Integer* Integer::Cast(v8::Value* value) {
 +#ifdef V8_ENABLE_CHECKS
 +  CheckCast(value);
 +#endif
 +  return static_cast<Integer*>(value);
 +}
 +
 +
 +Date* Date::Cast(v8::Value* value) {
 +#ifdef V8_ENABLE_CHECKS
 +  CheckCast(value);
 +#endif
 +  return static_cast<Date*>(value);
 +}
 +
 +
 +Object* Object::Cast(v8::Value* value) {
 +#ifdef V8_ENABLE_CHECKS
 +  CheckCast(value);
 +#endif
 +  return static_cast<Object*>(value);
 +}
 +
 +
 +Array* Array::Cast(v8::Value* value) {
 +#ifdef V8_ENABLE_CHECKS
 +  CheckCast(value);
 +#endif
 +  return static_cast<Array*>(value);
 +}
 +
 +
 +Function* Function::Cast(v8::Value* value) {
 +#ifdef V8_ENABLE_CHECKS
 +  CheckCast(value);
 +#endif
 +  return static_cast<Function*>(value);
 +}
 +
 +
 +External* External::Cast(v8::Value* value) {
 +#ifdef V8_ENABLE_CHECKS
 +  CheckCast(value);
 +#endif
 +  return static_cast<External*>(value);
 +}
 +
 +
 +Local<Value> AccessorInfo::Data() const {
 +  return Local<Value>(reinterpret_cast<Value*>(&args_[-2]));
 +}
 +
 +
 +Local<Object> AccessorInfo::This() const {
 +  return Local<Object>(reinterpret_cast<Object*>(&args_[0]));
 +}
 +
 +
 +Local<Object> AccessorInfo::Holder() const {
 +  return Local<Object>(reinterpret_cast<Object*>(&args_[-1]));
 +}
 +
 +
 +/**
 + * \example shell.cc
 + * A simple shell that takes a list of expressions on the
 + * command-line and executes them.
 + */
 +
 +
 +/**
 + * \example process.cc
 + */
 +
 +
 +}  // namespace v8
 +
 +
 +#undef V8EXPORT
 +#undef TYPE_CHECK
 +
 +
 +#endif  // V8_H_
 diff --git a/plugins/Skins/libs/v8.lib b/plugins/Skins/libs/v8.lib Binary files differnew file mode 100644 index 0000000000..b7a6809edc --- /dev/null +++ b/plugins/Skins/libs/v8.lib diff --git a/plugins/Skins/libs/v8_g.lib b/plugins/Skins/libs/v8_g.lib Binary files differnew file mode 100644 index 0000000000..007c42932b --- /dev/null +++ b/plugins/Skins/libs/v8_g.lib diff --git a/plugins/Skins/options.cpp b/plugins/Skins/options.cpp new file mode 100644 index 0000000000..086b7cb9eb --- /dev/null +++ b/plugins/Skins/options.cpp @@ -0,0 +1,487 @@ +/* 
 +Copyright (C) 2008 Ricardo Pescuma Domenecci
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt.  If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA.  
 +*/
 +
 +
 +#include "commons.h"
 +
 +#include "options.h"
 +
 +
 +
 +// Prototypes /////////////////////////////////////////////////////////////////////////////////////
 +
 +HANDLE hOptHook = NULL;
 +
 +Options opts;
 +
 +
 +static BOOL CALLBACK SkinOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
 +
 +
 +// Functions //////////////////////////////////////////////////////////////////////////////////////
 +
 +
 +int InitOptionsCallback(WPARAM wParam,LPARAM lParam)
 +{
 +	OPTIONSDIALOGPAGE odp;
 +	ZeroMemory(&odp, sizeof(odp));
 +	odp.cbSize = sizeof(odp);
 +	odp.position = 0;
 +	odp.hInstance = hInst;
 +	odp.pszGroup = "Skins";
 +	odp.pszTab = "Skin";
 +	odp.pfnDlgProc = SkinOptDlgProc;
 +	odp.pszTemplate = MAKEINTRESOURCEA(IDD_SKIN_OPT);
 +	odp.flags = ODPF_BOLDGROUPS;
 +
 +	for(unsigned int i = 0; i < dlgs.size(); i++)
 +	{
 +		MirandaSkinnedDialog * dlg = dlgs[i];
 +		odp.pszTitle = (char *) dlg->getDescription(); // Yeah, yeah, I know...
 +		odp.dwInitParam = (LPARAM) dlg;
 +		CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp);
 +	}
 +
 +	return 0;
 +}
 +
 +
 +void InitOptions()
 +{
 +	LoadOptions();
 +	
 +	hOptHook = HookEvent(ME_OPT_INITIALISE, InitOptionsCallback);
 +}
 +
 +
 +void DeInitOptions()
 +{
 +	UnhookEvent(hOptHook);
 +}
 +
 +
 +void LoadOptions()
 +{
 +}
 +
 +static void GetTextMetric(HFONT hFont, TEXTMETRIC *tm)
 +{
 +	HDC hdc = GetDC(NULL);
 +	HFONT hOldFont = (HFONT) SelectObject(hdc, hFont);
 +	GetTextMetrics(hdc, tm);
 +	SelectObject(hdc, hOldFont);
 +	ReleaseDC(NULL, hdc);
 +}
 +
 +
 +static BOOL ScreenToClient(HWND hWnd, LPRECT lpRect)
 +{
 +	BOOL ret;
 +
 +	POINT pt;
 +
 +	pt.x = lpRect->left;
 +	pt.y = lpRect->top;
 +
 +	ret = ScreenToClient(hWnd, &pt);
 +
 +	if (!ret) return ret;
 +
 +	lpRect->left = pt.x;
 +	lpRect->top = pt.y;
 +
 +
 +	pt.x = lpRect->right;
 +	pt.y = lpRect->bottom;
 +
 +	ret = ScreenToClient(hWnd, &pt);
 +
 +	lpRect->right = pt.x;
 +	lpRect->bottom = pt.y;
 +
 +	return ret;
 +}
 +
 +
 +#define V_SPACE 5
 +#define H_INITIAL_SPACE 10
 +#define MAX_TEXT_SIZE 128
 +
 +static BOOL CALLBACK SkinOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 +{
 +	switch (msg)
 +	{
 +		case WM_INITDIALOG:
 +		{
 +			MirandaSkinnedDialog * dlg = (MirandaSkinnedDialog *) lParam;
 +			_ASSERT(dlg != NULL);
 +			SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) NULL);
 +
 +			std::vector<std::tstring> skins;
 +			getAvaiableSkins(skins, dlg);
 +			for(unsigned int i = 0; i < skins.size(); i++)
 +			{
 +				std::tstring &sk = skins[i];
 +				SendDlgItemMessage(hwndDlg, IDC_SKIN, CB_ADDSTRING, 0, (LONG) skins[i].c_str());
 +			}
 +			SendDlgItemMessage(hwndDlg, IDC_SKIN, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)dlg->getSkinName());
 +
 +			HWND skinOptsLabel = GetDlgItem(hwndDlg, IDC_SKIN_OPTS_L);
 +
 +			SkinOptions *opts = dlg->getOpts();
 +			if (opts == NULL)
 +			{
 +				ShowWindow(skinOptsLabel, SW_HIDE);
 +				ShowScrollBar(hwndDlg, SB_VERT, FALSE);
 +			}
 +			else
 +			{
 +				HWND skinLabel = GetDlgItem(hwndDlg, IDC_SKIN_L);
 +				HWND skinCombo = GetDlgItem(hwndDlg, IDC_SKIN);
 +
 +				RECT labelRc = {0};
 +				GetWindowRect(skinLabel, &labelRc);
 +				ScreenToClient(hwndDlg, &labelRc);
 +				labelRc.left += H_INITIAL_SPACE;
 +
 +				RECT valueRc = {0};
 +				GetWindowRect(skinCombo, &valueRc);
 +				ScreenToClient(hwndDlg, &valueRc);
 +
 +				RECT lineRc = {0};
 +				GetWindowRect(skinOptsLabel, &lineRc);
 +				ScreenToClient(hwndDlg, &lineRc);
 +
 +				HFONT hFont = (HFONT) SendMessage(hwndDlg, WM_GETFONT, 0, 0);
 +				TEXTMETRIC font;
 +				GetTextMetric(hFont, &font);
 +
 +				int lineHeight = max(font.tmHeight, 16) + 4;
 +				int y = lineRc.bottom + V_SPACE;
 +				int id = IDC_SKIN_OPTS_L + 1;
 +
 +				for (unsigned int i = 0; i < opts->getNumOptions(); i++)
 +				{
 +					SkinOption *opt = opts->getOption(i);
 +
 +					switch(opt->getType())
 +					{
 +						case CHECKBOX:
 +						{
 +							HWND chk = CreateWindow(_T("BUTTON"), opt->getDescription(), 
 +									WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_CHECKBOX | BS_AUTOCHECKBOX, 
 +									labelRc.left, y, 
 +									lineRc.right - labelRc.left, 
 +									lineHeight, hwndDlg, (HMENU) id, hInst, NULL);
 +							SendMessage(chk, BM_SETCHECK, opt->getValueCheckbox() ? BST_CHECKED : BST_UNCHECKED, 0);
 +							SendMessage(chk, WM_SETFONT, (WPARAM) hFont, FALSE);
 +
 +							break;
 +						}
 +						case NUMBER:
 +						{
 +							std::tstring tmp = opt->getDescription();
 +							tmp += _T(":");
 +							HWND lbl = CreateWindow(_T("STATIC"), tmp.c_str(), 
 +									WS_CHILD | WS_VISIBLE, 
 +									labelRc.left, y + (lineHeight - font.tmHeight) / 2, 
 +									labelRc.right - labelRc.left, font.tmHeight, 
 +									hwndDlg, (HMENU) id + 2, hInst, NULL);
 +							SendMessage(lbl, WM_SETFONT, (WPARAM) hFont, FALSE);
 +
 +							HWND edit = CreateWindowEx(WS_EX_CLIENTEDGE, _T("EDIT"), _T(""), 
 +									WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL | ES_NUMBER, 
 +									valueRc.left, y, 
 +									(valueRc.right - valueRc.left) / 2, lineHeight, 
 +									hwndDlg, (HMENU) id, hInst, NULL);
 +							SendMessage(edit, WM_SETFONT, (WPARAM) hFont, FALSE);
 +							SendMessage(edit, EM_LIMITTEXT, 10, 0);
 +
 +							HWND spin = CreateWindow(UPDOWN_CLASS, NULL, 
 +									WS_CHILD | WS_VISIBLE | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK, 
 +									valueRc.left, y, 
 +									1, 1, 
 +									hwndDlg, (HMENU) (id + 1), hInst, NULL);
 +							SendMessage(spin, WM_SETFONT, (WPARAM) hFont, FALSE);
 +							SendMessage(spin, UDM_SETBUDDY, (WPARAM) edit, 0);
 +							SendMessage(spin, UDM_SETRANGE, 0, MAKELONG(min(0x7fff, opt->getMax()), max(-0x7fff, min(0x7fff, opt->getMin()))));
 +							SendMessage(spin, UDM_SETPOS, 0, MAKELONG(opt->getValueNumber(), 0));
 +
 +							break;
 +						}
 +						case TEXT:
 +						{
 +							std::tstring tmp = opt->getDescription();
 +							tmp += _T(":");
 +							HWND lbl = CreateWindow(_T("STATIC"), tmp.c_str(), 
 +									WS_CHILD | WS_VISIBLE, 
 +									labelRc.left, y + (lineHeight - font.tmHeight) / 2, 
 +									labelRc.right - labelRc.left, font.tmHeight, 
 +									hwndDlg, (HMENU) id + 1, hInst, NULL);
 +							SendMessage(lbl, WM_SETFONT, (WPARAM) hFont, FALSE);
 +
 +							HWND edit = CreateWindowEx(WS_EX_CLIENTEDGE, _T("EDIT"), _T(""), 
 +									WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 
 +									valueRc.left, y, 
 +									lineRc.right - valueRc.left, lineHeight, 
 +									hwndDlg, (HMENU) id, hInst, NULL);
 +							SendMessage(edit, WM_SETFONT, (WPARAM) hFont, FALSE);
 +							SendMessage(edit, EM_LIMITTEXT, MAX_TEXT_SIZE, 0);
 +
 +							SetWindowText(edit, opt->getValueText());
 +
 +							break;
 +						}
 +					}
 +
 +					id += 3;
 +					y += lineHeight + V_SPACE;
 +				}
 +
 +				RECT rc = {0};
 +				GetClientRect(hwndDlg, &rc);
 +				int avaiable = rc.bottom - rc.top;
 +				int total = y - V_SPACE;
 +				int current = 0;
 +
 +				SCROLLINFO si; 
 +				si.cbSize = sizeof(si); 
 +				si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
 +				si.nMin   = 0; 
 +				si.nMax   = total; 
 +				si.nPage  = avaiable; 
 +				si.nPos   = current; 
 +				SetScrollInfo(hwndDlg, SB_VERT, &si, TRUE); 
 +			}
 +
 +			TranslateDialogDefault(hwndDlg);
 +
 +			SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) dlg);
 +
 +			break;
 +		}
 +
 +		case WM_VSCROLL: 
 +		{ 
 +			if (lParam != 0)
 +				break;
 +
 +			SCROLLINFO si = {0};
 +			si.cbSize = sizeof(si); 
 +			si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS; 
 +			GetScrollInfo(hwndDlg, SB_VERT, &si);
 +
 +			int total = si.nMax;
 +			int avaiable = si.nPage;
 +			int current = si.nPos;
 +
 +			HFONT hFont = (HFONT) SendMessage(hwndDlg, WM_GETFONT, 0, 0);
 +			TEXTMETRIC font;
 +			GetTextMetric(hFont, &font);
 +			int lineHeight = max(font.tmHeight, 16) + 4;
 +
 +			int yDelta;     // yDelta = new_pos - current_pos 
 +			int yNewPos;    // new position 
 + 
 +			switch (LOWORD(wParam)) 
 +			{ 
 +				case SB_PAGEUP: 
 +					yNewPos = current - avaiable / 2; 
 +					break;  
 +				case SB_PAGEDOWN: 
 +					yNewPos = current + avaiable / 2; 
 +					break; 
 +				case SB_LINEUP: 
 +					yNewPos = current - lineHeight; 
 +					break; 
 +				case SB_LINEDOWN: 
 +					yNewPos = current + lineHeight; 
 +					break; 
 +				case SB_THUMBPOSITION: 
 +					yNewPos = HIWORD(wParam); 
 +					break; 
 +				case SB_THUMBTRACK:
 +					yNewPos = HIWORD(wParam); 
 +					break;
 +				default: 
 +					yNewPos = current; 
 +			} 
 +
 +			yNewPos = min(total - avaiable, max(0, yNewPos)); 
 + 
 +			if (yNewPos == current) 
 +				break; 
 + 
 +			yDelta = yNewPos - current; 
 +			current = yNewPos; 
 + 
 +			// Scroll the window. (The system repaints most of the 
 +			// client area when ScrollWindowEx is called; however, it is 
 +			// necessary to call UpdateWindow in order to repaint the 
 +			// rectangle of pixels that were invalidated.) 
 + 
 +			ScrollWindowEx(hwndDlg, 0, -yDelta, (CONST RECT *) NULL, 
 +				(CONST RECT *) NULL, (HRGN) NULL, (LPRECT) NULL, 
 +				/* SW_ERASE | SW_INVALIDATE | */ SW_SCROLLCHILDREN); 
 +			UpdateWindow(hwndDlg); 
 +			InvalidateRect(hwndDlg, NULL, TRUE);
 + 
 +			// Reset the scroll bar. 
 + 
 +			si.fMask  = SIF_POS; 
 +			si.nPos   = current; 
 +			SetScrollInfo(hwndDlg, SB_VERT, &si, TRUE); 
 +
 +			break; 
 +		}
 +
 +		case WM_COMMAND:
 +		{
 +			MirandaSkinnedDialog * dlg = (MirandaSkinnedDialog *) GetWindowLong(hwndDlg, GWL_USERDATA);
 +			if (dlg == NULL)
 +				break;
 +
 +			SkinOptions *opts = dlg->getOpts();
 +
 +			if (LOWORD(wParam) == IDC_SKIN)
 +			{
 +				if (HIWORD(wParam) == CBN_SELCHANGE && (HWND)lParam == GetFocus())
 +				{
 +					SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
 +
 +					// Disable all options
 +					if (opts != NULL)
 +					{
 +						int id = IDC_SKIN_OPTS_L + 1;
 +						for (unsigned int i = 0; i < opts->getNumOptions(); i++)
 +						{
 +							EnableWindow(GetDlgItem(hwndDlg, id), FALSE);
 +							EnableWindow(GetDlgItem(hwndDlg, id+1), FALSE);
 +							EnableWindow(GetDlgItem(hwndDlg, id+2), FALSE);
 +							id += 3;
 +						}
 +					}
 +				}
 +				break;
 +			}
 +
 +			if (opts == NULL)
 +				break;
 +
 +			bool changed = false;
 +			int id = IDC_SKIN_OPTS_L + 1;
 +			for (unsigned int i = 0; i < opts->getNumOptions() && !changed; i++)
 +			{
 +				SkinOption *opt = opts->getOption(i);
 +
 +				if (LOWORD(wParam) == id)
 +				{
 +					switch(opt->getType())
 +					{
 +						case CHECKBOX:
 +						{
 +							changed = true;
 +							break;
 +						}
 +						case NUMBER:
 +						case TEXT:
 +						{
 +							// Don't make apply enabled during buddy set
 +							if (HIWORD(wParam) == EN_CHANGE && (HWND)lParam == GetFocus())
 +								changed = true;
 +							break;
 +						}
 +					}
 +				}
 +
 +				id += 3;
 +			}
 +
 +			if (changed)
 +				SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
 +
 +			break;
 +		}
 +		case WM_NOTIFY:
 +		{
 +			LPNMHDR lpnmhdr = (LPNMHDR) lParam;
 +
 +			if (lpnmhdr->idFrom == 0 && lpnmhdr->code == PSN_APPLY)
 +			{
 +				MirandaSkinnedDialog * dlg = (MirandaSkinnedDialog *) GetWindowLong(hwndDlg, GWL_USERDATA);
 +				if (dlg == NULL)
 +					break;
 +
 +				bool changedSkin = false;
 +
 +				// TODO Correctly handle changing skins
 +				int pos = SendDlgItemMessage(hwndDlg, IDC_SKIN, CB_GETCURSEL, 0, 0);
 +				if (pos != CB_ERR)
 +				{
 +					TCHAR tmp[1024];
 +					GetWindowText(GetDlgItem(hwndDlg, IDC_SKIN), tmp, MAX_REGS(tmp));
 +
 +					changedSkin = (lstrcmp(dlg->getSkinName(), tmp) != 0);
 +
 +					dlg->setSkinName(tmp);
 +				}
 +
 +				SkinOptions *opts = dlg->getOpts();
 +				if (opts != NULL && !changedSkin)
 +				{
 +					int id = IDC_SKIN_OPTS_L + 1;
 +					for (unsigned int i = 0; i < opts->getNumOptions(); i++)
 +					{
 +						SkinOption *opt = opts->getOption(i);
 +
 +						switch(opt->getType())
 +						{
 +							case CHECKBOX:
 +							{
 +								opt->setValueCheckbox(IsDlgButtonChecked(hwndDlg, id) != 0);
 +								break;
 +							}
 +							case NUMBER:
 +							{
 +								opt->setValueNumber(SendDlgItemMessage(hwndDlg, id + 1, UDM_GETPOS, 0, 0));
 +								break;
 +							}
 +							case TEXT:
 +							{
 +								TCHAR tmp[MAX_TEXT_SIZE];
 +								GetDlgItemText(hwndDlg, id, tmp, MAX_TEXT_SIZE);
 +								opt->setValueText(tmp);
 +								break;
 +							}
 +						}
 +
 +						id += 3;
 +					}
 +
 +					dlg->storeToDB(opts);
 +				}
 +
 +				return TRUE;
 +			}
 +			break;
 +		}
 +	}
 +
 +	return 0;
 +}
 diff --git a/plugins/Skins/options.h b/plugins/Skins/options.h new file mode 100644 index 0000000000..7b2616c521 --- /dev/null +++ b/plugins/Skins/options.h @@ -0,0 +1,47 @@ +/* 
 +Copyright (C) 2008 Ricardo Pescuma Domenecci
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt.  If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA.  
 +*/
 +
 +
 +#ifndef __OPTIONS_H__
 +# define __OPTIONS_H__
 +
 +
 +#include <windows.h>
 +
 +
 +struct Options {
 +};
 +
 +extern Options opts;
 +
 +
 +// Initializations needed by options
 +void InitOptions();
 +
 +// Deinitializations needed by options
 +void DeInitOptions();
 +
 +
 +// Loads the options from DB
 +// It don't need to be called, except in some rare cases
 +void LoadOptions();
 +
 +
 +
 +#endif // __OPTIONS_H__
 diff --git a/plugins/Skins/resource.h b/plugins/Skins/resource.h new file mode 100644 index 0000000000..d275032aeb --- /dev/null +++ b/plugins/Skins/resource.h @@ -0,0 +1,22 @@ +//{{NO_DEPENDENCIES}}
 +// Microsoft Visual C++ generated include file.
 +// Used by resource.rc
 +//
 +#define IDD_OPTIONS                     119
 +#define IDD_SKIN_OPT                    119
 +#define IDC_SKIN                        1087
 +#define IDC_SKIN_OPTS_L                 1088
 +#define IDC_SKIN_L                      -1
 +
 +// Next default values for new objects
 +// 
 +#ifdef APSTUDIO_INVOKED
 +#ifndef APSTUDIO_READONLY_SYMBOLS
 +#define _APS_NO_MFC                     1
 +#define _APS_3D_CONTROLS                     1
 +#define _APS_NEXT_RESOURCE_VALUE        128
 +#define _APS_NEXT_COMMAND_VALUE         40005
 +#define _APS_NEXT_CONTROL_VALUE         1089
 +#define _APS_NEXT_SYMED_VALUE           101
 +#endif
 +#endif
 diff --git a/plugins/Skins/resource.rc b/plugins/Skins/resource.rc new file mode 100644 index 0000000000..23698c2c7f --- /dev/null +++ b/plugins/Skins/resource.rc @@ -0,0 +1,111 @@ +// Microsoft Visual C++ generated resource script.
 +//
 +#include "resource.h"
 +
 +#define APSTUDIO_READONLY_SYMBOLS
 +/////////////////////////////////////////////////////////////////////////////
 +//
 +// Generated from the TEXTINCLUDE 2 resource.
 +//
 +#include "resource.h"
 +#include "winresrc.h"
 +
 +/////////////////////////////////////////////////////////////////////////////
 +#undef APSTUDIO_READONLY_SYMBOLS
 +
 +/////////////////////////////////////////////////////////////////////////////
 +// Neutral resources
 +
 +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
 +#ifdef _WIN32
 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
 +#pragma code_page(1252)
 +#endif //_WIN32
 +
 +/////////////////////////////////////////////////////////////////////////////
 +//
 +// Dialog
 +//
 +
 +IDD_SKIN_OPT DIALOGEX 0, 0, 318, 234
 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_VSCROLL
 +EXSTYLE WS_EX_CONTROLPARENT
 +FONT 8, "MS Shell Dlg", 0, 0, 0x1
 +BEGIN
 +    RTEXT           "Skin:",IDC_SKIN_L,14,7,63,11
 +    COMBOBOX        IDC_SKIN,81,5,108,13,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
 +    LTEXT           "Skin options:",IDC_SKIN_OPTS_L,14,26,283,11
 +END
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
 +//
 +// DESIGNINFO
 +//
 +
 +#ifdef APSTUDIO_INVOKED
 +GUIDELINES DESIGNINFO 
 +BEGIN
 +    IDD_SKIN_OPT, DIALOG
 +    BEGIN
 +        LEFTMARGIN, 1
 +        TOPMARGIN, 1
 +        BOTTOMMARGIN, 228
 +    END
 +END
 +#endif    // APSTUDIO_INVOKED
 +
 +#endif    // Neutral resources
 +/////////////////////////////////////////////////////////////////////////////
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
 +// English (Canada) resources
 +
 +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENC)
 +#ifdef _WIN32
 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_CAN
 +#pragma code_page(1252)
 +#endif //_WIN32
 +
 +#ifdef APSTUDIO_INVOKED
 +/////////////////////////////////////////////////////////////////////////////
 +//
 +// TEXTINCLUDE
 +//
 +
 +1 TEXTINCLUDE 
 +BEGIN
 +    "resource.h\0"
 +END
 +
 +2 TEXTINCLUDE 
 +BEGIN
 +    "#include ""resource.h""\r\n"
 +    "#include ""winresrc.h""\r\n"
 +    "\0"
 +END
 +
 +3 TEXTINCLUDE 
 +BEGIN
 +    "\r\n"
 +    "\0"
 +END
 +
 +#endif    // APSTUDIO_INVOKED
 +
 +#endif    // English (Canada) resources
 +/////////////////////////////////////////////////////////////////////////////
 +
 +
 +
 +#ifndef APSTUDIO_INVOKED
 +/////////////////////////////////////////////////////////////////////////////
 +//
 +// Generated from the TEXTINCLUDE 3 resource.
 +//
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
 +#endif    // not APSTUDIO_INVOKED
 +
 diff --git a/plugins/Skins/skins.cpp b/plugins/Skins/skins.cpp new file mode 100644 index 0000000000..f8142045df --- /dev/null +++ b/plugins/Skins/skins.cpp @@ -0,0 +1,968 @@ +/* 
 +Copyright (C) 2008 Ricardo Pescuma Domenecci
 +
 +This is free software; you can redistribute it and/or
 +modify it under the terms of the GNU Library General Public
 +License as published by the Free Software Foundation; either
 +version 2 of the License, or (at your option) any later version.
 +
 +This is distributed in the hope that it will be useful,
 +but WITHOUT ANY WARRANTY; without even the implied warranty of
 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +Library General Public License for more details.
 +
 +You should have received a copy of the GNU Library General Public
 +License along with this file; see the file license.txt. If
 +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 +Boston, MA 02111-1307, USA. 
 +*/
 +
 +#include "commons.h"
 +
 +
 +// Prototypes ///////////////////////////////////////////////////////////////////////////
 +
 +
 +PLUGININFOEX pluginInfo={
 +	sizeof(PLUGININFOEX),
 +#ifdef UNICODE
 +	"Skins (Unicode)",
 +#else
 +	"Skins",
 +#endif
 +	PLUGIN_MAKE_VERSION(0,0,0,5),
 +	"Skins",
 +	"Ricardo Pescuma Domenecci",
 +	"",
 +	"© 2008-2010 Ricardo Pescuma Domenecci",
 +	"http://pescuma.org/miranda/skins",
 +	UNICODE_AWARE,
 +	0,		//doesn't replace anything built-in
 +#ifdef UNICODE
 +	{ 0xde546127, 0x2cdd, 0x48ca, { 0x8a, 0xe5, 0x36, 0x25, 0xe7, 0x24, 0xf2, 0xda } }
 +#else
 +	{ 0x2f630a2a, 0xd8f9, 0x4f81, { 0x8a, 0x4e, 0xce, 0x9a, 0x73, 0x5d, 0xf2, 0xe9 } }
 +#endif
 +};
 +
 +
 +HINSTANCE hInst;
 +PLUGINLINK *pluginLink;
 +
 +std::vector<HANDLE> hHooks;
 +std::vector<HANDLE> hServices;
 +HANDLE hNetlibUser = 0;
 +
 +HANDLE hSkinsFolder = NULL;
 +TCHAR skinsFolder[1024];
 +
 +std::vector<MirandaSkinnedDialog *> dlgs;
 +
 +LIST_INTERFACE li;
 +FI_INTERFACE *fei = NULL;
 +struct MM_INTERFACE mmi;
 +struct UTF8_INTERFACE utfi;
 +
 +
 +int ModulesLoaded(WPARAM wParam, LPARAM lParam);
 +int PreShutdown(WPARAM wParam, LPARAM lParam);
 +
 +static int Service_GetInterface(WPARAM wParam, LPARAM lParam);
 +
 +
 +// Functions ////////////////////////////////////////////////////////////////////////////
 +
 +
 +extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 
 +{
 +	hInst = hinstDLL;
 +	return TRUE;
 +}
 +
 +
 +extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) 
 +{
 +	pluginInfo.cbSize = sizeof(PLUGININFO);
 +	return (PLUGININFO*) &pluginInfo;
 +}
 +
 +
 +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
 +{
 +	pluginInfo.cbSize = sizeof(PLUGININFOEX);
 +	return &pluginInfo;
 +}
 +
 +
 +static const MUUID interfaces[] = { MIID_SKINS, MIID_LAST };
 +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
 +{
 +	return interfaces;
 +}
 +
 +
 +extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) 
 +{
 +	pluginLink = link;
 +
 +	CHECK_VERSION("Skins");
 +
 +	// TODO Assert results here
 +	mir_getMMI(&mmi);
 +	mir_getUTFI(&utfi);
 +	mir_getLI(&li);
 +
 +	hHooks.push_back( HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded) );
 +	hHooks.push_back( HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown) );
 +
 +	NETLIBUSER nl_user = {0};
 +	nl_user.cbSize = sizeof(nl_user);
 +	nl_user.szSettingsModule = MODULE_NAME;
 +	nl_user.flags = NUF_NOOPTIONS;
 +	nl_user.szDescriptiveName = Translate("Skins");
 +	hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nl_user);
 +
 +	TCHAR mirandaFolder[1024];
 +	GetModuleFileName(GetModuleHandle(NULL), mirandaFolder, MAX_REGS(mirandaFolder));
 +	TCHAR *p = _tcsrchr(mirandaFolder, _T('\\'));
 +	if (p != NULL)
 +		*p = _T('\0');
 +
 +	// Folders plugin support
 +	if (ServiceExists(MS_FOLDERS_REGISTER_PATH))
 +	{
 +		hSkinsFolder = FoldersRegisterCustomPathT("Skins",  "Skins", _T(MIRANDA_PATH) _T("\\Skins"));
 +
 +		FoldersGetCustomPathT(hSkinsFolder, skinsFolder, MAX_REGS(skinsFolder), _T("."));
 +	}
 +	else
 +	{
 +		mir_sntprintf(skinsFolder, MAX_REGS(skinsFolder), _T("%s\\Skins"), mirandaFolder);
 +	}
 +
 +	InitOptions();
 +
 +	hServices.push_back( CreateServiceFunction(MS_SKINS_GETINTERFACE, Service_GetInterface) );
 +
 +	return 0;
 +}
 +
 +
 +extern "C" int __declspec(dllexport) Unload(void) 
 +{
 +	return 0;
 +}
 +
 +
 +// Called when all the modules are loaded
 +int ModulesLoaded(WPARAM wParam, LPARAM lParam) 
 +{
 +	// add our modules to the KnownModules list
 +	CallService("DBEditorpp/RegisterSingleModule", (WPARAM) MODULE_NAME, 0);
 +
 +	// updater plugin support
 +	if(ServiceExists(MS_UPDATE_REGISTER))
 +	{
 +		Update upd = {0};
 +		char szCurrentVersion[30];
 +
 +		upd.cbSize = sizeof(upd);
 +		upd.szComponentName = pluginInfo.shortName;
 +
 +		upd.szUpdateURL = UPDATER_AUTOREGISTER;
 +
 +		upd.szBetaVersionURL = "http://pescuma.googlecode.com/svn/trunk/Miranda/Plugins/skins/Docs/skins_version.txt";
 +		upd.szBetaChangelogURL = "http://pescuma.googlecode.com/svn/trunk/Miranda/Plugins/skins/Docs/skins_changelog.txt";
 +		upd.pbBetaVersionPrefix = (BYTE *)"Skins ";
 +		upd.cpbBetaVersionPrefix = strlen((char *)upd.pbBetaVersionPrefix);
 +#ifdef UNICODE
 +		upd.szBetaUpdateURL = "http://pescuma.googlecode.com/files/skinsW.%VERSION%.zip";
 +#else
 +		upd.szBetaUpdateURL = "http://pescuma.googlecode.com/files/skins.%VERSION%.zip";
 +#endif
 +
 +		upd.pbVersion = (BYTE *)CreateVersionStringPlugin((PLUGININFO*) &pluginInfo, szCurrentVersion);
 +		upd.cpbVersion = strlen((char *)upd.pbVersion);
 +
 +		CallService(MS_UPDATE_REGISTER, 0, (LPARAM)&upd);
 +	}
 +
 +	return 0;
 +}
 +
 +
 +int PreShutdown(WPARAM wParam, LPARAM lParam)
 +{
 +	unsigned int i;
 +
 +	for(i = 0; i < hServices.size(); i++)
 +		DestroyServiceFunction(hServices[i]);
 +	hServices.clear();
 +
 +	for(i = 0; i < hHooks.size(); i++)
 +		UnhookEvent(hHooks[i]);
 +	hHooks.clear();
 +
 +	DeInitOptions();
 +
 +	return 0;
 +}
 +
 +
 +BOOL FileExists(const char *filename)
 +{
 +	DWORD attrib = GetFileAttributesA(filename);
 +	if (attrib == 0xFFFFFFFF || (attrib & FILE_ATTRIBUTE_DIRECTORY))
 +		return FALSE;
 +	return TRUE;
 +}
 +
 +#ifdef UNICODE
 +BOOL FileExists(const WCHAR *filename)
 +{
 +	DWORD attrib = GetFileAttributesW(filename);
 +	if (attrib == 0xFFFFFFFF || (attrib & FILE_ATTRIBUTE_DIRECTORY))
 +		return FALSE;
 +	return TRUE;
 +}
 +#endif
 +
 +
 +BOOL DirExists(const char *filename)
 +{
 +	DWORD attrib = GetFileAttributesA(filename);
 +	if (attrib == 0xFFFFFFFF || !(attrib & FILE_ATTRIBUTE_DIRECTORY))
 +		return FALSE;
 +	return TRUE;
 +}
 +
 +#ifdef UNICODE
 +BOOL DirExists(const WCHAR *filename)
 +{
 +	DWORD attrib = GetFileAttributesW(filename);
 +	if (attrib == 0xFFFFFFFF || !(attrib & FILE_ATTRIBUTE_DIRECTORY))
 +		return FALSE;
 +	return TRUE;
 +}
 +#endif
 +
 +
 +BOOL CreatePath(const char *path) 
 +{
 +	char folder[1024];
 +	strncpy(folder, path, MAX_REGS(folder));
 +	folder[MAX_REGS(folder)-1] = '\0';
 +
 +	char *p = folder;
 +	if (p[0] && p[1] == ':' && p[2] == '\\') p += 3; // skip drive letter
 +
 +	SetLastError(ERROR_SUCCESS);
 +	while(p = strchr(p, '\\')) 
 +	{
 +		*p = '\0';
 +		CreateDirectoryA(folder, 0);
 +		*p = '\\';
 +		p++;
 +	}
 +	CreateDirectoryA(folder, 0);
 +
 +	DWORD lerr = GetLastError();
 +	return (lerr == ERROR_SUCCESS || lerr == ERROR_ALREADY_EXISTS);
 +}
 +
 +
 +void log(const char *fmt, ...)
 +{
 + va_list va;
 + char text[1024];
 +
 + va_start(va, fmt);
 + mir_vsnprintf(text, sizeof(text), fmt, va);
 + va_end(va);
 +
 +	CallService(MS_NETLIB_LOG, (WPARAM) NULL, (LPARAM) text);
 +}
 +
 +
 +MirandaSkinnedDialog *GetDialog(const char *name)
 +{
 +	_ASSERT(name != NULL);
 +
 +	for(unsigned int i = 0; i < dlgs.size(); i++)
 +	{
 +		MirandaSkinnedDialog *dlg = dlgs[i];
 +		if (strcmp(name, dlg->getName()) == 0)
 +			return dlg;
 +	}
 +
 +	return NULL;
 +}
 +
 +void getSkinnedDialogFilename(std::tstring &ret, const TCHAR *skin, const char *dialogName)
 +{
 +	ret = skinsFolder;
 +	ret += _T("\\");
 +	ret += skin;
 +	ret += _T("\\");
 +	ret += CharToTchar(dialogName);
 +	ret += _T(".");
 +	ret += _T(SKIN_EXTENSION);
 +}
 +
 +void getAvaiableSkins(std::vector<std::tstring> &skins, MirandaSkinnedDialog *dlg)
 +{
 +	TCHAR file[1024];
 +	mir_sntprintf(file, MAX_REGS(file), _T("%s\\*"), skinsFolder);
 +
 +	WIN32_FIND_DATA ffd = {0};
 +	HANDLE hFFD = FindFirstFile(file, &ffd);
 +	if (hFFD == INVALID_HANDLE_VALUE)
 +		return;
 +
 +	do
 +	{
 +		if (lstrcmp(ffd.cFileName, _T(".")) == 0 || lstrcmp(ffd.cFileName, _T("..")) == 0)
 +			continue;
 +
 +		mir_sntprintf(file, MAX_REGS(file), _T("%s\\%s"), skinsFolder, ffd.cFileName);
 +		if (!DirExists(file))
 +			continue;
 +
 +		if (dlg != NULL)
 +		{
 +			std::tstring filename;
 +			getSkinnedDialogFilename(filename, ffd.cFileName, dlg->getName());
 +			if (!FileExists(filename.c_str()))
 +				continue;
 +		}
 +
 +		skins.push_back(std::tstring(ffd.cFileName));
 +	}
 +	while(FindNextFile(hFFD, &ffd));
 +
 +	FindClose(hFFD);
 +}
 +
 +void OnError(void *param, const TCHAR *err)
 +{
 +	MirandaSkinnedDialog *dlg = (MirandaSkinnedDialog *) param;
 +	
 +	std::tstring title;
 +	title = CharToTchar(dlg->getName());
 +	title += _T("- Error executing skin");
 +
 +	MessageBox(NULL, err, title.c_str(), MB_OK | MB_ICONERROR);
 +}
 +
 +SKINNED_DIALOG Interface_RegisterDialog(const char *name, const char *description, const char *module)
 +{
 +	if (name == NULL || name[0] == 0 || module == NULL || module[0] == 0)
 +		return NULL;
 +	if (GetDialog(name) != NULL)
 +		return NULL;
 +
 +	// Check if default skin exists
 +	std::tstring filename;
 +	filename = skinsFolder;
 +	filename += _T("\\");
 +	filename += _T(DEFAULT_SKIN_NAME);
 +	filename += _T("\\");
 +	filename += Utf8ToTchar(name);
 +	filename += _T(".");
 +	filename += _T(SKIN_EXTENSION);
 +
 +	if (!FileExists(filename.c_str()))
 +		return NULL;
 +
 +	MirandaSkinnedDialog *dlg = new MirandaSkinnedDialog(name, description, module);
 +	dlg->setErrorCallback(OnError, dlg);
 +	dlgs.push_back(dlg);
 +	return (SKINNED_DIALOG) dlg;
 +}
 +
 +void Interface_DeleteDialog(SKINNED_DIALOG aDlg)
 +{
 +	if (aDlg == NULL)
 +		return;
 +
 +	MirandaSkinnedDialog * dlg = (MirandaSkinnedDialog *) aDlg;
 +	for(std::vector<MirandaSkinnedDialog*>::iterator it = dlgs.begin(); it != dlgs.end(); it++)
 +	{
 +		if (*it == dlg)
 +		{
 +			dlgs.erase(it);
 +			break;
 +		}
 +	}
 +
 +	delete dlg;
 +}
 +
 +void Interface_SetSkinChangedCallback(SKINNED_DIALOG aDlg, SkinOptionsChangedCallback cb, void *param)
 +{
 +	if (aDlg == NULL)
 +		return;
 +
 +	MirandaSkinnedDialog * dlg = (MirandaSkinnedDialog *) aDlg;
 +	dlg->setOnSkinChangedCallback((MirandaSkinnedCallback) cb, param);
 +}
 +
 +void Interface_FinishedConfiguring(SKINNED_DIALOG aDlg)
 +{
 +	if (aDlg == NULL)
 +		return;
 +
 +	MirandaSkinnedDialog *dlg = (MirandaSkinnedDialog *) aDlg;
 +	dlg->finishedConfiguring();
 +}
 +
 +SKINNED_FIELD Interface_AddTextField(SKINNED_DIALOG aDlg, const char *name, const char *description)
 +{
 +	if (aDlg == NULL || name == NULL || name[0] == 0)
 +		return NULL;
 +
 +	MirandaSkinnedDialog *dlg = (MirandaSkinnedDialog *) aDlg;
 +
 +	MirandaTextField *field = new MirandaTextField(dlg, name, description);
 +	if (!dlg->addField(field))
 +	{
 +		delete field;
 +		return NULL;
 +	}
 +
 +	return (SKINNED_FIELD) field;
 +}
 +
 +SKINNED_FIELD Interface_AddIconField(SKINNED_DIALOG aDlg, const char *name, const char *description)
 +{
 +	if (aDlg == NULL || name == NULL || name[0] == 0)
 +		return NULL;
 +
 +	MirandaSkinnedDialog *dlg = (MirandaSkinnedDialog *) aDlg;
 +
 +	MirandaIconField *field = new MirandaIconField(dlg, name, description);
 +	if (!dlg->addField(field))
 +	{
 +		delete field;
 +		return NULL;
 +	}
 +
 +	return (SKINNED_FIELD) field;
 +}
 +
 +SKINNED_FIELD Interface_AddImageField(SKINNED_DIALOG aDlg, const char *name, const char *description)
 +{
 +	if (aDlg == NULL || name == NULL || name[0] == 0)
 +		return NULL;
 +
 +	MirandaSkinnedDialog *dlg = (MirandaSkinnedDialog *) aDlg;
 +
 +	MirandaImageField *field = new MirandaImageField(dlg, name, description);
 +	if (!dlg->addField(field))
 +	{
 +		delete field;
 +		return NULL;
 +	}
 +
 +	return (SKINNED_FIELD) field;
 +}
 +
 +SKINNED_FIELD Interface_GetField(SKINNED_DIALOG aDlg, const char *name)
 +{
 +	if (aDlg == NULL || name == NULL || name[0] == 0)
 +		return NULL;
 +
 +	MirandaSkinnedDialog *dlg = (MirandaSkinnedDialog *) aDlg;
 +
 +	return (SKINNED_FIELD) dlg->getField(name);
 +}
 +
 +void Interface_SetDialogSize(SKINNED_DIALOG aDlg, int width, int height)
 +{
 +	if (aDlg == NULL)
 +		return;
 +
 +	MirandaSkinnedDialog *dlg = (MirandaSkinnedDialog *) aDlg;
 +	dlg->setSize(Size(width, height));
 +}
 +
 +void Interface_SetInfoInt(SKINNED_DIALOG aDlg, const char *name, int value)
 +{
 +	if (aDlg == NULL || name == NULL)
 +		return;
 +
 +	MirandaSkinnedDialog *dlg = (MirandaSkinnedDialog *) aDlg;
 +	dlg->getInfo()->set(name, value);
 +}
 +
 +void Interface_SetInfoDouble(SKINNED_DIALOG aDlg, const char *name, double value)
 +{
 +	if (aDlg == NULL || name == NULL)
 +		return;
 +
 +	MirandaSkinnedDialog *dlg = (MirandaSkinnedDialog *) aDlg;
 +	dlg->getInfo()->set(name, value);
 +}
 +
 +void Interface_SetInfoBool(SKINNED_DIALOG aDlg, const char *name, BOOL value)
 +{
 +	if (aDlg == NULL || name == NULL)
 +		return;
 +
 +	MirandaSkinnedDialog *dlg = (MirandaSkinnedDialog *) aDlg;
 +	dlg->getInfo()->set(name, value);
 +}
 +
 +void Interface_SetInfoString(SKINNED_DIALOG aDlg, const char *name, const TCHAR *value)
 +{
 +	if (aDlg == NULL || name == NULL)
 +		return;
 +
 +	MirandaSkinnedDialog *dlg = (MirandaSkinnedDialog *) aDlg;
 +	dlg->getInfo()->set(name, value);
 +}
 +
 +void Interface_RemoveInfo(SKINNED_DIALOG aDlg, const char *name)
 +{
 +	if (aDlg == NULL || name == NULL)
 +		return;
 +
 +	MirandaSkinnedDialog *dlg = (MirandaSkinnedDialog *) aDlg;
 +	dlg->getInfo()->remove(name);
 +}
 +
 +
 +void Interface_SetEnabled(SKINNED_FIELD aField, BOOL enabled)
 +{
 +	if (aField == NULL)
 +		return;
 +
 +	Field *field = (Field *) aField;
 +	field->setEnabled(enabled != 0);
 +}
 +
 +void Interface_SetToolTipA(SKINNED_FIELD aField, const char *tooltip)
 +{
 +	if (aField == NULL)
 +		return;
 +
 +	Field *field = (Field *) aField;
 +	field->setToolTip(CharToTchar(tooltip));
 +}
 +
 +void Interface_SetToolTipW(SKINNED_FIELD aField, const WCHAR *tooltip)
 +{
 +	if (aField == NULL)
 +		return;
 +
 +	Field *field = (Field *) aField;
 +	field->setToolTip(WcharToTchar(tooltip));
 +}
 +
 +void Interface_SetTextA(SKINNED_FIELD aField, const char *text)
 +{
 +	if (aField == NULL)
 +		return;
 +
 +	Field *field = (Field *) aField;
 +	switch(field->getType())
 +	{
 +	case SIMPLE_TEXT:
 +		((TextField *) field)->setText(CharToTchar(text));
 +		break;
 +	case CONTROL_LABEL:
 +	case CONTROL_BUTTON:
 +	case CONTROL_EDIT:
 +		((ControlField *) field)->setText(CharToTchar(text));
 +		break;
 +	}
 +}
 +
 +void Interface_SetTextW(SKINNED_FIELD aField, const WCHAR *text)
 +{
 +	if (aField == NULL)
 +		return;
 +
 +	Field *field = (Field *) aField;
 +	switch(field->getType())
 +	{
 +	case SIMPLE_TEXT:
 +		((TextField *) field)->setText(WcharToTchar(text));
 +		break;
 +	case CONTROL_LABEL:
 +	case CONTROL_BUTTON:
 +	case CONTROL_EDIT:
 +		((ControlField *) field)->setText(WcharToTchar(text));
 +		break;
 +	}
 +}
 +
 +void Interface_SetIcon(SKINNED_FIELD aField, HICON hIcon)
 +{
 +	if (aField == NULL)
 +		return;
 +
 +	Field *field = (Field *) aField;
 +	switch(field->getType())
 +	{
 +	case SIMPLE_ICON:
 +		((IconField *) field)->setIcon(hIcon);
 +		break;
 +	}
 +}
 +
 +void Interface_SetImage(SKINNED_FIELD aField, HBITMAP hBmp)
 +{
 +	if (aField == NULL)
 +		return;
 +
 +	Field *field = (Field *) aField;
 +	switch(field->getType())
 +	{
 +	case SIMPLE_IMAGE:
 +		((ImageField *) field)->setImage(hBmp);
 +		break;
 +	}
 +}
 +
 +SKINNED_DIALOG_STATE Interface_Run(SKINNED_DIALOG aDlg)
 +{
 +	if (aDlg == NULL)
 +		return NULL;
 +
 +	MirandaSkinnedDialog *dlg = (MirandaSkinnedDialog *) aDlg;
 +	return (SKINNED_DIALOG_STATE) dlg->getState();
 +}
 +
 +/*
 +void Interface_DeleteDialogState(SKINNED_DIALOG_STATE aDlg)
 +{
 +	if (aDlg == NULL)
 +		return;
 +
 +	DialogState * dlg = (DialogState *) aDlg;
 +
 +	delete dlg;
 +}
 +*/
 +
 +SKINNED_FIELD_STATE Interface_GetFieldState(SKINNED_DIALOG_STATE aDlg, const char *name)
 +{
 +	if (aDlg == NULL || name == NULL || name[0] == 0)
 +		return NULL;
 +
 +	DialogState *dlg = (DialogState *) aDlg;
 +
 +	return (SKINNED_FIELD_STATE) dlg->getField(name);
 +}
 +
 +RECT Interface_GetDialogBorders(SKINNED_DIALOG_STATE aDlg)
 +{
 +	RECT ret = {0};
 +
 +	if (aDlg == NULL)
 +		return ret;
 +
 +	DialogState *state = (DialogState *) aDlg;
 +	BorderState *borders = state->getBorders();
 +
 +	ret.left = borders->getLeft();
 +	ret.top = borders->getTop();
 +	ret.right = borders->getRight();
 +	ret.bottom = borders->getBottom();
 +
 +	return ret;
 +}
 +
 +RECT Interface_GetRect(SKINNED_FIELD_STATE field)
 +{
 +	if (field == NULL)
 +	{
 +		RECT ret = {0};
 +		return ret;
 +	}
 +
 +	FieldState *fieldState = (FieldState *) field;
 +
 +	return fieldState->getRect();
 +}
 +
 +RECT Interface_GetInsideRect(SKINNED_FIELD_STATE field)
 +{
 +	if (field == NULL)
 +	{
 +		RECT ret = {0};
 +		return ret;
 +	}
 +
 +	FieldState *fieldState = (FieldState *) field;
 +
 +	return fieldState->getInsideRect();
 +}
 +
 +RECT Interface_GetRawRect(SKINNED_FIELD_STATE field)
 +{
 +	if (field == NULL)
 +	{
 +		RECT ret = {0};
 +		return ret;
 +	}
 +
 +	FieldState *fieldState = (FieldState *) field;
 +
 +	return fieldState->getRect(true);
 +}
 +
 +RECT Interface_GetRawInsideRect(SKINNED_FIELD_STATE field)
 +{
 +	if (field == NULL)
 +	{
 +		RECT ret = {0};
 +		return ret;
 +	}
 +
 +	FieldState *fieldState = (FieldState *) field;
 +
 +	return fieldState->getInsideRect(true);
 +}
 +
 +RECT Interface_GetBorders(SKINNED_FIELD_STATE field)
 +{
 +	RECT ret = {0};
 +
 +	if (field == NULL)
 +		return ret;
 +
 +	FieldState *fieldState = (FieldState *) field;
 +	BorderState *borders = fieldState->getBorders();
 +
 +	ret.left = borders->getLeft();
 +	ret.top = borders->getTop();
 +	ret.right = borders->getRight();
 +	ret.bottom = borders->getBottom();
 +
 +	return ret;
 +}
 +
 +BOOL Interface_IsVisible(SKINNED_FIELD_STATE field)
 +{
 +	if (field == NULL)
 +		return FALSE;
 +
 +	FieldState *fieldState = (FieldState *) field;
 +
 +	return fieldState->isVisible();
 +}
 +
 +char * Interface_GetToolTipA(SKINNED_FIELD_STATE field)
 +{
 +	if (field == NULL)
 +		return NULL;
 +
 +	FieldState *fieldState = (FieldState *) field;
 +	return TcharToChar(fieldState->getToolTip()).detach();
 +}
 +
 +WCHAR * Interface_GetToolTipW(SKINNED_FIELD_STATE field) 
 +{
 +	if (field == NULL)
 +		return NULL;
 +
 +	FieldState *fieldState = (FieldState *) field;
 +	return TcharToWchar(fieldState->getToolTip()).detach();
 +}
 +
 +char * Interface_GetTextA(SKINNED_FIELD_STATE field)
 +{
 +	if (field == NULL)
 +		return NULL;
 +
 +	FieldState *fieldState = (FieldState *) field;
 +
 +	switch(fieldState->getField()->getType())
 +	{
 +		case SIMPLE_TEXT:
 +			return TcharToChar(((TextFieldState *) fieldState)->getText()).detach();
 +		case CONTROL_LABEL:
 +		case CONTROL_BUTTON:
 +		case CONTROL_EDIT:
 +			return TcharToChar(((ControlFieldState *) field)->getText()).detach();
 +	}
 +
 +	return NULL;
 +}
 +
 +WCHAR * Interface_GetTextW(SKINNED_FIELD_STATE field) 
 +{
 +	if (field == NULL)
 +		return NULL;
 +
 +	FieldState *fieldState = (FieldState *) field;
 +
 +	switch(fieldState->getField()->getType())
 +	{
 +		case SIMPLE_TEXT:
 +			return TcharToWchar(((TextFieldState *) fieldState)->getText()).detach();
 +		case CONTROL_LABEL:
 +		case CONTROL_BUTTON:
 +		case CONTROL_EDIT:
 +			return TcharToWchar(((ControlFieldState *) field)->getText()).detach();
 +	}
 +
 +	return NULL;
 +}
 +
 +HFONT Interface_GetFont(SKINNED_FIELD_STATE field)
 +{
 +	if (field == NULL)
 +		return NULL;
 +
 +	FieldState *fieldState = (FieldState *) field;
 +
 +	switch(fieldState->getField()->getType())
 +	{
 +		case SIMPLE_TEXT:
 +			return ((TextFieldState *) fieldState)->getFont()->getHFONT();
 +		case CONTROL_LABEL:
 +		case CONTROL_BUTTON:
 +		case CONTROL_EDIT:
 +			return ((ControlFieldState *) fieldState)->getFont()->getHFONT();
 +	}
 +
 +	return NULL;
 +}
 +
 +COLORREF Interface_GetFontColor(SKINNED_FIELD_STATE field)
 +{
 +	if (field == NULL)
 +		return RGB(0,0,0);
 +
 +	FieldState *fieldState = (FieldState *) field;
 +
 +	switch(fieldState->getField()->getType())
 +	{
 +		case SIMPLE_TEXT:
 +			return ((TextFieldState *) fieldState)->getFont()->getColor();
 +		case CONTROL_LABEL:
 +		case CONTROL_BUTTON:
 +		case CONTROL_EDIT:
 +			return ((ControlFieldState *) fieldState)->getFont()->getColor();
 +	}
 +
 +	return RGB(0,0,0);
 +}
 +
 +int Interface_GetHorizontalAlign(SKINNED_FIELD_STATE field) 
 +{
 +	if (field == NULL)
 +		return SKN_HALIGN_LEFT;
 +
 +	FieldState *fieldState = (FieldState *) field;
 +	return fieldState->getHAlign();
 +}
 +
 +int Interface_GetVerticalAlign(SKINNED_FIELD_STATE field) 
 +{
 +	if (field == NULL)
 +		return SKN_VALIGN_TOP;
 +
 +	FieldState *fieldState = (FieldState *) field;
 +	return fieldState->getVAlign();
 +}
 +
 +HICON Interface_GetIcon(SKINNED_FIELD_STATE field)
 +{
 +	if (field == NULL)
 +		return NULL;
 +
 +	FieldState *fieldState = (FieldState *) field;
 +
 +	switch(fieldState->getField()->getType())
 +	{
 +		case SIMPLE_ICON:
 +			return ((IconFieldState *) fieldState)->getIcon();
 +	}
 +	return NULL;
 +}
 +
 +HBITMAP Interface_GetImage(SKINNED_FIELD_STATE field)
 +{
 +	if (field == NULL)
 +		return NULL;
 +
 +	FieldState *fieldState = (FieldState *) field;
 +
 +	switch(fieldState->getField()->getType())
 +	{
 +		case SIMPLE_IMAGE:
 +			return ((ImageFieldState *) fieldState)->getImage();
 +	}
 +	return NULL;
 +}
 +
 +
 +static int Service_GetInterface(WPARAM wParam, LPARAM lParam)
 +{
 +	SKIN_INTERFACE *mski = (SKIN_INTERFACE *) lParam;
 +	if (mski == NULL)
 +		return -1;
 +
 +	if (mski->cbSize < sizeof(SKIN_INTERFACE))
 +		return -2;
 +
 +	mski->RegisterDialog = &Interface_RegisterDialog;
 +	mski->DeleteDialog = &Interface_DeleteDialog;
 +	mski->SetSkinChangedCallback = &Interface_SetSkinChangedCallback;
 +	mski->FinishedConfiguring = &Interface_FinishedConfiguring;
 +
 +	mski->AddTextField = &Interface_AddTextField;
 +	mski->AddIconField = &Interface_AddIconField;
 +	mski->AddImageField = &Interface_AddImageField;
 +	mski->GetField = &Interface_GetField;
 +	mski->SetDialogSize = &Interface_SetDialogSize;
 +
 +	mski->SetInfoInt = &Interface_SetInfoInt;
 +	mski->SetInfoDouble = &Interface_SetInfoDouble;
 +	mski->SetInfoBool = &Interface_SetInfoBool;
 +	mski->SetInfoString = &Interface_SetInfoString;
 +	mski->RemoveInfo = &Interface_RemoveInfo;
 +
 +	mski->SetEnabled = &Interface_SetEnabled;
 +	mski->SetToolTipA = &Interface_SetToolTipA;
 +	mski->SetToolTipW = &Interface_SetToolTipW;
 +
 +	mski->SetTextA = &Interface_SetTextA;
 +	mski->SetTextW = &Interface_SetTextW;
 +
 +	mski->SetIcon = &Interface_SetIcon;
 +
 +	mski->SetImage = &Interface_SetImage;
 +
 +	mski->Run = &Interface_Run;
 +
 +	mski->GetFieldState = &Interface_GetFieldState;
 +	mski->GetDialogBorders = &Interface_GetDialogBorders;
 +
 +	mski->GetRect = &Interface_GetRect;
 +	mski->GetInsideRect = &Interface_GetInsideRect;
 +	mski->GetRawRect = &Interface_GetRawRect;
 +	mski->GetRawInsideRect = &Interface_GetRawInsideRect;
 +
 +	mski->GetBorders = &Interface_GetBorders;
 +	mski->IsVisible = &Interface_IsVisible;
 +	mski->GetToolTipA = &Interface_GetToolTipA;
 +	mski->GetToolTipW = &Interface_GetToolTipW;
 +	mski->GetHorizontalAlign = &Interface_GetHorizontalAlign;
 +	mski->GetVerticalAlign = &Interface_GetVerticalAlign;
 +
 +	mski->GetTextA = &Interface_GetTextA;
 +	mski->GetTextW = &Interface_GetTextW;
 +	mski->GetFont = &Interface_GetFont;
 +	mski->GetFontColor = &Interface_GetFontColor;
 +
 +	mski->GetIcon = &Interface_GetIcon;
 +
 +	mski->GetImage = &Interface_GetImage;
 +
 +	return 0;
 +}
 diff --git a/plugins/Skins/skins.vcproj b/plugins/Skins/skins.vcproj new file mode 100644 index 0000000000..413faa319e --- /dev/null +++ b/plugins/Skins/skins.vcproj @@ -0,0 +1,1066 @@ +<?xml version="1.0" encoding="Windows-1252"?>
 +<VisualStudioProject
 +	ProjectType="Visual C++"
 +	Version="9,00"
 +	Name="skins"
 +	ProjectGUID="{F5F5EA6E-F648-4174-8419-D6CA41DF0A11}"
 +	RootNamespace="skins"
 +	TargetFrameworkVersion="0"
 +	>
 +	<Platforms>
 +		<Platform
 +			Name="Win32"
 +		/>
 +	</Platforms>
 +	<ToolFiles>
 +	</ToolFiles>
 +	<Configurations>
 +		<Configuration
 +			Name="Debug|Win32"
 +			OutputDirectory=".\Debug"
 +			IntermediateDirectory=".\Debug"
 +			ConfigurationType="2"
 +			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
 +			UseOfMFC="0"
 +			ATLMinimizesCRunTimeLibraryUsage="false"
 +			CharacterSet="2"
 +			>
 +			<Tool
 +				Name="VCPreBuildEventTool"
 +			/>
 +			<Tool
 +				Name="VCCustomBuildTool"
 +			/>
 +			<Tool
 +				Name="VCXMLDataGeneratorTool"
 +			/>
 +			<Tool
 +				Name="VCWebServiceProxyGeneratorTool"
 +			/>
 +			<Tool
 +				Name="VCMIDLTool"
 +				PreprocessorDefinitions="NDEBUG"
 +				MkTypLibCompatible="true"
 +				SuppressStartupBanner="true"
 +				TargetEnvironment="1"
 +				TypeLibraryName=".\Debug/skins.tlb"
 +				HeaderFileName=""
 +			/>
 +			<Tool
 +				Name="VCCLCompilerTool"
 +				Optimization="0"
 +				AdditionalIncludeDirectories="../../include,sdk,libs,../utils"
 +				PreprocessorDefinitions="WIN32;W32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
 +				RuntimeLibrary="1"
 +				PrecompiledHeaderFile=".\Debug/skins.pch"
 +				AssemblerListingLocation=".\Debug/"
 +				ObjectFile=".\Debug/"
 +				ProgramDataBaseFileName=".\Debug/"
 +				BrowseInformation="1"
 +				WarningLevel="3"
 +				SuppressStartupBanner="true"
 +				DebugInformationFormat="4"
 +			/>
 +			<Tool
 +				Name="VCManagedResourceCompilerTool"
 +			/>
 +			<Tool
 +				Name="VCResourceCompilerTool"
 +				PreprocessorDefinitions="NDEBUG"
 +				Culture="1047"
 +			/>
 +			<Tool
 +				Name="VCPreLinkEventTool"
 +			/>
 +			<Tool
 +				Name="VCLinkerTool"
 +				AdditionalOptions="/ALIGN:4096 /filealign:0x200 /ignore:4108 "
 +				AdditionalDependencies="v8_g.lib Ws2_32.lib Winmm.lib"
 +				OutputFile="..\..\bin\debug\Plugins\skins.dll"
 +				LinkIncremental="2"
 +				SuppressStartupBanner="true"
 +				AdditionalLibraryDirectories="$(ProjectDir)libs\"
 +				GenerateDebugInformation="true"
 +				ProgramDatabaseFile=".\Debug/skins.pdb"
 +				BaseAddress="0x3EC20000"
 +				RandomizedBaseAddress="1"
 +				DataExecutionPrevention="0"
 +				ImportLibrary=".\Debug/skins.lib"
 +				TargetMachine="1"
 +			/>
 +			<Tool
 +				Name="VCALinkTool"
 +			/>
 +			<Tool
 +				Name="VCManifestTool"
 +			/>
 +			<Tool
 +				Name="VCXDCMakeTool"
 +			/>
 +			<Tool
 +				Name="VCBscMakeTool"
 +				SuppressStartupBanner="true"
 +				OutputFile=".\Debug/skins.bsc"
 +			/>
 +			<Tool
 +				Name="VCFxCopTool"
 +			/>
 +			<Tool
 +				Name="VCAppVerifierTool"
 +			/>
 +			<Tool
 +				Name="VCPostBuildEventTool"
 +			/>
 +		</Configuration>
 +		<Configuration
 +			Name="Release|Win32"
 +			OutputDirectory=".\Release"
 +			IntermediateDirectory=".\Release"
 +			ConfigurationType="2"
 +			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
 +			UseOfMFC="0"
 +			ATLMinimizesCRunTimeLibraryUsage="false"
 +			CharacterSet="2"
 +			WholeProgramOptimization="1"
 +			>
 +			<Tool
 +				Name="VCPreBuildEventTool"
 +			/>
 +			<Tool
 +				Name="VCCustomBuildTool"
 +			/>
 +			<Tool
 +				Name="VCXMLDataGeneratorTool"
 +			/>
 +			<Tool
 +				Name="VCWebServiceProxyGeneratorTool"
 +			/>
 +			<Tool
 +				Name="VCMIDLTool"
 +				PreprocessorDefinitions="NDEBUG"
 +				MkTypLibCompatible="true"
 +				SuppressStartupBanner="true"
 +				TargetEnvironment="1"
 +				TypeLibraryName=".\Release/skins.tlb"
 +				HeaderFileName=""
 +			/>
 +			<Tool
 +				Name="VCCLCompilerTool"
 +				Optimization="2"
 +				InlineFunctionExpansion="0"
 +				WholeProgramOptimization="true"
 +				AdditionalIncludeDirectories="../../include,sdk,libs,../utils"
 +				PreprocessorDefinitions="WIN32;W32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
 +				StringPooling="true"
 +				RuntimeLibrary="0"
 +				EnableFunctionLevelLinking="true"
 +				PrecompiledHeaderFile=".\Release/skins.pch"
 +				AssemblerListingLocation=".\Release/"
 +				ObjectFile=".\Release/"
 +				ProgramDataBaseFileName=".\Release/"
 +				BrowseInformation="2"
 +				BrowseInformationFile=".\Release/"
 +				WarningLevel="3"
 +				SuppressStartupBanner="true"
 +			/>
 +			<Tool
 +				Name="VCManagedResourceCompilerTool"
 +			/>
 +			<Tool
 +				Name="VCResourceCompilerTool"
 +				PreprocessorDefinitions="NDEBUG"
 +				Culture="1047"
 +			/>
 +			<Tool
 +				Name="VCPreLinkEventTool"
 +			/>
 +			<Tool
 +				Name="VCLinkerTool"
 +				AdditionalOptions="/ALIGN:4096 /filealign:0x200 /ignore:4108 "
 +				AdditionalDependencies="v8.lib Ws2_32.lib Winmm.lib"
 +				OutputFile="..\..\bin\release\Plugins\skins.dll"
 +				LinkIncremental="1"
 +				SuppressStartupBanner="true"
 +				AdditionalLibraryDirectories="$(ProjectDir)libs\"
 +				GenerateDebugInformation="true"
 +				ProgramDatabaseFile=".\Release/skins.pdb"
 +				GenerateMapFile="true"
 +				MapFileName=".\Release/skins.map"
 +				LinkTimeCodeGeneration="1"
 +				BaseAddress="0x3EC20000"
 +				RandomizedBaseAddress="1"
 +				DataExecutionPrevention="0"
 +				ImportLibrary=".\Release/skins.lib"
 +				TargetMachine="1"
 +			/>
 +			<Tool
 +				Name="VCALinkTool"
 +			/>
 +			<Tool
 +				Name="VCManifestTool"
 +			/>
 +			<Tool
 +				Name="VCXDCMakeTool"
 +			/>
 +			<Tool
 +				Name="VCBscMakeTool"
 +				SuppressStartupBanner="true"
 +				OutputFile=".\Release/skins.bsc"
 +			/>
 +			<Tool
 +				Name="VCFxCopTool"
 +			/>
 +			<Tool
 +				Name="VCAppVerifierTool"
 +			/>
 +			<Tool
 +				Name="VCPostBuildEventTool"
 +			/>
 +		</Configuration>
 +		<Configuration
 +			Name="Unicode Debug|Win32"
 +			OutputDirectory=".\Unicode_Debug"
 +			IntermediateDirectory=".\Unicode_Debug"
 +			ConfigurationType="2"
 +			UseOfMFC="0"
 +			ATLMinimizesCRunTimeLibraryUsage="false"
 +			CharacterSet="1"
 +			>
 +			<Tool
 +				Name="VCPreBuildEventTool"
 +			/>
 +			<Tool
 +				Name="VCCustomBuildTool"
 +			/>
 +			<Tool
 +				Name="VCXMLDataGeneratorTool"
 +			/>
 +			<Tool
 +				Name="VCWebServiceProxyGeneratorTool"
 +			/>
 +			<Tool
 +				Name="VCMIDLTool"
 +				PreprocessorDefinitions="NDEBUG"
 +				MkTypLibCompatible="true"
 +				SuppressStartupBanner="true"
 +				TargetEnvironment="1"
 +				TypeLibraryName=".\Unicode_Debug/skins.tlb"
 +				HeaderFileName=""
 +			/>
 +			<Tool
 +				Name="VCCLCompilerTool"
 +				Optimization="0"
 +				AdditionalIncludeDirectories="../../include,sdk,libs,../utils"
 +				PreprocessorDefinitions="WIN32;W32;_DEBUG;DEBUG;_WINDOWS;UNICODE;_USRDLL;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
 +				MinimalRebuild="true"
 +				BasicRuntimeChecks="3"
 +				RuntimeLibrary="1"
 +				PrecompiledHeaderFile=".\Unicode_Debug/skins.pch"
 +				AssemblerListingLocation=""
 +				BrowseInformation="1"
 +				WarningLevel="3"
 +				SuppressStartupBanner="true"
 +				DebugInformationFormat="4"
 +			/>
 +			<Tool
 +				Name="VCManagedResourceCompilerTool"
 +			/>
 +			<Tool
 +				Name="VCResourceCompilerTool"
 +			/>
 +			<Tool
 +				Name="VCPreLinkEventTool"
 +			/>
 +			<Tool
 +				Name="VCLinkerTool"
 +				AdditionalOptions="/ALIGN:4096 /filealign:0x200 /ignore:4108 "
 +				AdditionalDependencies="v8_g.lib Ws2_32.lib Winmm.lib"
 +				OutputFile="..\..\bin\debug unicode\Plugins\skinsW.dll"
 +				LinkIncremental="2"
 +				AdditionalLibraryDirectories="$(ProjectDir)libs\"
 +				GenerateDebugInformation="true"
 +				ProgramDatabaseFile=".\Unicode_Debug/skinsW.pdb"
 +				SubSystem="2"
 +				BaseAddress=""
 +				ImportLibrary=".\Unicode_Debug/skinsW.lib"
 +				TargetMachine="1"
 +			/>
 +			<Tool
 +				Name="VCALinkTool"
 +			/>
 +			<Tool
 +				Name="VCManifestTool"
 +			/>
 +			<Tool
 +				Name="VCXDCMakeTool"
 +			/>
 +			<Tool
 +				Name="VCBscMakeTool"
 +			/>
 +			<Tool
 +				Name="VCFxCopTool"
 +			/>
 +			<Tool
 +				Name="VCAppVerifierTool"
 +			/>
 +			<Tool
 +				Name="VCPostBuildEventTool"
 +			/>
 +		</Configuration>
 +		<Configuration
 +			Name="Unicode Release|Win32"
 +			OutputDirectory=".\Unicode_Release"
 +			IntermediateDirectory=".\Unicode_Release"
 +			ConfigurationType="2"
 +			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
 +			UseOfMFC="0"
 +			ATLMinimizesCRunTimeLibraryUsage="false"
 +			CharacterSet="1"
 +			WholeProgramOptimization="1"
 +			>
 +			<Tool
 +				Name="VCPreBuildEventTool"
 +			/>
 +			<Tool
 +				Name="VCCustomBuildTool"
 +			/>
 +			<Tool
 +				Name="VCXMLDataGeneratorTool"
 +			/>
 +			<Tool
 +				Name="VCWebServiceProxyGeneratorTool"
 +			/>
 +			<Tool
 +				Name="VCMIDLTool"
 +				PreprocessorDefinitions="NDEBUG"
 +				MkTypLibCompatible="true"
 +				SuppressStartupBanner="true"
 +				TargetEnvironment="1"
 +				TypeLibraryName=".\Unicode_Release/skins.tlb"
 +				HeaderFileName=""
 +			/>
 +			<Tool
 +				Name="VCCLCompilerTool"
 +				Optimization="2"
 +				InlineFunctionExpansion="0"
 +				FavorSizeOrSpeed="1"
 +				WholeProgramOptimization="true"
 +				AdditionalIncludeDirectories="../../include,sdk,libs,../utils"
 +				PreprocessorDefinitions="WIN32;W32;NDEBUG;_WINDOWS;UNICODE;_USRDLL;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
 +				StringPooling="true"
 +				RuntimeLibrary="0"
 +				EnableFunctionLevelLinking="true"
 +				PrecompiledHeaderFile=".\Unicode_Release/skins.pch"
 +				AssemblerListingLocation=".\Unicode_Release/"
 +				ObjectFile=".\Unicode_Release/"
 +				ProgramDataBaseFileName=".\Unicode_Release/"
 +				BrowseInformation="2"
 +				BrowseInformationFile=".\Unicode_Release/"
 +				WarningLevel="3"
 +				SuppressStartupBanner="true"
 +			/>
 +			<Tool
 +				Name="VCManagedResourceCompilerTool"
 +			/>
 +			<Tool
 +				Name="VCResourceCompilerTool"
 +				PreprocessorDefinitions="NDEBUG"
 +				Culture="1047"
 +			/>
 +			<Tool
 +				Name="VCPreLinkEventTool"
 +			/>
 +			<Tool
 +				Name="VCLinkerTool"
 +				AdditionalOptions="/ALIGN:4096 /filealign:0x200 /ignore:4108 "
 +				AdditionalDependencies="v8.lib Ws2_32.lib Winmm.lib"
 +				OutputFile="..\..\bin\release unicode\Plugins\skinsW.dll"
 +				LinkIncremental="1"
 +				SuppressStartupBanner="true"
 +				AdditionalLibraryDirectories="$(ProjectDir)libs\"
 +				GenerateDebugInformation="true"
 +				ProgramDatabaseFile=".\Unicode_Release/skinsW.pdb"
 +				GenerateMapFile="true"
 +				MapFileName=".\Unicode_Release/skinsW.map"
 +				LinkTimeCodeGeneration="1"
 +				BaseAddress="0x3EC20000"
 +				RandomizedBaseAddress="1"
 +				DataExecutionPrevention="0"
 +				ImportLibrary=".\Unicode_Release/skinsW.lib"
 +				TargetMachine="1"
 +			/>
 +			<Tool
 +				Name="VCALinkTool"
 +			/>
 +			<Tool
 +				Name="VCManifestTool"
 +			/>
 +			<Tool
 +				Name="VCXDCMakeTool"
 +			/>
 +			<Tool
 +				Name="VCBscMakeTool"
 +				SuppressStartupBanner="true"
 +				OutputFile=".\Unicode_Release/skins.bsc"
 +			/>
 +			<Tool
 +				Name="VCFxCopTool"
 +			/>
 +			<Tool
 +				Name="VCAppVerifierTool"
 +			/>
 +			<Tool
 +				Name="VCPostBuildEventTool"
 +			/>
 +		</Configuration>
 +	</Configurations>
 +	<References>
 +	</References>
 +	<Files>
 +		<Filter
 +			Name="Header Files"
 +			Filter="h;hpp;hxx;hm;inl"
 +			>
 +			<File
 +				RelativePath="commons.h"
 +				>
 +			</File>
 +			<File
 +				RelativePath="m_skins.h"
 +				>
 +			</File>
 +			<File
 +				RelativePath=".\m_skins_cpp.h"
 +				>
 +			</File>
 +			<File
 +				RelativePath="..\utils\mir_icons.h"
 +				>
 +			</File>
 +			<File
 +				RelativePath="..\utils\mir_memory.h"
 +				>
 +			</File>
 +			<File
 +				RelativePath="..\utils\mir_options.h"
 +				>
 +			</File>
 +			<File
 +				RelativePath="options.h"
 +				>
 +			</File>
 +			<File
 +				RelativePath="resource.h"
 +				>
 +			</File>
 +			<Filter
 +				Name="SkinLib Header Files"
 +				>
 +				<File
 +					RelativePath=".\SkinLib\globals.h"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\SkinLib\Position.h"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\SkinLib\scope.h"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\SkinLib\Size.h"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\SkinLib\SkinnedDialog.h"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\SkinLib\SkinOption.h"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\SkinLib\SkinOptions.h"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\SkinLib\tstring.h"
 +					>
 +				</File>
 +				<Filter
 +					Name="Fields Header Files"
 +					>
 +					<File
 +						RelativePath=".\SkinLib\ButtonField.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\ControlField.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\Dialog.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\DialogInfo.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\EditField.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\Field.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\IconField.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\ImageField.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\LabelField.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\TextField.h"
 +						>
 +					</File>
 +				</Filter>
 +				<Filter
 +					Name="v8 Header Files"
 +					>
 +					<File
 +						RelativePath=".\SkinLib\BorderState_v8_wrapper.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\ControlFieldState_v8_wrapper.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\DialogState_v8_wrapper.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\FieldState_v8_wrapper.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\FontState_v8_wrapper.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\SkinOption_v8_wrapper.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\TextFieldState_v8_wrapper.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\V8Script.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\V8Templates.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\V8Wrappers.h"
 +						>
 +					</File>
 +				</Filter>
 +				<Filter
 +					Name="States Header Files"
 +					>
 +					<File
 +						RelativePath=".\SkinLib\BorderState.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\ButtonFieldState.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\ControlFieldState.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\DialogState.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\EditFieldState.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\FieldState.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\FontState.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\IconFieldState.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\ImageFieldState.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\LabelFieldState.h"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\TextFieldState.h"
 +						>
 +					</File>
 +				</Filter>
 +			</Filter>
 +			<Filter
 +				Name="Miranda Wrappers Header Files"
 +				>
 +				<File
 +					RelativePath=".\MirandaField.h"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\MirandaFont.h"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\MirandaIconField.h"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\MirandaImageField.h"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\MirandaSkinnedDialog.h"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\MirandaTextField.h"
 +					>
 +				</File>
 +			</Filter>
 +		</Filter>
 +		<Filter
 +			Name="Resource Files"
 +			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
 +			>
 +			<File
 +				RelativePath="resource.rc"
 +				>
 +				<FileConfiguration
 +					Name="Debug|Win32"
 +					>
 +					<Tool
 +						Name="VCResourceCompilerTool"
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +				<FileConfiguration
 +					Name="Release|Win32"
 +					>
 +					<Tool
 +						Name="VCResourceCompilerTool"
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +				<FileConfiguration
 +					Name="Unicode Debug|Win32"
 +					>
 +					<Tool
 +						Name="VCResourceCompilerTool"
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +				<FileConfiguration
 +					Name="Unicode Release|Win32"
 +					>
 +					<Tool
 +						Name="VCResourceCompilerTool"
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +			</File>
 +		</Filter>
 +		<Filter
 +			Name="Source Files"
 +			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
 +			>
 +			<File
 +				RelativePath="..\utils\mir_icons.cpp"
 +				>
 +				<FileConfiguration
 +					Name="Debug|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +				<FileConfiguration
 +					Name="Release|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +				<FileConfiguration
 +					Name="Unicode Debug|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +				<FileConfiguration
 +					Name="Unicode Release|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +			</File>
 +			<File
 +				RelativePath="..\utils\mir_options.cpp"
 +				>
 +				<FileConfiguration
 +					Name="Debug|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +				<FileConfiguration
 +					Name="Release|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +				<FileConfiguration
 +					Name="Unicode Debug|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +				<FileConfiguration
 +					Name="Unicode Release|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +			</File>
 +			<File
 +				RelativePath="options.cpp"
 +				>
 +				<FileConfiguration
 +					Name="Debug|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +				<FileConfiguration
 +					Name="Release|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +				<FileConfiguration
 +					Name="Unicode Debug|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +				<FileConfiguration
 +					Name="Unicode Release|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +			</File>
 +			<File
 +				RelativePath="skins.cpp"
 +				>
 +				<FileConfiguration
 +					Name="Debug|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +				<FileConfiguration
 +					Name="Release|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +				<FileConfiguration
 +					Name="Unicode Debug|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +				<FileConfiguration
 +					Name="Unicode Release|Win32"
 +					>
 +					<Tool
 +						Name="VCCLCompilerTool"
 +						AdditionalIncludeDirectories=""
 +						PreprocessorDefinitions=""
 +					/>
 +				</FileConfiguration>
 +			</File>
 +			<Filter
 +				Name="SkinLib Source Files"
 +				>
 +				<File
 +					RelativePath=".\SkinLib\Position.cpp"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\SkinLib\Size.cpp"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\SkinLib\SkinnedDialog.cpp"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\SkinLib\SkinOptions.cpp"
 +					>
 +				</File>
 +				<Filter
 +					Name="Fields Source Files"
 +					>
 +					<File
 +						RelativePath=".\SkinLib\ButtonField.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\ControlField.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\Dialog.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\DialogInfo.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\EditField.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\Field.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\IconField.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\ImageField.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\LabelField.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\TextField.cpp"
 +						>
 +					</File>
 +				</Filter>
 +				<Filter
 +					Name="v8 Source Files"
 +					>
 +					<File
 +						RelativePath=".\SkinLib\BorderState_v8_wrapper.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\ControlFieldState_v8_wrapper.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\DialogState_v8_wrapper.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\FieldState_v8_wrapper.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\FontState_v8_wrapper.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\SkinOption_v8_wrapper.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\TextFieldState_v8_wrapper.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\V8Script.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\V8Templates.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\V8Wrappers.cpp"
 +						>
 +					</File>
 +				</Filter>
 +				<Filter
 +					Name="States Source Files"
 +					>
 +					<File
 +						RelativePath=".\SkinLib\BorderState.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\ButtonFieldState.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\ControlFieldState.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\DialogState.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\EditFieldState.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\FieldState.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\FontState.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\IconFieldState.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\ImageFieldState.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\LabelFieldState.cpp"
 +						>
 +					</File>
 +					<File
 +						RelativePath=".\SkinLib\TextFieldState.cpp"
 +						>
 +					</File>
 +				</Filter>
 +			</Filter>
 +			<Filter
 +				Name="Miranda Wrappers Source Files"
 +				>
 +				<File
 +					RelativePath=".\MirandaFont.cpp"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\MirandaIconField.cpp"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\MirandaImageField.cpp"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\MirandaSkinnedDialog.cpp"
 +					>
 +				</File>
 +				<File
 +					RelativePath=".\MirandaTextField.cpp"
 +					>
 +				</File>
 +			</Filter>
 +		</Filter>
 +		<Filter
 +			Name="Docs"
 +			>
 +			<File
 +				RelativePath="Docs\langpack_skins.txt"
 +				>
 +			</File>
 +			<File
 +				RelativePath="Docs\skins_changelog.txt"
 +				>
 +			</File>
 +			<File
 +				RelativePath="Docs\skins_readme.txt"
 +				>
 +			</File>
 +			<File
 +				RelativePath="Docs\skins_version.txt"
 +				>
 +			</File>
 +		</Filter>
 +	</Files>
 +	<Globals>
 +	</Globals>
 +</VisualStudioProject>
  | 
