// xkeymacs.h: interface for the CXkeymacsDll class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_XKEYMACS_H__88552DEC_1233_4A0A_BE62_9EF7BC618EC6__INCLUDED_)
#define AFX_XKEYMACS_H__88552DEC_1233_4A0A_BE62_9EF7BC618EC6__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

HINSTANCE GetThisHInst();

#include "ClipboardSnap.h"

enum { MAX_APP = 64 };
enum { NONE = 0x0, SHIFT = 0x1, CONTROL = 0x2, META = 0x4, CONTROLX = 0x8,
	   MAX_COMMAND_TYPE = NONE + SHIFT + CONTROL + META + CONTROLX + 1 };
enum { /* WIN_SHIFT = 0x100, */ WIN_CTRL = 0x200, WIN_ALT = 0x400 };
enum { MAX_KEY = 256 };
enum { MAX_FUNCTION = 64 };
enum { MAX_DEFINITION = 256 };

enum { WINDOW_NAME_LENGTH	= 128 };
enum { CLASS_NAME_LENGTH	= 128 };
enum { SUB_KEY_NAME_LENGTH	= 128 };

enum ICON_TYPE { MAIN_ICON, CX_ICON, META_ICON, SHIFT_ICON, CTRL_ICON, ALT_ICON, MAX_ICON_TYPE };
enum XKEYMACS_STATUS { STATUS_ENABLE, STATUS_DISABLE_TMP, STATUS_DISABLE_WOCQ, STATUS_DISABLE, MAX_STATUS };
enum { ON_ICON, OFF_ICON };	// alias of status

enum GOTO { GOTO_DO_NOTHING, GOTO_HOOK, GOTO_RECURSIVE, GOTO_HOOKX, GOTO_HOOK0_9, CONTINUE };
enum SETTING_STYLE { SETTING_DEFAULT, SETTING_SPECIFIC, SETTING_DISABLE, SETTING_UNDEFINED };

enum { EXTENDED_KEY = 0x01000000 };
enum { REPEATED_KEY = 0x40000000 };
enum { BEING_RELEASED = 0x80000000 };

typedef struct KbdMacro
{
	int nCode;
	WPARAM wParam;
	LPARAM lParam;
	BOOL bOriginal;
} KbdMacro_t;

typedef struct Modifier {
	char *name;
	int id;
} Modifier_t;

static const Modifier_t Modifiers[] = {
//	{ "A-", ALT },
	{ "C-", CONTROL},
//	{ "H-", HYPER },
	{ "M-", META },
	{ "S-", SHIFT },
//	{ "s-", SUPER },
	{ "Ctrl+", WIN_CTRL },
	{ "Alt+", WIN_ALT },
};

typedef struct KeyName
{
	BYTE bVk;
	char *name;
} KeyName_t;

