From ba1083b4da33ca44a5ae7d90eabbe3d6d340a81e Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 17 May 2018 16:47:04 +0300 Subject: XSoundNotify, YAPP, YaRelay, ZeroSwitch, ZeroNotify -> CMPlugin --- plugins/XSoundNotify/src/dialog.cpp | 2 +- plugins/XSoundNotify/src/options.cpp | 2 +- plugins/XSoundNotify/src/stdafx.h | 9 +- plugins/XSoundNotify/src/xsn_main.cpp | 23 ++--- plugins/YAPP/src/icons.cpp | 4 +- plugins/YAPP/src/message_pump.cpp | 4 +- plugins/YAPP/src/notify_imp.cpp | 2 +- plugins/YAPP/src/options.cpp | 2 +- plugins/YAPP/src/services.cpp | 2 +- plugins/YAPP/src/stdafx.h | 15 ++-- plugins/YAPP/src/yapp.cpp | 27 +++--- plugins/YARelay/src/main.cpp | 48 +++++------ plugins/YARelay/src/options.cpp | 21 ++--- plugins/YARelay/src/stdafx.h | 28 +++--- plugins/ZeroNotification/src/main.cpp | 143 +++---------------------------- plugins/ZeroNotification/src/options.cpp | 143 +++++++++++++++++++++++++++++++ plugins/ZeroNotification/src/stdafx.h | 11 ++- plugins/ZeroSwitch/src/ZeroSwitch.cpp | 37 +++++--- plugins/ZeroSwitch/src/stdafx.h | 1 - 19 files changed, 289 insertions(+), 235 deletions(-) create mode 100644 plugins/ZeroNotification/src/options.cpp diff --git a/plugins/XSoundNotify/src/dialog.cpp b/plugins/XSoundNotify/src/dialog.cpp index 283aa78bdb..96d623ccbb 100644 --- a/plugins/XSoundNotify/src/dialog.cpp +++ b/plugins/XSoundNotify/src/dialog.cpp @@ -194,7 +194,7 @@ INT_PTR ShowDialog(WPARAM wParam, LPARAM) { HWND hChangeSoundDlg = WindowList_Find(hChangeSoundDlgList, wParam); if (!hChangeSoundDlg) { - hChangeSoundDlg = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_CONTACTS), nullptr, DlgProcContactsOptions, (LPARAM)wParam); + hChangeSoundDlg = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_CONTACTS), nullptr, DlgProcContactsOptions, (LPARAM)wParam); ShowWindow(hChangeSoundDlg, SW_SHOW); } else { diff --git a/plugins/XSoundNotify/src/options.cpp b/plugins/XSoundNotify/src/options.cpp index 0444d7c155..61d9505381 100644 --- a/plugins/XSoundNotify/src/options.cpp +++ b/plugins/XSoundNotify/src/options.cpp @@ -344,7 +344,7 @@ INT OptInit(WPARAM wParam, LPARAM) { OPTIONSDIALOGPAGE odp = { 0 }; odp.position = 100000000; - odp.hInstance = hInst; + odp.hInstance = g_plugin.getInst(); odp.flags = ODPF_BOLDGROUPS | ODPF_UNICODE; odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); odp.szGroup.w = LPGENW("Sounds"); diff --git a/plugins/XSoundNotify/src/stdafx.h b/plugins/XSoundNotify/src/stdafx.h index ea8008c8c6..8e147d857d 100644 --- a/plugins/XSoundNotify/src/stdafx.h +++ b/plugins/XSoundNotify/src/stdafx.h @@ -3,7 +3,6 @@ #include #include -#define __NO_CMPLUGIN_NEEDED #include #include #include @@ -23,6 +22,13 @@ #define SETTINGSKEY "XSNPlugin_sound" #define SETTINGSIGNOREKEY "XSNPlugin_ignore" +struct CMPlugin : public PLUGIN +{ + CMPlugin() : + PLUGIN(SETTINGSNAME) + {} +}; + struct XSN_Data { LPARAM hContact; @@ -41,7 +47,6 @@ struct XSN_Data extern LIST XSN_Users; -extern HINSTANCE hInst; extern MWindowList hChangeSoundDlgList; extern BYTE isIgnoreSound, isOwnSound; diff --git a/plugins/XSoundNotify/src/xsn_main.cpp b/plugins/XSoundNotify/src/xsn_main.cpp index e06c33a311..ca3dab258a 100644 --- a/plugins/XSoundNotify/src/xsn_main.cpp +++ b/plugins/XSoundNotify/src/xsn_main.cpp @@ -9,16 +9,19 @@ There is no warranty. #include "stdafx.h" -HINSTANCE hInst; int hLangpack; +CMPlugin g_plugin; +CHAT_MANAGER *pci; + LIST XSN_Users(10, NumericKeySortT); HGENMENU hChangeSound = nullptr; MWindowList hChangeSoundDlgList = nullptr; BYTE isIgnoreSound = 0, isOwnSound = 0, isIgnoreAccSound = 0, isAccSound = 0; -CHAT_MANAGER *pci; +///////////////////////////////////////////////////////////////////////////////////////// -PLUGININFOEX pluginInfo = { +PLUGININFOEX pluginInfo = +{ sizeof(PLUGININFOEX), __PLUGIN_NAME, PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), @@ -28,15 +31,9 @@ PLUGININFOEX pluginInfo = { __AUTHORWEB, UNICODE_AWARE, // {A01E25F7-A6EF-4B40-8CAC-755A2F2E55B5} - { 0xa01e25f7, 0xa6ef, 0x4b40,{ 0x8c, 0xac, 0x75, 0x5a, 0x2f, 0x2e, 0x55, 0xb5 } } + { 0xa01e25f7, 0xa6ef, 0x4b40,{ 0x8c, 0xac, 0x75, 0x5a, 0x2f, 0x2e, 0x55, 0xb5 }} }; -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD, LPVOID) -{ - hInst = hinstDLL; - return TRUE; -} - extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD) { return &pluginInfo; @@ -44,7 +41,8 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD) ///////////////////////////////////////////////////////////////////////////////////////// -struct { +struct +{ int iStatus; const char *szName; } @@ -190,6 +188,7 @@ static int OnPlaySound(WPARAM, LPARAM) { if (isIgnoreSound || isIgnoreAccSound) return 1; + if (isOwnSound) { isOwnSound = 0; return 1; @@ -255,6 +254,8 @@ extern "C" int __declspec(dllexport) Load() return 0; } +///////////////////////////////////////////////////////////////////////////////////////// + extern "C" int __declspec(dllexport) Unload(void) { WindowList_Destroy(hChangeSoundDlgList); diff --git a/plugins/YAPP/src/icons.cpp b/plugins/YAPP/src/icons.cpp index f9364cf47e..3de365b928 100644 --- a/plugins/YAPP/src/icons.cpp +++ b/plugins/YAPP/src/icons.cpp @@ -14,6 +14,6 @@ static IconItem iconList[] = void InitIcons() { - Icon_Register(hInst, SECT_TOLBAR, iconList, 2); - Icon_Register(hInst, SECT_POPUP, iconList+2, 3); + Icon_Register(g_plugin.getInst(), SECT_TOLBAR, iconList, 2); + Icon_Register(g_plugin.getInst(), SECT_POPUP, iconList+2, 3); } diff --git a/plugins/YAPP/src/message_pump.cpp b/plugins/YAPP/src/message_pump.cpp index 606401da6b..b6e62a415d 100644 --- a/plugins/YAPP/src/message_pump.cpp +++ b/plugins/YAPP/src/message_pump.cpp @@ -30,7 +30,7 @@ unsigned __stdcall MessagePumpThread(void* param) PopupData *pd = (PopupData*)hwndMsg.lParam; if (enabled && num_popups < MAX_POPUPS) { - HWND hwnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, POP_WIN_CLASS, L"Popup", WS_POPUP, 0, 0, 0, 0, nullptr, nullptr, hInst, (LPVOID)hwndMsg.lParam); + HWND hwnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, POP_WIN_CLASS, L"Popup", WS_POPUP, 0, 0, 0, 0, nullptr, nullptr, g_plugin.getInst(), (LPVOID)hwndMsg.lParam); num_popups++; if (hwndMsg.wParam) // set notifyer handle SendMessage(hwnd, PUM_SETNOTIFYH, hwndMsg.wParam, 0); @@ -91,7 +91,7 @@ void InitMessagePump() { WNDCLASS popup_win_class = { 0 }; popup_win_class.lpfnWndProc = PopupWindowProc; - popup_win_class.hInstance = hInst; + popup_win_class.hInstance = g_plugin.getInst(); popup_win_class.lpszClassName = POP_WIN_CLASS; popup_win_class.hCursor = LoadCursor(nullptr, IDC_ARROW); RegisterClass(&popup_win_class); diff --git a/plugins/YAPP/src/notify_imp.cpp b/plugins/YAPP/src/notify_imp.cpp index ccf5046923..ed7d92bdc2 100644 --- a/plugins/YAPP/src/notify_imp.cpp +++ b/plugins/YAPP/src/notify_imp.cpp @@ -95,7 +95,7 @@ INT_PTR CALLBACK DlgProcPopups(HWND hwnd, UINT msg, WPARAM, LPARAM lParam) int NotifyOptionsInitialize(WPARAM wParam, LPARAM) { OPTIONSDIALOGPAGE odp = { 0 }; - odp.hInstance = hInst; + odp.hInstance = g_plugin.getInst(); odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_NOTIFY); odp.szTitle.a = LPGEN("YAPP Popups"); odp.flags = ODPF_BOLDGROUPS; diff --git a/plugins/YAPP/src/options.cpp b/plugins/YAPP/src/options.cpp index c0ae8295c6..c02a3a17e5 100644 --- a/plugins/YAPP/src/options.cpp +++ b/plugins/YAPP/src/options.cpp @@ -475,7 +475,7 @@ int OptInit(WPARAM wParam, LPARAM) OPTIONSDIALOGPAGE odp = { 0 }; odp.flags = ODPF_BOLDGROUPS; odp.position = -790000000; - odp.hInstance = hInst; + odp.hInstance = g_plugin.getInst(); odp.szTitle.a = LPGEN("Popups"); odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT1); diff --git a/plugins/YAPP/src/services.cpp b/plugins/YAPP/src/services.cpp index a3d2ace7b4..a2951cb6ec 100644 --- a/plugins/YAPP/src/services.cpp +++ b/plugins/YAPP/src/services.cpp @@ -317,7 +317,7 @@ static INT_PTR ShowMessageW(WPARAM wParam, LPARAM lParam) INT_PTR Popup_ShowHistory(WPARAM, LPARAM) { if (!hHistoryWindow) - hHistoryWindow = CreateDialog(hInst, MAKEINTRESOURCE(IDD_LST_HISTORY), nullptr, DlgProcHistLst); + hHistoryWindow = CreateDialog(g_plugin.getInst(), MAKEINTRESOURCE(IDD_LST_HISTORY), nullptr, DlgProcHistLst); ShowWindow(hHistoryWindow, SW_SHOW); return 0; diff --git a/plugins/YAPP/src/stdafx.h b/plugins/YAPP/src/stdafx.h index 7309ef7413..d1475a724d 100644 --- a/plugins/YAPP/src/stdafx.h +++ b/plugins/YAPP/src/stdafx.h @@ -13,7 +13,6 @@ #include #include -#define __NO_CMPLUGIN_NEEDED #include #include #include @@ -43,10 +42,16 @@ #define MODULE "YAPP" -extern HMODULE hInst; -extern bool bShutdown; +struct CMPlugin : public PLUGIN +{ + CMPlugin() : + PLUGIN(MODULE) + {} +}; -extern HFONT hFontFirstLine, hFontSecondLine, hFontTime; +extern bool bShutdown; + +extern HFONT hFontFirstLine, hFontSecondLine, hFontTime; extern COLORREF colFirstLine, colSecondLine, colBg, colTime, colBorder, colSidebar, colTitleUnderline; extern MNOTIFYLINK *notifyLink; @@ -70,4 +75,4 @@ typedef int (CALLBACK *PFNLVCOMPARE)(LPARAM, LPARAM, LPARAM); #define PDF_TCHAR PDF_UNICODE -void ShowPopup(PopupData &pd_in); \ No newline at end of file +void ShowPopup(PopupData &pd_in); diff --git a/plugins/YAPP/src/yapp.cpp b/plugins/YAPP/src/yapp.cpp index abf01aeb67..c00ce0989c 100644 --- a/plugins/YAPP/src/yapp.cpp +++ b/plugins/YAPP/src/yapp.cpp @@ -3,7 +3,7 @@ #include "stdafx.h" -HMODULE hInst = nullptr; +CMPlugin g_plugin; bool bShutdown = false; MNOTIFYLINK *notifyLink = nullptr; @@ -28,7 +28,10 @@ HANDLE hTTButton; // menu items HGENMENU hMenuRoot, hMenuItem, hMenuItemHistory; -PLUGININFOEX pluginInfo={ +///////////////////////////////////////////////////////////////////////////////////////// + +PLUGININFOEX pluginInfo = +{ sizeof(PLUGININFOEX), __PLUGIN_NAME, PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), @@ -41,18 +44,14 @@ PLUGININFOEX pluginInfo={ {0xefd15f16, 0x7ae4, 0x40d7, {0xa8, 0xe3, 0xa4, 0x11, 0xed, 0x74, 0x7b, 0xd5}} }; -BOOL WINAPI DllMain(HMODULE hModule, DWORD, LPVOID) -{ - hInst = hModule; - return TRUE; -} - extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD) { return &pluginInfo; } -int ReloadFont(WPARAM, LPARAM) +///////////////////////////////////////////////////////////////////////////////////////// + +static int ReloadFont(WPARAM, LPARAM) { LOGFONT log_font; if (hFontFirstLine) DeleteObject(hFontFirstLine); @@ -72,7 +71,7 @@ int ReloadFont(WPARAM, LPARAM) return 0; } -int TTBLoaded(WPARAM, LPARAM) +static int TTBLoaded(WPARAM, LPARAM) { TTBButton ttb = {}; ttb.pszService = "Popup/EnableDisableMenuCommand"; @@ -163,7 +162,7 @@ static void InitFonts() ReloadFont(0, 0); } -void InitMenuItems(void) +static void InitMenuItems(void) { bool isEnabled = db_get_b(0, "Popup", "ModuleIsEnabled", 1) == 1; @@ -187,7 +186,7 @@ void InitMenuItems(void) hMenuItem = Menu_AddMainMenuItem(&mi); } -int ModulesLoaded(WPARAM, LPARAM) +static int ModulesLoaded(WPARAM, LPARAM) { MNotifyGetLink(); @@ -205,7 +204,7 @@ int ModulesLoaded(WPARAM, LPARAM) return 0; } -int PreShutdown(WPARAM, LPARAM) +static int PreShutdown(WPARAM, LPARAM) { bShutdown = true; DeinitMessagePump(); @@ -229,6 +228,8 @@ extern "C" int __declspec(dllexport) Load(void) return 0; } +///////////////////////////////////////////////////////////////////////////////////////// + extern "C" int __declspec(dllexport) Unload() { DeleteObject(hFontFirstLine); diff --git a/plugins/YARelay/src/main.cpp b/plugins/YARelay/src/main.cpp index d0feea1c5f..4aba06bdb5 100644 --- a/plugins/YARelay/src/main.cpp +++ b/plugins/YARelay/src/main.cpp @@ -21,7 +21,7 @@ Features: #include "../../utils/mir_buffer.h" -HINSTANCE hInst; +CMPlugin g_plugin; int hLangpack; MCONTACT hForwardFrom, hForwardTo; @@ -30,6 +30,8 @@ int iSplit, iSplitMaxSize, iSendParts, iMarkRead, iSendAndHistory, iForwardOnSta LIST arMessageProcs(10, HandleKeySortT); +///////////////////////////////////////////////////////////////////////////////////////// + PLUGININFOEX pluginInfoEx = { sizeof(PLUGININFOEX), __PLUGIN_NAME, @@ -43,15 +45,14 @@ PLUGININFOEX pluginInfoEx = { {0x1202e6a, 0xc1b3, 0x42e5, {0x83, 0x8a, 0x3e, 0x49, 0x7b, 0x31, 0xf3, 0x8e}} }; -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD, LPVOID) +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD) { - hInst=hinstDLL; - return TRUE; + return &pluginInfoEx; } -/** -* Protocols acknowledgement -*/ +///////////////////////////////////////////////////////////////////////////////////////// +// Protocols acknowledgement + int ProtoAck(WPARAM,LPARAM lparam) { ACKDATA *pAck = (ACKDATA *)lparam; @@ -67,7 +68,7 @@ int ProtoAck(WPARAM,LPARAM lparam) time(<ime); DBEVENTINFO dbei = {}; - dbei.szModule = "yaRelay"; + dbei.szModule = MODULENAME; dbei.timestamp = ltime; dbei.flags = DBEF_SENT | DBEF_UTF; dbei.eventType = EVENTTYPE_MESSAGE; @@ -82,9 +83,9 @@ int ProtoAck(WPARAM,LPARAM lparam) return 0; } -/** -* New event was added into DB. -*/ +///////////////////////////////////////////////////////////////////////////////////////// +// New event was added into DB. + static int MessageEventAdded(WPARAM hContact, LPARAM hDBEvent) { // is the message sender accepted for forwarding @@ -212,33 +213,30 @@ static int MessageEventAdded(WPARAM hContact, LPARAM hDBEvent) return 0; } -extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD) -{ - return &pluginInfoEx; -} +///////////////////////////////////////////////////////////////////////////////////////// extern "C" int __declspec(dllexport) Load() { mir_getLP(&pluginInfoEx); // Load plugin options from DB - hForwardFrom = (MCONTACT)db_get_dw(NULL, "yaRelay", "ForwardFrom", 0); - hForwardTo = (MCONTACT)db_get_dw(NULL, "yaRelay", "ForwardTo", 0); + hForwardFrom = (MCONTACT)db_get_dw(NULL, MODULENAME, "ForwardFrom", 0); + hForwardTo = (MCONTACT)db_get_dw(NULL, MODULENAME, "ForwardTo", 0); - iForwardOnStatus = db_get_dw(NULL, "yaRelay", "ForwardOnStatus", STATUS_OFFLINE | STATUS_AWAY | STATUS_NA); + iForwardOnStatus = db_get_dw(NULL, MODULENAME, "ForwardOnStatus", STATUS_OFFLINE | STATUS_AWAY | STATUS_NA); - wchar_t *szForwardTemplate = db_get_wsa(NULL, "yaRelay", "ForwardTemplate"); + wchar_t *szForwardTemplate = db_get_wsa(NULL, MODULENAME, "ForwardTemplate"); if (szForwardTemplate){ wcsncpy(tszForwardTemplate, szForwardTemplate, _countof(tszForwardTemplate)); mir_free(szForwardTemplate); } else wcsncpy(tszForwardTemplate, L"%u: %m", MAXTEMPLATESIZE-1); - iSplit = db_get_dw(NULL, "yaRelay", "Split", 0); - iSplitMaxSize = db_get_dw(NULL, "yaRelay", "SplitMaxSize", 100); - iSendParts = db_get_dw(NULL, "yaRelay", "SendParts", 0); - iMarkRead = db_get_dw(NULL, "yaRelay", "MarkRead", 0); - iSendAndHistory = db_get_dw(NULL, "yaRelay", "SendAndHistory", 1); + iSplit = db_get_dw(NULL, MODULENAME, "Split", 0); + iSplitMaxSize = db_get_dw(NULL, MODULENAME, "SplitMaxSize", 100); + iSendParts = db_get_dw(NULL, MODULENAME, "SendParts", 0); + iMarkRead = db_get_dw(NULL, MODULENAME, "MarkRead", 0); + iSendAndHistory = db_get_dw(NULL, MODULENAME, "SendAndHistory", 1); // hook events HookEvent(ME_DB_EVENT_ADDED, MessageEventAdded); @@ -247,6 +245,8 @@ extern "C" int __declspec(dllexport) Load() return 0; } +///////////////////////////////////////////////////////////////////////////////////////// + extern "C" int __declspec(dllexport) Unload(void) { return 0; diff --git a/plugins/YARelay/src/options.cpp b/plugins/YARelay/src/options.cpp index 86d9ad6028..2ce13a9d78 100644 --- a/plugins/YARelay/src/options.cpp +++ b/plugins/YARelay/src/options.cpp @@ -168,15 +168,15 @@ static INT_PTR CALLBACK OptionsFrameProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, iSplitMaxSize = 1; // write to database - db_set_dw(NULL, "yaRelay", "ForwardFrom", (DWORD)hForwardFrom); - db_set_dw(NULL, "yaRelay", "ForwardTo", (DWORD)hForwardTo); - db_set_dw(NULL, "yaRelay", "ForwardOnStatus", iForwardOnStatus); - db_set_ws(NULL, "yaRelay", "ForwardTemplate", tszForwardTemplate); - db_set_dw(NULL, "yaRelay", "Split", iSplit); - db_set_dw(NULL, "yaRelay", "SplitMaxSize", iSplitMaxSize); - db_set_dw(NULL, "yaRelay", "SendParts", iSendParts); - db_set_dw(NULL, "yaRelay", "MarkRead", iMarkRead); - db_set_dw(NULL, "yaRelay", "SendAndHistory", iSendAndHistory); + db_set_dw(NULL, MODULENAME, "ForwardFrom", (DWORD)hForwardFrom); + db_set_dw(NULL, MODULENAME, "ForwardTo", (DWORD)hForwardTo); + db_set_dw(NULL, MODULENAME, "ForwardOnStatus", iForwardOnStatus); + db_set_ws(NULL, MODULENAME, "ForwardTemplate", tszForwardTemplate); + db_set_dw(NULL, MODULENAME, "Split", iSplit); + db_set_dw(NULL, MODULENAME, "SplitMaxSize", iSplitMaxSize); + db_set_dw(NULL, MODULENAME, "SendParts", iSendParts); + db_set_dw(NULL, MODULENAME, "MarkRead", iMarkRead); + db_set_dw(NULL, MODULENAME, "SendAndHistory", iSendAndHistory); return TRUE; } break; @@ -188,10 +188,11 @@ static INT_PTR CALLBACK OptionsFrameProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, /** * Init options panel */ + int OptionsInit(WPARAM wParam, LPARAM) { OPTIONSDIALOGPAGE odp = { 0 }; - odp.hInstance = hInst; + odp.hInstance = g_plugin.getInst(); odp.position = -1; odp.szGroup.a = LPGEN("Message sessions"); odp.pszTemplate = MAKEINTRESOURCEA(IDD_SETTINGS); diff --git a/plugins/YARelay/src/stdafx.h b/plugins/YARelay/src/stdafx.h index a185b39742..2d76fcbfaa 100644 --- a/plugins/YARelay/src/stdafx.h +++ b/plugins/YARelay/src/stdafx.h @@ -23,7 +23,6 @@ Features: #include #include -#define __NO_CMPLUGIN_NEEDED #include #include #include @@ -36,18 +35,25 @@ Features: #include "resource.h" #include "version.h" -#define STATUS_OFFLINE 0x1 -#define STATUS_ONLINE 0x2 -#define STATUS_AWAY 0x4 -#define STATUS_NA 0x8 -#define STATUS_OCCUPIED 0x10 -#define STATUS_DND 0x20 -#define STATUS_FREECHAT 0x40 -#define STATUS_INVISIBLE 0x80 +#define STATUS_OFFLINE 0x1 +#define STATUS_ONLINE 0x2 +#define STATUS_AWAY 0x4 +#define STATUS_NA 0x8 +#define STATUS_OCCUPIED 0x10 +#define STATUS_DND 0x20 +#define STATUS_FREECHAT 0x40 +#define STATUS_INVISIBLE 0x80 -#define MAXTEMPLATESIZE 1024 +#define MAXTEMPLATESIZE 1024 -extern HINSTANCE hInst; +#define MODULENAME "yaRelay" + +struct CMPlugin : public PLUGIN +{ + CMPlugin() : + PLUGIN(MODULENAME) + {} +}; extern MCONTACT hForwardFrom, hForwardTo; extern wchar_t tszForwardTemplate[MAXTEMPLATESIZE]; diff --git a/plugins/ZeroNotification/src/main.cpp b/plugins/ZeroNotification/src/main.cpp index b92f20bc6a..cb6bafbf0b 100644 --- a/plugins/ZeroNotification/src/main.cpp +++ b/plugins/ZeroNotification/src/main.cpp @@ -8,27 +8,13 @@ https://miranda-ng.org/ #include "stdafx.h" -HINSTANCE hInst; +CMPlugin g_plugin; HGENMENU noSoundMenu; int hLangpack; -struct CheckBoxValues_t -{ - DWORD style; - wchar_t *szDescr; -}; +int OptionsInitialize(WPARAM, LPARAM); -static const struct CheckBoxValues_t statusValues[] = { - { PF2_ONLINE, TEXT("Online") }, - { PF2_SHORTAWAY, TEXT("Away") }, - { PF2_LONGAWAY, TEXT("Not available") }, - { PF2_LIGHTDND, TEXT("Occupied") }, - { PF2_HEAVYDND, TEXT("Do not disturb") }, - { PF2_FREECHAT, TEXT("Free for chat") }, - { PF2_INVISIBLE, TEXT("Invisible") }, - { PF2_OUTTOLUNCH, TEXT("Out to lunch") }, - { PF2_ONTHEPHONE, TEXT("On the phone") } -}; +///////////////////////////////////////////////////////////////////////////////////////// PLUGININFOEX pluginInfoEx = { sizeof(PLUGININFOEX), @@ -48,50 +34,15 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD) return &pluginInfoEx; } -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD, LPVOID) -{ - hInst = hinstDLL; - return TRUE; -} - -static void FillCheckBoxTree(HWND hwndTree, const struct CheckBoxValues_t *values, int nValues, DWORD style) -{ - TVINSERTSTRUCT tvis; - tvis.hParent = nullptr; - tvis.hInsertAfter = TVI_LAST; - tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_STATE; - for (int i = 0; i < nValues; i++) { - tvis.item.lParam = values[i].style; - tvis.item.pszText = TranslateW(values[i].szDescr); - tvis.item.stateMask = TVIS_STATEIMAGEMASK; - tvis.item.state = INDEXTOSTATEIMAGEMASK((style&tvis.item.lParam) != 0 ? 2 : 1); - TreeView_InsertItem(hwndTree, &tvis); - } -} - -static DWORD MakeCheckBoxTreeFlags(HWND hwndTree) -{ - DWORD flags = 0; - - TVITEM tvi; - tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_STATE; - tvi.hItem = TreeView_GetRoot(hwndTree); - while (tvi.hItem) { - TreeView_GetItem(hwndTree, &tvi); - if (((tvi.state & TVIS_STATEIMAGEMASK) >> 12 == 2)) - flags |= tvi.lParam; - tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem); - } - return flags; -} +///////////////////////////////////////////////////////////////////////////////////////// +// Update the name on the menu -//Update the name on the menu static void UpdateMenuItem() { Menu_ModifyItem(noSoundMenu, db_get_b(NULL, "Skin", "UseSound", 1) ? DISABLE_SOUND : ENABLE_SOUND); } -//Called when the sound setting in the database is changed +// Called when the sound setting in the database is changed static int SoundSettingChanged(WPARAM, LPARAM lParam) { DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam; @@ -100,7 +51,7 @@ static int SoundSettingChanged(WPARAM, LPARAM lParam) return 0; } -static int SetNotify(const long status) +int SetNotify(const long status) { db_set_b(NULL, "Skin", "UseSound", (BYTE)!(db_get_dw(NULL, MODNAME, "NoSound", DEFAULT_NOSOUND) & status)); db_set_b(NULL, "CList", "DisableTrayFlash", (BYTE)(db_get_dw(NULL, MODNAME, "NoBlink", DEFAULT_NOBLINK) & status)); @@ -110,7 +61,7 @@ static int SetNotify(const long status) return 0; } -//Called whenever a change in status is detected +// Called whenever a change in status is detected static int ProtoAck(WPARAM, LPARAM lParam) { // quit if not status event @@ -126,82 +77,6 @@ static int ProtoAck(WPARAM, LPARAM lParam) return 0; } -static INT_PTR CALLBACK DlgProcNoSoundOpts(HWND hwndDlg, UINT msg, WPARAM, LPARAM lParam) -{ - DWORD test; - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_NOSOUND), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_NOSOUND), GWL_STYLE) | TVS_NOHSCROLL | TVS_CHECKBOXES); - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_NOBLINK), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_NOBLINK), GWL_STYLE) | TVS_NOHSCROLL | TVS_CHECKBOXES); - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_NOCLCBLINK), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_NOCLCBLINK), GWL_STYLE) | TVS_NOHSCROLL | TVS_CHECKBOXES); - CheckDlgButton(hwndDlg, IDC_HIDEMENU, db_get_b(NULL, MODNAME, "HideMenu", 1) ? BST_CHECKED : BST_UNCHECKED); - - FillCheckBoxTree(GetDlgItem(hwndDlg, IDC_NOSOUND), statusValues, sizeof(statusValues) / sizeof(statusValues[0]), db_get_dw(NULL, MODNAME, "NoSound", DEFAULT_NOSOUND)); - FillCheckBoxTree(GetDlgItem(hwndDlg, IDC_NOBLINK), statusValues, sizeof(statusValues) / sizeof(statusValues[0]), db_get_dw(NULL, MODNAME, "NoBlink", DEFAULT_NOBLINK)); - FillCheckBoxTree(GetDlgItem(hwndDlg, IDC_NOCLCBLINK), statusValues, sizeof(statusValues) / sizeof(statusValues[0]), db_get_dw(NULL, MODNAME, "NoCLCBlink", DEFAULT_NOCLCBLINK)); - return TRUE; - - case WM_COMMAND: - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->idFrom) { - case IDC_NOSOUND: - case IDC_NOBLINK: - case IDC_NOCLCBLINK: - if (((LPNMHDR)lParam)->code == NM_CLICK) { - TVHITTESTINFO hti; - hti.pt.x = (short)LOWORD(GetMessagePos()); - hti.pt.y = (short)HIWORD(GetMessagePos()); - ScreenToClient(((LPNMHDR)lParam)->hwndFrom, &hti.pt); - if (TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom, &hti)) { - if (hti.flags & TVHT_ONITEMSTATEICON) { - TVITEM tvi; - tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; - tvi.hItem = hti.hItem; - TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); - tvi.iImage = tvi.iSelectedImage = tvi.iImage == 1 ? 2 : 1; - TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - } - break; - case 0: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - db_set_b(NULL, MODNAME, "HideMenu", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_HIDEMENU)); - - db_set_dw(NULL, MODNAME, "NoSound", MakeCheckBoxTreeFlags(GetDlgItem(hwndDlg, IDC_NOSOUND))); - db_set_dw(NULL, MODNAME, "NoBlink", MakeCheckBoxTreeFlags(GetDlgItem(hwndDlg, IDC_NOBLINK))); - db_set_dw(NULL, MODNAME, "NoCLCBlink", MakeCheckBoxTreeFlags(GetDlgItem(hwndDlg, IDC_NOCLCBLINK))); - - test = db_get_w(NULL, "CList", "Status", 0); - SetNotify(Proto_Status2Flag(db_get_w(NULL, "CList", "Status", 0))); - return TRUE; - } - break; - } - } - return FALSE; -} - -static int OptionsInitialize(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.position = 100000000; - odp.hInstance = hInst; - odp.flags = ODPF_UNICODE; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_NOSOUND); - odp.szTitle.w = LPGENW("Zero Notifications"); - odp.szGroup.w = LPGENW("Plugins"); - odp.pfnDlgProc = DlgProcNoSoundOpts; - Options_AddPage(wParam, &odp); - return 0; -} - static INT_PTR NoSoundMenuCommand(WPARAM, LPARAM) { bool useSound = db_get_b(0, "Skin", "UseSound", true); @@ -234,6 +109,8 @@ extern "C" __declspec(dllexport) int Load(void) return 0; } +///////////////////////////////////////////////////////////////////////////////////////// + extern "C" __declspec(dllexport) int Unload(void) { return 0; diff --git a/plugins/ZeroNotification/src/options.cpp b/plugins/ZeroNotification/src/options.cpp new file mode 100644 index 0000000000..9daa6886f2 --- /dev/null +++ b/plugins/ZeroNotification/src/options.cpp @@ -0,0 +1,143 @@ +/* +Copyright (C) 2012-18 Miranda NG team (https://miranda-ng.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "stdafx.h" + +struct CheckBoxValues_t +{ + DWORD style; + wchar_t *szDescr; +} +static const statusValues[] = +{ + { PF2_ONLINE, TEXT("Online") }, + { PF2_SHORTAWAY, TEXT("Away") }, + { PF2_LONGAWAY, TEXT("Not available") }, + { PF2_LIGHTDND, TEXT("Occupied") }, + { PF2_HEAVYDND, TEXT("Do not disturb") }, + { PF2_FREECHAT, TEXT("Free for chat") }, + { PF2_INVISIBLE, TEXT("Invisible") }, + { PF2_OUTTOLUNCH, TEXT("Out to lunch") }, + { PF2_ONTHEPHONE, TEXT("On the phone") } +}; + +static void FillCheckBoxTree(HWND hwndTree, const struct CheckBoxValues_t *values, int nValues, DWORD style) +{ + TVINSERTSTRUCT tvis; + tvis.hParent = nullptr; + tvis.hInsertAfter = TVI_LAST; + tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_STATE; + for (int i = 0; i < nValues; i++) { + tvis.item.lParam = values[i].style; + tvis.item.pszText = TranslateW(values[i].szDescr); + tvis.item.stateMask = TVIS_STATEIMAGEMASK; + tvis.item.state = INDEXTOSTATEIMAGEMASK((style & tvis.item.lParam) != 0 ? 2 : 1); + TreeView_InsertItem(hwndTree, &tvis); + } +} + +static DWORD MakeCheckBoxTreeFlags(HWND hwndTree) +{ + DWORD flags = 0; + + TVITEM tvi; + tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_STATE; + tvi.hItem = TreeView_GetRoot(hwndTree); + while (tvi.hItem) { + TreeView_GetItem(hwndTree, &tvi); + if (((tvi.state & TVIS_STATEIMAGEMASK) >> 12 == 2)) + flags |= tvi.lParam; + tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem); + } + return flags; +} + +static INT_PTR CALLBACK DlgProcNoSoundOpts(HWND hwndDlg, UINT msg, WPARAM, LPARAM lParam) +{ + DWORD test; + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_NOSOUND), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_NOSOUND), GWL_STYLE) | TVS_NOHSCROLL | TVS_CHECKBOXES); + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_NOBLINK), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_NOBLINK), GWL_STYLE) | TVS_NOHSCROLL | TVS_CHECKBOXES); + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_NOCLCBLINK), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_NOCLCBLINK), GWL_STYLE) | TVS_NOHSCROLL | TVS_CHECKBOXES); + CheckDlgButton(hwndDlg, IDC_HIDEMENU, db_get_b(NULL, MODNAME, "HideMenu", 1) ? BST_CHECKED : BST_UNCHECKED); + + FillCheckBoxTree(GetDlgItem(hwndDlg, IDC_NOSOUND), statusValues, sizeof(statusValues) / sizeof(statusValues[0]), db_get_dw(NULL, MODNAME, "NoSound", DEFAULT_NOSOUND)); + FillCheckBoxTree(GetDlgItem(hwndDlg, IDC_NOBLINK), statusValues, sizeof(statusValues) / sizeof(statusValues[0]), db_get_dw(NULL, MODNAME, "NoBlink", DEFAULT_NOBLINK)); + FillCheckBoxTree(GetDlgItem(hwndDlg, IDC_NOCLCBLINK), statusValues, sizeof(statusValues) / sizeof(statusValues[0]), db_get_dw(NULL, MODNAME, "NoCLCBlink", DEFAULT_NOCLCBLINK)); + return TRUE; + + case WM_COMMAND: + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + + case WM_NOTIFY: + switch (((LPNMHDR)lParam)->idFrom) { + case IDC_NOSOUND: + case IDC_NOBLINK: + case IDC_NOCLCBLINK: + if (((LPNMHDR)lParam)->code == NM_CLICK) { + TVHITTESTINFO hti; + hti.pt.x = (short)LOWORD(GetMessagePos()); + hti.pt.y = (short)HIWORD(GetMessagePos()); + ScreenToClient(((LPNMHDR)lParam)->hwndFrom, &hti.pt); + if (TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom, &hti)) { + if (hti.flags & TVHT_ONITEMSTATEICON) { + TVITEM tvi; + tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvi.hItem = hti.hItem; + TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); + tvi.iImage = tvi.iSelectedImage = tvi.iImage == 1 ? 2 : 1; + TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + } + break; + case 0: + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + db_set_b(NULL, MODNAME, "HideMenu", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_HIDEMENU)); + + db_set_dw(NULL, MODNAME, "NoSound", MakeCheckBoxTreeFlags(GetDlgItem(hwndDlg, IDC_NOSOUND))); + db_set_dw(NULL, MODNAME, "NoBlink", MakeCheckBoxTreeFlags(GetDlgItem(hwndDlg, IDC_NOBLINK))); + db_set_dw(NULL, MODNAME, "NoCLCBlink", MakeCheckBoxTreeFlags(GetDlgItem(hwndDlg, IDC_NOCLCBLINK))); + + test = db_get_w(NULL, "CList", "Status", 0); + SetNotify(Proto_Status2Flag(db_get_w(NULL, "CList", "Status", 0))); + return TRUE; + } + break; + } + } + return FALSE; +} + +int OptionsInitialize(WPARAM wParam, LPARAM) +{ + OPTIONSDIALOGPAGE odp = { 0 }; + odp.position = 100000000; + odp.hInstance = g_plugin.getInst(); + odp.flags = ODPF_UNICODE; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_NOSOUND); + odp.szTitle.w = LPGENW("Zero Notifications"); + odp.szGroup.w = LPGENW("Plugins"); + odp.pfnDlgProc = DlgProcNoSoundOpts; + Options_AddPage(wParam, &odp); + return 0; +} diff --git a/plugins/ZeroNotification/src/stdafx.h b/plugins/ZeroNotification/src/stdafx.h index fa2de8828f..c9b6406e2b 100644 --- a/plugins/ZeroNotification/src/stdafx.h +++ b/plugins/ZeroNotification/src/stdafx.h @@ -3,7 +3,6 @@ #include #include -#define __NO_CMPLUGIN_NEEDED #include #include #include @@ -14,7 +13,14 @@ #include "version.h" #include "resource.h" -#define MODNAME "ZeroNotify" +#define MODNAME "ZeroNotify" + +struct CMPlugin : public PLUGIN +{ + CMPlugin() : + PLUGIN(MODNAME) + {} +}; #define DEFAULT_NOSOUND 0x00000000 #define DEFAULT_NOBLINK 0x00000000 @@ -23,3 +29,4 @@ #define DISABLE_SOUND LPGENW("Disable &Sounds") #define ENABLE_SOUND LPGENW("Enable &Sounds") +int SetNotify(const long status); diff --git a/plugins/ZeroSwitch/src/ZeroSwitch.cpp b/plugins/ZeroSwitch/src/ZeroSwitch.cpp index 1230b92a2e..1c26de1e98 100644 --- a/plugins/ZeroSwitch/src/ZeroSwitch.cpp +++ b/plugins/ZeroSwitch/src/ZeroSwitch.cpp @@ -3,12 +3,21 @@ #include "stdafx.h" -HINSTANCE hInst; +struct CMPlugin : public PLUGIN +{ + CMPlugin() : + PLUGIN(nullptr) + {} +} +g_plugin; + HHOOK hHook; HWND hDummyWnd = nullptr, hHelperWnd = nullptr, hMirandaWnd = nullptr; int hLangpack; CLIST_INTERFACE *pcli; +///////////////////////////////////////////////////////////////////////////////////////// + PLUGININFOEX pluginInfo = { sizeof(PLUGININFOEX), __PLUGIN_NAME, @@ -22,17 +31,13 @@ PLUGININFOEX pluginInfo = { { 0x3f1657b1, 0x69cb, 0x4992, { 0x9c, 0xfc, 0x22, 0x6c, 0x80, 0x8a, 0x52, 0x2 } } }; -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD, LPVOID) -{ - hInst = hinstDLL; - return TRUE; -} - extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD) { return &pluginInfo; } +///////////////////////////////////////////////////////////////////////////////////////// + LRESULT CALLBACK HelperProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) @@ -73,7 +78,7 @@ void CreateHelperWnd() wcex.lpfnWndProc = HelperProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; - wcex.hInstance = hInst; + wcex.hInstance = g_plugin.getInst(); wcex.hIcon = Skin_LoadIcon(SKINICON_OTHER_MIRANDA, true); wcex.hCursor = nullptr; wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); @@ -84,14 +89,14 @@ void CreateHelperWnd() if (NULL == RegisterClassEx(&wcex)) return; // wtf - hDummyWnd = CreateWindow(L"ZeroSwitchHlp", L"", WS_POPUP, 0, 0, 0, 0, nullptr, nullptr, hInst, nullptr); + hDummyWnd = CreateWindow(L"ZeroSwitchHlp", L"", WS_POPUP, 0, 0, 0, 0, nullptr, nullptr, g_plugin.getInst(), nullptr); if (!hDummyWnd) - UnregisterClass(L"ZeroSwitchHlp", hInst); - hHelperWnd = CreateWindow(L"ZeroSwitchHlp", L"Miranda NG", WS_OVERLAPPEDWINDOW | WS_VISIBLE, -100, -100, 90, 90, hDummyWnd, nullptr, hInst, nullptr); + UnregisterClass(L"ZeroSwitchHlp", g_plugin.getInst()); + hHelperWnd = CreateWindow(L"ZeroSwitchHlp", L"Miranda NG", WS_OVERLAPPEDWINDOW | WS_VISIBLE, -100, -100, 90, 90, hDummyWnd, nullptr, g_plugin.getInst(), nullptr); if (!hHelperWnd) { DestroyWindow(hDummyWnd); - UnregisterClass(L"ZeroSwitchHlp", hInst); + UnregisterClass(L"ZeroSwitchHlp", g_plugin.getInst()); } } @@ -101,7 +106,7 @@ void DestroyHelperWnd() { DestroyWindow(hHelperWnd); DestroyWindow(hDummyWnd); - UnregisterClass(L"ZeroSwitchHlp", hInst); + UnregisterClass(L"ZeroSwitchHlp", g_plugin.getInst()); } } @@ -129,6 +134,8 @@ LRESULT CALLBACK CallWndRetProc(int nCode, WPARAM wParam, LPARAM lParam) return CallNextHookEx(nullptr, nCode, wParam, lParam); // Pass the message to other hooks in chain } +///////////////////////////////////////////////////////////////////////////////////////// + extern "C" int __declspec(dllexport) Load(void) { mir_getLP(&pluginInfo); @@ -146,10 +153,12 @@ extern "C" int __declspec(dllexport) Load(void) return 0; } +///////////////////////////////////////////////////////////////////////////////////////// + extern "C" int __declspec(dllexport) Unload(void) { if (hHook) UnhookWindowsHookEx(hHook); DestroyHelperWnd(); return 0; -} \ No newline at end of file +} diff --git a/plugins/ZeroSwitch/src/stdafx.h b/plugins/ZeroSwitch/src/stdafx.h index 8b91cd0a06..ac729e6640 100644 --- a/plugins/ZeroSwitch/src/stdafx.h +++ b/plugins/ZeroSwitch/src/stdafx.h @@ -9,7 +9,6 @@ // Windows Header Files: #include -#define __NO_CMPLUGIN_NEEDED #include #include #include -- cgit v1.2.3