static const KeyName_t ControlCharacters[] = {
//	{ VK_LBUTTON,		"mouse-1" },				// does not work well
//	{ VK_RBUTTON,		"mouse-3" },				// does not work well
	{ VK_CANCEL,		"break" },
//	{ VK_MBUTTON,		"mouse-2" },				// does not work well
	{ VK_BACK,			"backspace" },
	{ VK_TAB,			"tab" },
	{ VK_RETURN,		"return" },
	{ VK_CAPITAL,		"capslock" },
	{ VK_KANA,			"kana" },
	{ VK_KANJI,			"kanji" },
	{ VK_ESCAPE,		"escape" },
	{ VK_CONVERT,		"convert" },
	{ VK_NONCONVERT,	"nonconvert" },
//	{ VK_SPACE,			"SPC" },					// [? ]
	{ VK_PRIOR,			"prior" },
	{ VK_NEXT,			"next" },
	{ VK_END,			"end" },
	{ VK_HOME,			"home" },
	{ VK_LEFT,			"left" },
	{ VK_UP,			"up" },
	{ VK_RIGHT,			"right" },
	{ VK_DOWN,			"down" },
	{ VK_SELECT,		"select" },
	{ VK_PRINT,			"print" },
	{ VK_EXECUTE,		"execute" },
	{ VK_SNAPSHOT,		"printscreen" },			// work as print
	{ VK_INSERT,		"insert" },
	{ VK_DELETE,		"delete" },
	{ VK_LWIN,			"lwindow" },
	{ VK_RWIN,			"rwindow" },
	{ VK_APPS,			"apps" },
	{ VK_SLEEP,			"sleep" },
	{ VK_NUMPAD0,		"kp-0" },
	{ VK_NUMPAD1,		"kp-1" },
	{ VK_NUMPAD2,		"kp-2" },
	{ VK_NUMPAD3,		"kp-3" },
	{ VK_NUMPAD4,		"kp-4" },
	{ VK_NUMPAD5,		"kp-5" },
	{ VK_NUMPAD6,		"kp-6" },
	{ VK_NUMPAD7,		"kp-7" },
	{ VK_NUMPAD8,		"kp-8" },
	{ VK_NUMPAD9,		"kp-9" },
	{ VK_MULTIPLY,		"kp-multiply" },
	{ VK_ADD,			"kp-add" },
	{ VK_SUBTRACT,		"kp-subtract" },
	{ VK_DECIMAL,		"kp-decimal" },
	{ VK_DIVIDE,		"kp-divide" },
//	{ VK_F1,			"f1" },						// FIXME
//	{ VK_F2,			"f2" },						// Move at the end of definition of funcgtion keys to keep away confliction f1/f2 and f1?/f2? by strncmp()
	{ VK_F3,			"f3" },
	{ VK_F4,			"f4" },
	{ VK_F5,			"f5" },
	{ VK_F6,			"f6" },
	{ VK_F7,			"f7" },
	{ VK_F8,			"f8" },
	{ VK_F9,			"f9" },
	{ VK_F10,			"f10" },
	{ VK_F11,			"f11" },
	{ VK_F12,			"f12" },
	{ VK_F13,			"f13" },
	{ VK_F14,			"f14" },
	{ VK_F15,			"f15" },
	{ VK_F16,			"f16" },
	{ VK_F17,			"f17" },
	{ VK_F18,			"f18" },
	{ VK_F19,			"f19" },
	{ VK_F20,			"f20" },
	{ VK_F21,			"f21" },
	{ VK_F22,			"f22" },
	{ VK_F23,			"f23" },
	{ VK_F24,			"f24" },
	{ VK_F1,			"f1" },
	{ VK_F2,			"f2" },
	{ VK_NUMLOCK,		"kp-numlock" },
	{ VK_SCROLL,		"scroll" },
	{ 0xa6,				"browser-back" },			// VK_BROWSER_BACK
	{ 0xa7,				"browser-forward" },		// VK_BROWSER_FORWARD
	{ 0xa8,				"browser-refresh" },		// VK_BROWSER_REFRESH
	{ 0xa9,				"browser-stop" },			// VK_BROWSER_STOP
	{ 0xaa,				"browser-search" },			// VK_BROWSER_SEARCH
	{ 0xab,				"browser-favorites" },		// VK_BROWSER_FAVORITES
	{ 0xac,				"browser-home"},			// VK_BROWSER_HOME
	{ 0xad,				"volume-mute" },			// VK_VOLUME_MUTE
	{ 0xae,				"volume-down" },			// VK_VOLUME_DOWN
	{ 0xaf,				"volume-up" },				// VK_VOLUME_UP
	{ 0xb0,				"media-next-track" },		// VK_MEDIA_NEXT_TRACK
	{ 0xb1,				"media-prev-track" },		// VK_MEDIA_PREV_TRACK
	{ 0xb2,				"media-stop" },				// VK_MEDIA_STOP
	{ 0xb3,				"media-play-pause" },		// VK_MEDIA_PLAY_PAUSE
	{ 0xb4,				"launch-mail" },			// VK_LAUNCH_MAIL
	{ 0xb5,				"launch-media-select" },	// VK_LAUNCH_MEDIA_SELECT
	{ 0xb6,				"launch-1" },				// VK_LAUNCH_APP1
	{ 0xb7,				"launch-2" },				// VK_LAUNCH_APP2
};

class AFX_EXT_CLASS CXkeymacsDll  
{
public:
//	static int m_nPassThrough;
	void AddAllShell_NotifyIcon();
	void DeleteAllShell_NotifyIcon();
	void SetKillRingMax(int nApplicationID, int nKillRingMax);
	void CXkeymacsDll::EnableShell_NotifyIcon(ICON_TYPE icon, BOOL bEnable);
	void SetNotifyIconData(ICON_TYPE icon, NOTIFYICONDATA stNtfyIcon, HICON hEnable, HICON hDisableTMP, HICON hDisableWOCQ, HICON hDisable, BOOL bEnable);
	void SetNotifyIconData(ICON_TYPE icon, NOTIFYICONDATA stNtfyIcon, HICON hOn, HICON hOff, BOOL bEnable);
	void Clear(int nApplicationID);
	BOOL IsKeyboardHook();
	void SetCommandID(int nApplicationID, int nCommandType, int nKey, int nCommandID);
	void SetApplicationName(int nApplicationID, CString szApplicationName);
	BOOL ReleaseKeyboardHook();
	void SetEnableCUA(int nApplicationID, BOOL bEnableCUA);
	void SetIgnoreUndefinedC_x(int nApplicationID, BOOL bIgnoreUndefinedC_x);
	void SetIgnoreUndefinedMetaCtrl(int nApplicationID, BOOL bIgnoreUndefinedMetaCtrl);
	BOOL SetKeyboardHook();
	void SetSettingStyle(int nApplicationID, int nSettingStyle);
	void SetUseDialogSetting(int nApplicationID, BOOL bUseDialogSetting);
	static void AddKillRing(BOOL bNewData = TRUE);
	static void CallMacro();
	static void ClearFunctionDefinition();
	static void DefiningMacro(BOOL bDefiningMacro);
	static void DepressKey(BYTE bVk, BOOL bOriginal = TRUE);
	static BOOL GetEnableCUA();
	static CClipboardSnap* GetKillRing(CClipboardSnap *pSnap, BOOL bForce = TRUE);
	static void IncreaseKillRingIndex(int nKillRing = 1);
	static BOOL IsDown(BYTE bVk, BOOL bPhysicalKey = TRUE);
	static void Kdu(BYTE bVk, DWORD n = 1, BOOL bOriginal = TRUE);
	static int ModifyShell_NotifyIcon(ICON_TYPE icon, BOOL bNewStatus);
	static void ReleaseKey(BYTE bVk);
	static void SetFunctionDefinition(int nFunctionID, CString szDefinition);
	static void SetFunctionKey(int nFunctionID, int nApplicationID, int nCommandType, int nKey);
	static void SetKeyboardHookFlag();
	static void SetKeyboardHookFlag(BOOL bFlag);
	CXkeymacsDll();
	virtual ~CXkeymacsDll();
private:
	static HHOOK m_hHookKeyboard;
	static HHOOK m_hHookCallWnd;
	static HHOOK m_hHookGetMessage;
	static HHOOK m_hHookShell;
	void AddShell_NotifyIcon(ICON_TYPE icon);
	void DeleteShell_NotifyIcon(ICON_TYPE icon);
	static BOOL DefiningMacro();
	static BOOL IsControl();
	static BOOL IsMeta();
	static void DoKeybd_event(BYTE bVk, DWORD dwFlags);
	static LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK ShellProc(int nCode, WPARAM wParam, LPARAM lParam);
	static void ParseKey(const int nFunctionID, unsigned int &i);
	static BYTE a2v(char nAscii);
	static BOOL IsShift(char nAscii);
	static void Kdu(int nCommandType, BYTE bVk);
	static char m_szFunctionDefinition[MAX_FUNCTION][MAX_DEFINITION];
	static void CallFunction(int nFunctionID);
	static int m_nFunctionID[MAX_APP][MAX_COMMAND_TYPE][MAX_KEY];
	static BOOL m_bEnableCUA[MAX_APP];
	static char m_szOldApplicationName[MAX_PATH];
	static char m_szApplicationName[MAX_PATH];
	static int IsPassThrough(BYTE nKey);
	static BOOL IsDepressedShiftKeyOnly(BYTE nKey);
	static BOOL IsFoo(BOOL bF_(), int Foo());
	static BOOL IsValidKey(BYTE bVk);
	static CObList m_Macro;
	static BOOL m_bDefiningMacro;
	static void Original(int nCommandType, BYTE bVk, int nOriginal);
	static int Original(int nCommandType, BYTE bVk);
	static HICON m_hIcon[MAX_ICON_TYPE][MAX_STATUS];
	static BOOL m_bUseDialogSetting[MAX_APP];
	static void InitKeyboardProc(BOOL bImeComposition);
	static BOOL m_bIgnoreUndefinedC_x[MAX_APP];
	static BOOL m_bIgnoreUndefinedMetaCtrl[MAX_APP];
	static int m_nSettingStyle[MAX_APP];
	static int m_nApplicationID;
	static int m_nOriginal[MAX_COMMAND_TYPE][MAX_KEY];
	static int m_nKillRing;
	static CList m_oKillRing;
	static int m_nKillRingMax[MAX_APP];
	static int GetMickey(int nDifferential, int nThreshold1, int nThreshold2, int nAcceleration, int nSpeed);
	static BOOL DoShell_NotifyIcon(ICON_TYPE icon, DWORD dwMessage);
	static BOOL m_bIcon[MAX_ICON_TYPE];
	static DWORD m_dwOldMessage[MAX_ICON_TYPE];
	static NOTIFYICONDATA m_stNtfyIcon[MAX_ICON_TYPE];
	static NOTIFYICONDATA m_stOldNtfyIcon[MAX_ICON_TYPE];
	static BOOL m_bHook;
	static BOOL m_bRightShift;
	static BOOL m_bRightAlt;
	static BOOL m_bRightControl;
	static char m_szSpecialApp[MAX_APP][CLASS_NAME_LENGTH];
	static int m_nCommandID[MAX_APP][MAX_COMMAND_TYPE][MAX_KEY];
};


class AFX_EXT_CLASS CXkeymacsData  
{
public:
	int GetWindowTextType();
	void SetWindowTextType(int nWindowTextType);
	CString GetWindowText();
	void SetWindowText(LPCTSTR lpszWindowText);
	static BOOL Is106Keyboard();
	static void Set106Keyboard(BOOL b106Keyboard);
	static int GetToolTipID(int nCommandID);
	static int GetDescriptionID(int nCommandID);
	void SetUseDialogSetting(BOOL bUseDialogSetting);
	BOOL GetUseDialogSetting();
	BOOL GetEnableCUA();
	void SetEnableCUA(BOOL bEnableCUA);
	BOOL GetIgnoreUndefinedC_x();
	void SetIgnoreUndefinedC_x(BOOL bIgnoreUndefinedC_x);
	BOOL GetIgnoreUndefinedMetaCtrl();
	void SetIgnoreUndefinedMetaCtrl(BOOL bIgnoreUndefinedMetaCtrl);
	static int GetCategoryID(int nCommandID);
	void SetSettingStyle(int nSettingStyle);
	int GetSettingStyle();
	static int GetDefaultControlID(int nCommandID, int nIndex);
	static int GetDefaultCommandKey(int nCommandID, int nIndex);
	static int GetDefaultCommandType(int nCommandID, int nIndex);
	static CString GetCommandName(int nCommandID);
	void SetKillRingMax(int nKillRingMax);
	int GetKillRingMax();
	CString GetApplicationTitle();
	void SetApplicationTitle(LPCTSTR lpszApplicationTitle);
	void ClearAll();
	int GetCommandID(int nCommandType, int nKey);
	void SetCommandID(int nCommandType, int nKey, int nCommandID);
	CString GetApplicationName();
	void SetApplicationName(LPCTSTR lpszApplicationName);
	CXkeymacsData();
	virtual ~CXkeymacsData();

private:
	int m_nWindowTextType;
	CString m_strWindowText;
	BOOL m_bEnableCUA;
	static BOOL m_b106Keyboard;
	BOOL m_bUseDialogSetting;
	BOOL m_bIgnoreUndefinedC_x;
	BOOL m_bIgnoreUndefinedMetaCtrl;
	int m_nSettingStyle;
	int m_nKillRingMax;
	CString m_strApplicationTitle;
	CString m_strApplicationName;
	int m_nCommandID[MAX_COMMAND_TYPE][MAX_KEY];
};

#endif // !defined(AFX_XKEYMACS_H__88552DEC_1233_4A0A_BE62_9EF7BC618EC6__INCLUDED_)

(C) 2001-2005 oishi@cam.hi-ho.ne.jp