From 4d01f5f5096cb4d22c4a7ba17cc82977c7f5f19b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Tue, 29 Oct 2013 18:17:04 +0000 Subject: Adopted MirandaG15 plugin First compilable version and 32-bit only. git-svn-id: http://svn.miranda-ng.org/main/trunk@6681 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- .../MirandaG15/LCDFramework/LCDFramework.vcxproj | 301 +++ .../LCDFramework/LCDFramework.vcxproj.filters | 145 ++ plugins/MirandaG15/LCDFramework/g15sdk/lglcd.h | 454 +++++ .../LCDFramework/g15sdk/lib/x64/lgLcd.lib | Bin 0 -> 11950 bytes .../LCDFramework/g15sdk/lib/x86/lgLcd.lib | Bin 0 -> 7994 bytes plugins/MirandaG15/LCDFramework/hid/hid.lib | Bin 0 -> 28352 bytes plugins/MirandaG15/LCDFramework/hid/hidpi.h | 1267 +++++++++++++ plugins/MirandaG15/LCDFramework/hid/hidsdi.h | 257 +++ plugins/MirandaG15/LCDFramework/hid/hidusage.h | 270 +++ plugins/MirandaG15/LCDFramework/src/CLCDBar.cpp | 192 ++ plugins/MirandaG15/LCDFramework/src/CLCDBar.h | 64 + plugins/MirandaG15/LCDFramework/src/CLCDBitmap.cpp | 48 + plugins/MirandaG15/LCDFramework/src/CLCDBitmap.h | 31 + .../MirandaG15/LCDFramework/src/CLCDConnection.cpp | 173 ++ .../MirandaG15/LCDFramework/src/CLCDConnection.h | 74 + .../LCDFramework/src/CLCDConnectionLogitech.cpp | 1023 ++++++++++ .../LCDFramework/src/CLCDConnectionLogitech.h | 148 ++ plugins/MirandaG15/LCDFramework/src/CLCDDevice.h | 63 + plugins/MirandaG15/LCDFramework/src/CLCDGfx.cpp | 798 ++++++++ plugins/MirandaG15/LCDFramework/src/CLCDGfx.h | 82 + plugins/MirandaG15/LCDFramework/src/CLCDInput.cpp | 857 +++++++++ plugins/MirandaG15/LCDFramework/src/CLCDInput.h | 108 ++ plugins/MirandaG15/LCDFramework/src/CLCDLabel.cpp | 228 +++ plugins/MirandaG15/LCDFramework/src/CLCDLabel.h | 52 + plugins/MirandaG15/LCDFramework/src/CLCDList.h | 943 ++++++++++ plugins/MirandaG15/LCDFramework/src/CLCDObject.h | 52 + .../LCDFramework/src/CLCDOutputManager.cpp | 451 +++++ .../LCDFramework/src/CLCDOutputManager.h | 102 + plugins/MirandaG15/LCDFramework/src/CLCDScreen.cpp | 282 +++ plugins/MirandaG15/LCDFramework/src/CLCDScreen.h | 67 + .../MirandaG15/LCDFramework/src/CLCDTextLog.cpp | 440 +++++ plugins/MirandaG15/LCDFramework/src/CLCDTextLog.h | 90 + .../MirandaG15/LCDFramework/src/CLCDTextObject.cpp | 187 ++ .../MirandaG15/LCDFramework/src/CLCDTextObject.h | 53 + plugins/MirandaG15/LCDFramework/src/ConStream.cpp | Bin 0 -> 3624 bytes plugins/MirandaG15/LCDFramework/src/ConStream.h | Bin 0 -> 2488 bytes plugins/MirandaG15/LCDFramework/src/LCDFramework.h | 20 + plugins/MirandaG15/LCDFramework/src/LCDObject.cpp | 137 ++ plugins/MirandaG15/LCDFramework/src/debug.cpp | 58 + plugins/MirandaG15/LCDFramework/src/debug.h | 21 + plugins/MirandaG15/LCDFramework/src/misc.cpp | 217 +++ plugins/MirandaG15/LCDFramework/src/misc.h | 97 + plugins/MirandaG15/LCDFramework/src/stdafx.h | 33 + plugins/MirandaG15/LCDFramework/todo.txt | 8 + plugins/MirandaG15/MirandaG15.aps | Bin 0 -> 25992 bytes plugins/MirandaG15/MirandaG15.rc | 348 ++++ plugins/MirandaG15/MirandaG15.sln | 39 + plugins/MirandaG15/MirandaG15.vcxproj | 420 +++++ plugins/MirandaG15/MirandaG15.vcxproj.filters | 229 +++ plugins/MirandaG15/changelog.txt | 129 ++ plugins/MirandaG15/data/back.bmp | Bin 0 -> 74 bytes plugins/MirandaG15/data/chat.bmp | Bin 0 -> 74 bytes plugins/MirandaG15/data/clist.bmp | Bin 0 -> 74 bytes plugins/MirandaG15/data/down.bmp | Bin 0 -> 74 bytes plugins/MirandaG15/data/edit.bmp | Bin 0 -> 74 bytes plugins/MirandaG15/data/events/conn.bmp | Bin 0 -> 174 bytes plugins/MirandaG15/data/events/conn_large.bmp | Bin 0 -> 246 bytes plugins/MirandaG15/data/events/info.bmp | Bin 0 -> 174 bytes plugins/MirandaG15/data/events/info_large.bmp | Bin 0 -> 246 bytes plugins/MirandaG15/data/events/msg.bmp | Bin 0 -> 174 bytes plugins/MirandaG15/data/events/msg_large.bmp | Bin 0 -> 94 bytes plugins/MirandaG15/data/events/user.bmp | Bin 0 -> 174 bytes plugins/MirandaG15/data/events/user_large.bmp | Bin 0 -> 246 bytes plugins/MirandaG15/data/hist.bmp | Bin 0 -> 74 bytes plugins/MirandaG15/data/minus.bmp | Bin 0 -> 210 bytes plugins/MirandaG15/data/next.bmp | Bin 0 -> 74 bytes plugins/MirandaG15/data/notick.ico | Bin 0 -> 318 bytes plugins/MirandaG15/data/open.bmp | Bin 0 -> 74 bytes plugins/MirandaG15/data/plus.bmp | Bin 0 -> 210 bytes plugins/MirandaG15/data/prev.bmp | Bin 0 -> 74 bytes plugins/MirandaG15/data/reply.bmp | Bin 0 -> 74 bytes plugins/MirandaG15/data/send.bmp | Bin 0 -> 74 bytes plugins/MirandaG15/data/status/away.bmp | Bin 0 -> 82 bytes plugins/MirandaG15/data/status/dnd.bmp | Bin 0 -> 82 bytes plugins/MirandaG15/data/status/ffc.bmp | Bin 0 -> 82 bytes plugins/MirandaG15/data/status/invis.bmp | Bin 0 -> 134 bytes plugins/MirandaG15/data/status/na.bmp | Bin 0 -> 82 bytes plugins/MirandaG15/data/status/occ.bmp | Bin 0 -> 82 bytes plugins/MirandaG15/data/status/off.bmp | Bin 0 -> 82 bytes plugins/MirandaG15/data/status/on.bmp | Bin 0 -> 82 bytes plugins/MirandaG15/data/status/status.bmp | Bin 0 -> 628 bytes plugins/MirandaG15/data/tick.ico | Bin 0 -> 318 bytes plugins/MirandaG15/data/up.bmp | Bin 0 -> 74 bytes plugins/MirandaG15/langpack_german.txt | 262 +++ plugins/MirandaG15/readme.txt | 54 + plugins/MirandaG15/resource.h | 163 ++ plugins/MirandaG15/src/CAppletManager.cpp | 1960 ++++++++++++++++++++ plugins/MirandaG15/src/CAppletManager.h | 193 ++ plugins/MirandaG15/src/CChatScreen.cpp | 800 ++++++++ plugins/MirandaG15/src/CChatScreen.h | 113 ++ plugins/MirandaG15/src/CConfig.cpp | 970 ++++++++++ plugins/MirandaG15/src/CConfig.h | 166 ++ plugins/MirandaG15/src/CContactList.cpp | 1174 ++++++++++++ plugins/MirandaG15/src/CContactList.h | 145 ++ plugins/MirandaG15/src/CContactlistScreen.cpp | 315 ++++ plugins/MirandaG15/src/CContactlistScreen.h | 62 + plugins/MirandaG15/src/CCreditsScreen.cpp | 266 +++ plugins/MirandaG15/src/CCreditsScreen.h | 53 + plugins/MirandaG15/src/CEvent.h | 71 + plugins/MirandaG15/src/CEventLog.cpp | 120 ++ plugins/MirandaG15/src/CEventLog.h | 46 + plugins/MirandaG15/src/CEventScreen.cpp | 239 +++ plugins/MirandaG15/src/CEventScreen.h | 51 + plugins/MirandaG15/src/CIRCConnection.h | 12 + plugins/MirandaG15/src/CIRCHistory.h | 23 + plugins/MirandaG15/src/CNotificationScreen.cpp | 374 ++++ plugins/MirandaG15/src/CNotificationScreen.h | 95 + plugins/MirandaG15/src/CProtocolData.h | 13 + plugins/MirandaG15/src/CScreen.cpp | 180 ++ plugins/MirandaG15/src/CScreen.h | 47 + plugins/MirandaG15/src/CScreensaverScreen.cpp | 200 ++ plugins/MirandaG15/src/CScreensaverScreen.h | 51 + plugins/MirandaG15/src/Miranda.cpp | 223 +++ plugins/MirandaG15/src/Miranda.h | 4 + plugins/MirandaG15/src/StdAfx.h | 53 + plugins/MirandaG15/src/m_metacontacts.h | 166 ++ plugins/MirandaG15/todo.txt | 14 + 117 files changed, 19736 insertions(+) create mode 100644 plugins/MirandaG15/LCDFramework/LCDFramework.vcxproj create mode 100644 plugins/MirandaG15/LCDFramework/LCDFramework.vcxproj.filters create mode 100644 plugins/MirandaG15/LCDFramework/g15sdk/lglcd.h create mode 100644 plugins/MirandaG15/LCDFramework/g15sdk/lib/x64/lgLcd.lib create mode 100644 plugins/MirandaG15/LCDFramework/g15sdk/lib/x86/lgLcd.lib create mode 100644 plugins/MirandaG15/LCDFramework/hid/hid.lib create mode 100644 plugins/MirandaG15/LCDFramework/hid/hidpi.h create mode 100644 plugins/MirandaG15/LCDFramework/hid/hidsdi.h create mode 100644 plugins/MirandaG15/LCDFramework/hid/hidusage.h create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDBar.cpp create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDBar.h create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDBitmap.cpp create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDBitmap.h create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDConnection.cpp create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDConnection.h create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDConnectionLogitech.cpp create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDConnectionLogitech.h create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDDevice.h create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDGfx.cpp create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDGfx.h create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDInput.cpp create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDInput.h create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDLabel.cpp create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDLabel.h create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDList.h create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDObject.h create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDOutputManager.cpp create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDOutputManager.h create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDScreen.cpp create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDScreen.h create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDTextLog.cpp create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDTextLog.h create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDTextObject.cpp create mode 100644 plugins/MirandaG15/LCDFramework/src/CLCDTextObject.h create mode 100644 plugins/MirandaG15/LCDFramework/src/ConStream.cpp create mode 100644 plugins/MirandaG15/LCDFramework/src/ConStream.h create mode 100644 plugins/MirandaG15/LCDFramework/src/LCDFramework.h create mode 100644 plugins/MirandaG15/LCDFramework/src/LCDObject.cpp create mode 100644 plugins/MirandaG15/LCDFramework/src/debug.cpp create mode 100644 plugins/MirandaG15/LCDFramework/src/debug.h create mode 100644 plugins/MirandaG15/LCDFramework/src/misc.cpp create mode 100644 plugins/MirandaG15/LCDFramework/src/misc.h create mode 100644 plugins/MirandaG15/LCDFramework/src/stdafx.h create mode 100644 plugins/MirandaG15/LCDFramework/todo.txt create mode 100644 plugins/MirandaG15/MirandaG15.aps create mode 100644 plugins/MirandaG15/MirandaG15.rc create mode 100644 plugins/MirandaG15/MirandaG15.sln create mode 100644 plugins/MirandaG15/MirandaG15.vcxproj create mode 100644 plugins/MirandaG15/MirandaG15.vcxproj.filters create mode 100644 plugins/MirandaG15/changelog.txt create mode 100644 plugins/MirandaG15/data/back.bmp create mode 100644 plugins/MirandaG15/data/chat.bmp create mode 100644 plugins/MirandaG15/data/clist.bmp create mode 100644 plugins/MirandaG15/data/down.bmp create mode 100644 plugins/MirandaG15/data/edit.bmp create mode 100644 plugins/MirandaG15/data/events/conn.bmp create mode 100644 plugins/MirandaG15/data/events/conn_large.bmp create mode 100644 plugins/MirandaG15/data/events/info.bmp create mode 100644 plugins/MirandaG15/data/events/info_large.bmp create mode 100644 plugins/MirandaG15/data/events/msg.bmp create mode 100644 plugins/MirandaG15/data/events/msg_large.bmp create mode 100644 plugins/MirandaG15/data/events/user.bmp create mode 100644 plugins/MirandaG15/data/events/user_large.bmp create mode 100644 plugins/MirandaG15/data/hist.bmp create mode 100644 plugins/MirandaG15/data/minus.bmp create mode 100644 plugins/MirandaG15/data/next.bmp create mode 100644 plugins/MirandaG15/data/notick.ico create mode 100644 plugins/MirandaG15/data/open.bmp create mode 100644 plugins/MirandaG15/data/plus.bmp create mode 100644 plugins/MirandaG15/data/prev.bmp create mode 100644 plugins/MirandaG15/data/reply.bmp create mode 100644 plugins/MirandaG15/data/send.bmp create mode 100644 plugins/MirandaG15/data/status/away.bmp create mode 100644 plugins/MirandaG15/data/status/dnd.bmp create mode 100644 plugins/MirandaG15/data/status/ffc.bmp create mode 100644 plugins/MirandaG15/data/status/invis.bmp create mode 100644 plugins/MirandaG15/data/status/na.bmp create mode 100644 plugins/MirandaG15/data/status/occ.bmp create mode 100644 plugins/MirandaG15/data/status/off.bmp create mode 100644 plugins/MirandaG15/data/status/on.bmp create mode 100644 plugins/MirandaG15/data/status/status.bmp create mode 100644 plugins/MirandaG15/data/tick.ico create mode 100644 plugins/MirandaG15/data/up.bmp create mode 100644 plugins/MirandaG15/langpack_german.txt create mode 100644 plugins/MirandaG15/readme.txt create mode 100644 plugins/MirandaG15/resource.h create mode 100644 plugins/MirandaG15/src/CAppletManager.cpp create mode 100644 plugins/MirandaG15/src/CAppletManager.h create mode 100644 plugins/MirandaG15/src/CChatScreen.cpp create mode 100644 plugins/MirandaG15/src/CChatScreen.h create mode 100644 plugins/MirandaG15/src/CConfig.cpp create mode 100644 plugins/MirandaG15/src/CConfig.h create mode 100644 plugins/MirandaG15/src/CContactList.cpp create mode 100644 plugins/MirandaG15/src/CContactList.h create mode 100644 plugins/MirandaG15/src/CContactlistScreen.cpp create mode 100644 plugins/MirandaG15/src/CContactlistScreen.h create mode 100644 plugins/MirandaG15/src/CCreditsScreen.cpp create mode 100644 plugins/MirandaG15/src/CCreditsScreen.h create mode 100644 plugins/MirandaG15/src/CEvent.h create mode 100644 plugins/MirandaG15/src/CEventLog.cpp create mode 100644 plugins/MirandaG15/src/CEventLog.h create mode 100644 plugins/MirandaG15/src/CEventScreen.cpp create mode 100644 plugins/MirandaG15/src/CEventScreen.h create mode 100644 plugins/MirandaG15/src/CIRCConnection.h create mode 100644 plugins/MirandaG15/src/CIRCHistory.h create mode 100644 plugins/MirandaG15/src/CNotificationScreen.cpp create mode 100644 plugins/MirandaG15/src/CNotificationScreen.h create mode 100644 plugins/MirandaG15/src/CProtocolData.h create mode 100644 plugins/MirandaG15/src/CScreen.cpp create mode 100644 plugins/MirandaG15/src/CScreen.h create mode 100644 plugins/MirandaG15/src/CScreensaverScreen.cpp create mode 100644 plugins/MirandaG15/src/CScreensaverScreen.h create mode 100644 plugins/MirandaG15/src/Miranda.cpp create mode 100644 plugins/MirandaG15/src/Miranda.h create mode 100644 plugins/MirandaG15/src/StdAfx.h create mode 100644 plugins/MirandaG15/src/m_metacontacts.h create mode 100644 plugins/MirandaG15/todo.txt (limited to 'plugins/MirandaG15') diff --git a/plugins/MirandaG15/LCDFramework/LCDFramework.vcxproj b/plugins/MirandaG15/LCDFramework/LCDFramework.vcxproj new file mode 100644 index 0000000000..602824c232 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/LCDFramework.vcxproj @@ -0,0 +1,301 @@ + + + + + Debug ANSI + Win32 + + + Debug ANSI + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release ANSI + Win32 + + + Release ANSI + x64 + + + Release + Win32 + + + Release + x64 + + + + {3BBA4976-826E-44E5-B65F-8A2E1D912BE7} + LCDFramework + Win32Proj + + + + StaticLibrary + MultiByte + true + + + StaticLibrary + MultiByte + true + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + StaticLibrary + Unicode + true + + + StaticLibrary + Unicode + true + + + StaticLibrary + Unicode + + + StaticLibrary + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + + + + Disabled + $(ProjectDir)\g15sdk\;$(ProjectDir)\hid;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + lglcd.lib;hid.lib;setupapi.lib;%(AdditionalDependencies) + $(ProjectDir)\g15sdk\Lib\x86;$(ProjectDir)\hid;%(AdditionalLibraryDirectories) + + + + + Disabled + $(ProjectDir)\g15sdk\;$(ProjectDir)\hid;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + lglcd.lib;hid.lib;setupapi.lib;%(AdditionalDependencies) + $(ProjectDir)\g15sdk\Lib\x86;$(ProjectDir)\hid;%(AdditionalLibraryDirectories) + + + + + $(ProjectDir)\g15sdk\;$(ProjectDir)\hid\;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + lglcd.lib;hid.lib;setupapi.lib;%(AdditionalDependencies) + $(ProjectDir)\g15sdk\Lib\x86;$(ProjectDir)\hid;%(AdditionalLibraryDirectories) + + + + + $(ProjectDir)\g15sdk\;$(ProjectDir)\hid\;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + lglcd.lib;hid.lib;setupapi.lib;%(AdditionalDependencies) + $(ProjectDir)\g15sdk\Lib\x86;$(ProjectDir)\hid;%(AdditionalLibraryDirectories) + + + + + Disabled + $(ProjectDir)\g15sdk\;$(ProjectDir)\hid;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + lglcd.lib;hid.lib;setupapi.lib;%(AdditionalDependencies) + $(ProjectDir)\g15sdk\Lib\x86;$(ProjectDir)\hid;%(AdditionalLibraryDirectories) + + + + + Disabled + $(ProjectDir)\g15sdk\;$(ProjectDir)\hid;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + lglcd.lib;hid.lib;setupapi.lib;%(AdditionalDependencies) + $(ProjectDir)\g15sdk\Lib\x86;$(ProjectDir)\hid;%(AdditionalLibraryDirectories) + + + + + $(ProjectDir)\g15sdk\;$(ProjectDir)\hid\;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + lglcd.lib;hid.lib;setupapi.lib;%(AdditionalDependencies) + $(ProjectDir)\g15sdk\Lib\x86;$(ProjectDir)\hid;%(AdditionalLibraryDirectories) + + + + + $(ProjectDir)\g15sdk\;$(ProjectDir)\hid\;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + lglcd.lib;hid.lib;setupapi.lib;%(AdditionalDependencies) + $(ProjectDir)\g15sdk\Lib\x86;$(ProjectDir)\hid;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/LCDFramework.vcxproj.filters b/plugins/MirandaG15/LCDFramework/LCDFramework.vcxproj.filters new file mode 100644 index 0000000000..34bf8dd788 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/LCDFramework.vcxproj.filters @@ -0,0 +1,145 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {b5136e30-be62-43f3-b14b-feb34b84fc74} + + + {67510d21-eb00-49ae-a049-8dedd1561324} + + + {510e0b20-a701-4058-b1e2-2e3949eeb56a} + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {fad292fa-e001-4c46-931d-d2cdcd274c21} + + + {65812f3e-00a5-4a8b-a420-f1db867ba16c} + + + {438192d8-3f4c-42d7-9351-dbdbb6305977} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\LCDConnections + + + Source Files\LCDConnections + + + Source Files\debug + + + Source Files\debug + + + Source Files\LCDObjects + + + Source Files\LCDObjects + + + Source Files\LCDObjects + + + Source Files\LCDObjects + + + Source Files\LCDObjects + + + Source Files\LCDObjects + + + Source Files\LCDObjects + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files\LCDConnections + + + Header Files\LCDConnections + + + Header Files\LCDConnections + + + Header Files\debug + + + Header Files\debug + + + Header Files\LCDObjects + + + Header Files\LCDObjects + + + Header Files\LCDObjects + + + Header Files\LCDObjects + + + Header Files\LCDObjects + + + Header Files\LCDObjects + + + Header Files\LCDObjects + + + Header Files\LCDObjects + + + + + + + \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/g15sdk/lglcd.h b/plugins/MirandaG15/LCDFramework/g15sdk/lglcd.h new file mode 100644 index 0000000000..c9ef6d11f7 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/g15sdk/lglcd.h @@ -0,0 +1,454 @@ +/* + + lglcd.h + + library definition for lglcd.a + part of lglcd for Microsoft(R) Windows(R) + + The Logitech LCD SDK, including all acompanying documentation, + is protected by intellectual property laws. All use of the Logitech + LCD SDK is subject to the License Agreement found in the + "ReadMe License Agreement" file and in the Reference Manual. All rights + not expressly granted by Logitech are reserved. + + + 01/14/2005 1.00 initial draft + 02/23/2005 1.01 added callbacks, implemented changes as discussed + 02/08/2006 1.02 added call to set foreground, sync update with confirmation + 05/29/2006 1.03 Added device family feature + 12/03/2007 3.00 Added support for color devices and partial event notifications (arrival and removal) + 10/03/2008 3.01 Added more event notifications + 10/27/2008 3.01 Deprecated enumeration and index-based open; Applets should use lgLcdOpenByType() (and + possibly notifications) + +*/ + +#ifndef _LGLCD_H_INCLUDED_ +#define _LGLCD_H_INCLUDED_ + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(push, 8) + +//// Definitions + +// Invalid handle definitions +#define LGLCD_INVALID_CONNECTION (-1) +#define LGLCD_INVALID_DEVICE (-1) + + +// Common Soft-Buttons available through the SDK +#define LGLCDBUTTON_LEFT (0x00000100) +#define LGLCDBUTTON_RIGHT (0x00000200) +#define LGLCDBUTTON_OK (0x00000400) +#define LGLCDBUTTON_CANCEL (0x00000800) +#define LGLCDBUTTON_UP (0x00001000) +#define LGLCDBUTTON_DOWN (0x00002000) +#define LGLCDBUTTON_MENU (0x00004000) + +// Soft-Button masks. Kept for backwards compatibility +#define LGLCDBUTTON_BUTTON0 (0x00000001) +#define LGLCDBUTTON_BUTTON1 (0x00000002) +#define LGLCDBUTTON_BUTTON2 (0x00000004) +#define LGLCDBUTTON_BUTTON3 (0x00000008) +#define LGLCDBUTTON_BUTTON4 (0x00000010) +#define LGLCDBUTTON_BUTTON5 (0x00000020) +#define LGLCDBUTTON_BUTTON6 (0x00000040) +#define LGLCDBUTTON_BUTTON7 (0x00000080) + +//************************************************************************ +// lgLcdDeviceDesc +//************************************************************************ +typedef struct +{ + DWORD Width; + DWORD Height; + DWORD Bpp; + DWORD NumSoftButtons; +} lgLcdDeviceDesc; + + +//************************************************************************ +// lgLcdDeviceDescEx +//************************************************************************ +typedef struct +{ + DWORD deviceFamilyId; + WCHAR deviceDisplayName[MAX_PATH]; + DWORD Width; // # of pixels (horizontally) on the LCD + DWORD Height; // # of pixels (lines) on the LCD + DWORD Bpp; // # of bits per pixel (1,8,16,24,...) + DWORD NumSoftButtons; + DWORD Reserved1; + DWORD Reserved2; +} lgLcdDeviceDescExW; + +typedef struct +{ + DWORD deviceFamilyId; + CHAR deviceDisplayName[MAX_PATH]; + DWORD Width; + DWORD Height; + DWORD Bpp; + DWORD NumSoftButtons; + DWORD Reserved1; + DWORD Reserved2; +} lgLcdDeviceDescExA; + +#ifdef UNICODE +typedef lgLcdDeviceDescExW lgLcdDeviceDescEx; +#else +typedef lgLcdDeviceDescExA lgLcdDeviceDescEx; +#endif + +//************************************************************************ +// lgLcdBitmap +//************************************************************************ + +#define LGLCD_BMP_FORMAT_160x43x1 (0x00000001) +#define LGLCD_BMP_FORMAT_QVGAx32 (0x00000003) +#define LGLCD_BMP_WIDTH (160) +#define LGLCD_BMP_HEIGHT (43) +#define LGLCD_BMP_BPP (1) +#define LGLCD_BW_BMP_WIDTH (160) +#define LGLCD_BW_BMP_HEIGHT (43) +#define LGLCD_BW_BMP_BPP (1) +#define LGLCD_QVGA_BMP_WIDTH (320) +#define LGLCD_QVGA_BMP_HEIGHT (240) +#define LGLCD_QVGA_BMP_BPP (4) + +typedef struct +{ + DWORD Format; +} lgLcdBitmapHeader; + +typedef struct +{ + lgLcdBitmapHeader hdr; + BYTE pixels[LGLCD_BMP_WIDTH * LGLCD_BMP_HEIGHT * LGLCD_BMP_BPP]; +} lgLcdBitmap160x43x1; + +typedef struct +{ + lgLcdBitmapHeader hdr; // Format = LGLCD_BMP_FORMAT_QVGAx32 + BYTE pixels[LGLCD_QVGA_BMP_WIDTH * LGLCD_QVGA_BMP_HEIGHT * LGLCD_QVGA_BMP_BPP]; +} lgLcdBitmapQVGAx32; +// +// Generic bitmap for use by both color and BW applets +// +typedef union +{ + lgLcdBitmapHeader hdr; // provides easy access to the header + lgLcdBitmap160x43x1 bmp_mono; // B/W bitmap data + lgLcdBitmapQVGAx32 bmp_qvga32; // Color bitmap data +} lgLcdBitmap; + +// Priorities +#define LGLCD_PRIORITY_IDLE_NO_SHOW (0) +#define LGLCD_PRIORITY_BACKGROUND (64) +#define LGLCD_PRIORITY_NORMAL (128) +#define LGLCD_PRIORITY_ALERT (255) +#define LGLCD_SYNC_UPDATE(priority) (0x80000000 | (priority)) +#define LGLCD_SYNC_COMPLETE_WITHIN_FRAME(priority) (0xC0000000 | (priority)) +#define LGLCD_ASYNC_UPDATE(priority) (priority) + +// Foreground mode for client applications +#define LGLCD_LCD_FOREGROUND_APP_NO (0) +#define LGLCD_LCD_FOREGROUND_APP_YES (1) + +// Device family definitions +#define LGLCD_DEVICE_FAMILY_BW_160x43_GAMING (0x00000001) +#define LGLCD_DEVICE_FAMILY_KEYBOARD_G15 (0x00000001) +#define LGLCD_DEVICE_FAMILY_BW_160x43_AUDIO (0x00000002) +#define LGLCD_DEVICE_FAMILY_SPEAKERS_Z10 (0x00000002) +#define LGLCD_DEVICE_FAMILY_JACKBOX (0x00000004) +#define LGLCD_DEVICE_FAMILY_BW_160x43_BASIC (0x00000008) +#define LGLCD_DEVICE_FAMILY_LCDEMULATOR_G15 (0x00000008) +#define LGLCD_DEVICE_FAMILY_RAINBOW (0x00000010) +#define LGLCD_DEVICE_FAMILY_QVGA_BASIC (0x00000020) +#define LGLCD_DEVICE_FAMILY_QVGA_GAMING (0x00000040) +#define LGLCD_DEVICE_FAMILY_GAMEBOARD_G13 (0x00000080) +#define LGLCD_DEVICE_FAMILY_OTHER (0x80000000) + +// Combinations of device families (device clans?) +#define LGLCD_DEVICE_FAMILY_ALL_BW_160x43 (LGLCD_DEVICE_FAMILY_BW_160x43_GAMING \ + | LGLCD_DEVICE_FAMILY_BW_160x43_AUDIO \ + | LGLCD_DEVICE_FAMILY_JACKBOX \ + | LGLCD_DEVICE_FAMILY_BW_160x43_BASIC \ + | LGLCD_DEVICE_FAMILY_RAINBOW \ + | LGLCD_DEVICE_FAMILY_GAMEBOARD_G13) + +#define LGLCD_DEVICE_FAMILY_ALL_QVGA (LGLCD_DEVICE_FAMILY_QVGA_BASIC \ + | LGLCD_DEVICE_FAMILY_QVGA_GAMING) + +#define LGLCD_DEVICE_FAMILY_ALL (LGLCD_DEVICE_FAMILY_ALL_BW_160x43 \ + | LGLCD_DEVICE_FAMILY_ALL_QVGA) + + +// Capabilities of applets connecting to LCD Manager. +#define LGLCD_APPLET_CAP_BASIC (0x00000000) +#define LGLCD_APPLET_CAP_BW (0x00000001) +#define LGLCD_APPLET_CAP_QVGA (0x00000002) + +// Notifications sent by LCD Manager to applets connected to it. +#define LGLCD_NOTIFICATION_DEVICE_ARRIVAL (0x00000001) +#define LGLCD_NOTIFICATION_DEVICE_REMOVAL (0x00000002) +#define LGLCD_NOTIFICATION_CLOSE_CONNECTION (0x00000003) +#define LGLCD_NOTIFICATION_APPLET_DISABLED (0x00000004) +#define LGLCD_NOTIFICATION_APPLET_ENABLED (0x00000005) +#define LGLCD_NOTIFICATION_TERMINATE_APPLET (0x00000006) + +// Device types used in notifications +#define LGLCD_DEVICE_BW (0x00000001) +#define LGLCD_DEVICE_QVGA (0x00000002) + +//************************************************************************ +// Callbacks +//************************************************************************ + +// Callback used to notify client of soft button change +typedef DWORD (WINAPI *lgLcdOnSoftButtonsCB)(IN int device, + IN DWORD dwButtons, + IN const PVOID pContext); + +// Callback used to allow client to pop up a "configuration panel" +typedef DWORD (WINAPI *lgLcdOnConfigureCB)(IN int connection, + IN const PVOID pContext); + +// Callback used to notify client of events, such as device arrival, ... +// Arrival, removal, applet enable/disable supported as of version 3.0. +typedef DWORD (WINAPI *lgLcdOnNotificationCB)(IN int connection, + IN const PVOID pContext, + IN DWORD notificationCode, + IN DWORD notifyParm1, + IN DWORD notifyParm2, + IN DWORD notifyParm3, + IN DWORD notifyParm4); + + +//************************************************************************ +// lgLcdConfigureContext +//************************************************************************ +typedef struct +{ + // Set to NULL if not configurable + lgLcdOnConfigureCB configCallback; + PVOID configContext; +} lgLcdConfigureContext; + +//************************************************************************ +// lgLcdNotificationContext +//************************************************************************ +typedef struct +{ + // Set to NULL if not notifiable + lgLcdOnNotificationCB notificationCallback; + PVOID notifyContext; +} lgLcdNotificationContext; + +//************************************************************************ +// lgLcdConnectContext +//************************************************************************ +typedef struct +{ + // "Friendly name" display in the listing + LPCWSTR appFriendlyName; + // isPersistent determines whether this connection persists in the list + BOOL isPersistent; + // isAutostartable determines whether the client can be started by + // LCDMon + BOOL isAutostartable; + lgLcdConfigureContext onConfigure; + // --> Connection handle + int connection; +} lgLcdConnectContextW; + +typedef struct +{ + // "Friendly name" display in the listing + LPCSTR appFriendlyName; + // isPersistent determines whether this connection persists in the list + BOOL isPersistent; + // isAutostartable determines whether the client can be started by + // LCDMon + BOOL isAutostartable; + lgLcdConfigureContext onConfigure; + // --> Connection handle + int connection; +} lgLcdConnectContextA; + +//************************************************************************ +// lgLcdConnectContextEx +//************************************************************************ +typedef struct +{ + // "Friendly name" display in the listing + LPCWSTR appFriendlyName; + // isPersistent determines whether this connection persists in the list + BOOL isPersistent; + // isAutostartable determines whether the client can be started by + // LCDMon + BOOL isAutostartable; + lgLcdConfigureContext onConfigure; + // --> Connection handle + int connection; + // New additions added in 1.03 revision + DWORD dwAppletCapabilitiesSupported; // Or'd combination of LGLCD_APPLET_CAP_... defines + DWORD dwReserved1; + lgLcdNotificationContext onNotify; +} lgLcdConnectContextExW; + +typedef struct +{ + // "Friendly name" display in the listing + LPCSTR appFriendlyName; + // isPersistent determines whether this connection persists in the list + BOOL isPersistent; + // isAutostartable determines whether the client can be started by + // LCDMon + BOOL isAutostartable; + lgLcdConfigureContext onConfigure; + // --> Connection handle + int connection; + // New additions added in 1.03 revision + DWORD dwAppletCapabilitiesSupported; // Or'd combination of LGLCD_APPLET_CAP_... defines + DWORD dwReserved1; + lgLcdNotificationContext onNotify; +} lgLcdConnectContextExA; + +#ifdef UNICODE +typedef lgLcdConnectContextW lgLcdConnectContext; +typedef lgLcdConnectContextExW lgLcdConnectContextEx; +#else +typedef lgLcdConnectContextA lgLcdConnectContext; +typedef lgLcdConnectContextExA lgLcdConnectContextEx; +#endif + +//************************************************************************ +// lgLcdOpenContext & lgLcdOpenByTypeContext +//************************************************************************ + +typedef struct +{ + // Set to NULL if no softbutton notifications are needed + lgLcdOnSoftButtonsCB softbuttonsChangedCallback; + PVOID softbuttonsChangedContext; +} lgLcdSoftbuttonsChangedContext; + +typedef struct +{ + int connection; + // Device index to open + int index; + lgLcdSoftbuttonsChangedContext onSoftbuttonsChanged; + // --> Device handle + int device; +} lgLcdOpenContext; + +typedef struct +{ + int connection; + // Device type to open (either LGLCD_DEVICE_BW or LGLCD_DEVICE_QVGA) + int deviceType; + lgLcdSoftbuttonsChangedContext onSoftbuttonsChanged; + // --> Device handle + int device; +} lgLcdOpenByTypeContext; + + +//************************************************************************ +// Prototypes +//************************************************************************ + +// Initialize the library by calling this function. +DWORD WINAPI lgLcdInit(void); + +// Must be called to release the library and free all allocated structures. +DWORD WINAPI lgLcdDeInit(void); + +// Connect as a client to the LCD subsystem. Provide name to be +// displayed for user when viewing the user interface of the LCD module, +// as well as a configuration callback and context, and a flag that states +// whether this client is startable by LCDMon +DWORD WINAPI lgLcdConnectW(IN OUT lgLcdConnectContextW *ctx); +DWORD WINAPI lgLcdConnectA(IN OUT lgLcdConnectContextA *ctx); +DWORD WINAPI lgLcdConnectExW(IN OUT lgLcdConnectContextExW *ctx); +DWORD WINAPI lgLcdConnectExA(IN OUT lgLcdConnectContextExA *ctx); +#ifdef UNICODE +#define lgLcdConnect lgLcdConnectW +#define lgLcdConnectEx lgLcdConnectExW +#else +#define lgLcdConnect lgLcdConnectA +#define lgLcdConnectEx lgLcdConnectExA +#endif // !UNICODE + +// Must be called to release the connection and free all allocated resources +DWORD WINAPI lgLcdDisconnect(int connection); + +// New additions added in 1.03 revision of API. Call this method to setup which device families the applet +// is interested in. After this call, the applet can use lgLcdEnumerateEx to determine +// if a device from the device family wanted is found. +DWORD WINAPI lgLcdSetDeviceFamiliesToUse(IN int connection, + DWORD dwDeviceFamiliesSupported, // Or'd combination of LGLCD_DEVICE_FAMILY_... defines + DWORD dwReserved1); + +// To determine all connected LCD devices supported by this library, and +// their capabilities. Start with index 0, and increment by one, until +// the library returns an error (WHICH?). +DWORD WINAPI lgLcdEnumerate(IN int connection, IN int index, + OUT lgLcdDeviceDesc *description); + +// To determine all connected LCD devices supported by this library, and +// their capabilities. Start with 0, and increment by one, until +// the library returns an error (WHICH?). +DWORD WINAPI lgLcdEnumerateExW(IN int connection, IN int index, + OUT lgLcdDeviceDescExW *description); +DWORD WINAPI lgLcdEnumerateExA(IN int connection, IN int index, + OUT lgLcdDeviceDescExA *description); +#ifdef UNICODE +#define lgLcdEnumerateEx lgLcdEnumerateExW +#else +#define lgLcdEnumerateEx lgLcdEnumerateExA +#endif // !UNICODE + +// Opens the LCD at position=index. Library sets the device parameter to +// its internal reference to the device. Calling application provides the +// device handle in all calls that access the LCD. +DWORD WINAPI lgLcdOpen(IN OUT lgLcdOpenContext *ctx); + +// Opens an LCD of the specified type. If no such device is available, returns +// an error. +DWORD WINAPI lgLcdOpenByType(IN OUT lgLcdOpenByTypeContext *ctx); + +// Closes the LCD. Must be paired with lgLcdOpen()/lgLcdOpenByType(). +DWORD WINAPI lgLcdClose(IN int device); + +// Reads the state of the soft buttons for the device. +DWORD WINAPI lgLcdReadSoftButtons(IN int device, OUT DWORD *buttons); + +// Provides a bitmap to be displayed on the LCD. The priority field +// further describes the way in which the bitmap is to be applied. +DWORD WINAPI lgLcdUpdateBitmap(IN int device, + IN const lgLcdBitmapHeader *bitmap, + IN DWORD priority); + +// Sets the calling application as the shown application on the LCD, and stops +// any type of rotation among other applications on the LCD. +DWORD WINAPI lgLcdSetAsLCDForegroundApp(IN int device, IN int foregroundYesNoFlag); + +// These API calls are being deprecated. Consider using lgLcdOpenByType() and +// device arrival/removal notifications instead. +#pragma deprecated(lgLcdEnumerate,lgLcdEnumerateExA,lgLcdEnumerateExW,lgLcdOpen) + + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif + +#endif // _LGLCD_H_INCLUDED_ + +//** end of lglcd.h *************************************************** diff --git a/plugins/MirandaG15/LCDFramework/g15sdk/lib/x64/lgLcd.lib b/plugins/MirandaG15/LCDFramework/g15sdk/lib/x64/lgLcd.lib new file mode 100644 index 0000000000..998bd22c7d Binary files /dev/null and b/plugins/MirandaG15/LCDFramework/g15sdk/lib/x64/lgLcd.lib differ diff --git a/plugins/MirandaG15/LCDFramework/g15sdk/lib/x86/lgLcd.lib b/plugins/MirandaG15/LCDFramework/g15sdk/lib/x86/lgLcd.lib new file mode 100644 index 0000000000..a2725403e3 Binary files /dev/null and b/plugins/MirandaG15/LCDFramework/g15sdk/lib/x86/lgLcd.lib differ diff --git a/plugins/MirandaG15/LCDFramework/hid/hid.lib b/plugins/MirandaG15/LCDFramework/hid/hid.lib new file mode 100644 index 0000000000..09201a3356 Binary files /dev/null and b/plugins/MirandaG15/LCDFramework/hid/hid.lib differ diff --git a/plugins/MirandaG15/LCDFramework/hid/hidpi.h b/plugins/MirandaG15/LCDFramework/hid/hidpi.h new file mode 100644 index 0000000000..a23f3a701f --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/hid/hidpi.h @@ -0,0 +1,1267 @@ + /*++ + +Copyright (c) 1996 Microsoft Corporation + +Module Name: + + HIDPI.H + +Abstract: + + Public Interface to the HID parsing library. + +Environment: + + Kernel & user mode + +Revision History: + + 09-29-95 : created by Kenneth D. Ray + +--*/ + +#ifndef __HIDPI_H__ +#define __HIDPI_H__ + +#include + +// Please include "hidsdi.h" to use the user space (dll / parser) +// Please include "hidpddi.h" to use the kernel space parser + + +typedef enum _HIDP_REPORT_TYPE +{ + HidP_Input, + HidP_Output, + HidP_Feature +} HIDP_REPORT_TYPE; + +typedef struct _USAGE_AND_PAGE +{ + USAGE Usage; + USAGE UsagePage; +} USAGE_AND_PAGE, *PUSAGE_AND_PAGE; + +typedef struct _HIDP_BUTTON_CAPS +{ + USAGE UsagePage; + UCHAR ReportID; + BOOLEAN IsAlias; + + USHORT BitField; + USHORT LinkCollection; // A unique internal index pointer + + USAGE LinkUsage; + USAGE LinkUsagePage; + + BOOLEAN IsRange; + BOOLEAN IsStringRange; + BOOLEAN IsDesignatorRange; + BOOLEAN IsAbsolute; + + ULONG Reserved[10]; + union { + struct { + USAGE UsageMin, UsageMax; + USHORT StringMin, StringMax; + USHORT DesignatorMin, DesignatorMax; + USHORT DataIndexMin, DataIndexMax; + } Range; + struct { + USAGE Usage, Reserved1; + USHORT StringIndex, Reserved2; + USHORT DesignatorIndex, Reserved3; + USHORT DataIndex, Reserved4; + } NotRange; + }; + +} HIDP_BUTTON_CAPS, *PHIDP_BUTTON_CAPS; + + +typedef struct _HIDP_VALUE_CAPS +{ + USAGE UsagePage; + UCHAR ReportID; + BOOLEAN IsAlias; + + USHORT BitField; + USHORT LinkCollection; // A unique internal index pointer + + USAGE LinkUsage; + USAGE LinkUsagePage; + + BOOLEAN IsRange; + BOOLEAN IsStringRange; + BOOLEAN IsDesignatorRange; + BOOLEAN IsAbsolute; + + BOOLEAN HasNull; // Does this channel have a null report union + UCHAR Reserved; + USHORT BitSize; // How many bits are devoted to this value? + + USHORT ReportCount; // See Note below. Usually set to 1. + USHORT Reserved2[5]; + + ULONG UnitsExp; + ULONG Units; + + LONG LogicalMin, LogicalMax; + LONG PhysicalMin, PhysicalMax; + + union { + struct { + USAGE UsageMin, UsageMax; + USHORT StringMin, StringMax; + USHORT DesignatorMin, DesignatorMax; + USHORT DataIndexMin, DataIndexMax; + } Range; + + struct { + USAGE Usage, Reserved1; + USHORT StringIndex, Reserved2; + USHORT DesignatorIndex, Reserved3; + USHORT DataIndex, Reserved4; + } NotRange; + }; +} HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS; + +// +// Notes: +// +// ReportCount: When a report descriptor declares an Input, Output, or +// Feature main item with fewer usage declarations than the report count, then +// the last usage applies to all remaining unspecified count in that main item. +// (As an example you might have data that required many fields to describe, +// possibly buffered bytes.) In this case, only one value cap structure is +// allocated for these associtated fields, all with the same usage, and Report +// Count reflects the number of fields involved. Normally ReportCount is 1. +// + +// +// The link collection tree consists of an array of LINK_COLLECTION_NODES +// where the index into this array is the same as the collection number. +// +// Given a collection A which contains a subcollection B, A is defined to be +// the parent B, and B is defined to be the child. +// +// Given collections A, B, and C where B and C are children of A, and B was +// encountered before C in the report descriptor, B is defined as a sibling of +// C. (This implies, of course, that if B is a sibling of C, then C is NOT a +// sibling of B). +// +// B is defined as the NextSibling of C if and only if there exists NO +// child collection of A, call it D, such that B is a sibling of D and D +// is a sibling of C. +// +// E is defined to be the FirstChild of A if and only if for all children of A, +// F, that are not equivalent to E, F is a sibling of E. +// (This implies, of course, that the does not exist a child of A, call it G, +// where E is a sibling of G). In other words the first sibling is the last +// link collection found in the list. +// +// With that in mind, the following describes conclusively a data structure +// that provides direct traversal up, down, and accross the link collection +// tree. +// +// +typedef struct _HIDP_LINK_COLLECTION_NODE +{ + USAGE LinkUsage; + USAGE LinkUsagePage; + USHORT Parent; + USHORT NumberOfChildren; + USHORT NextSibling; + USHORT FirstChild; + ULONG CollectionType: 8; // As defined in 6.2.2.6 of HID spec + ULONG IsAlias : 1; // This link node is an allias of the next link node. + ULONG Reserved: 23; + PVOID UserContext; // The user can hang his coat here. +} HIDP_LINK_COLLECTION_NODE, *PHIDP_LINK_COLLECTION_NODE; +// +// When a link collection is described by a delimiter, alias link collection +// nodes are created. (One for each usage within the delimiter). +// The parser assigns each capability description listed above only one +// link collection. +// +// If a control is defined within a collection defined by +// delimited usages, then that control is said to be within multiple link +// collections, one for each usage within the open and close delimiter tokens. +// Such multiple link collecions are said to be aliases. The first N-1 such +// collections, listed in the link collection node array, have their IsAlias +// bit set. The last such link collection is the link collection index used +// in the capabilities described above. +// Clients wishing to set a control in an aliased collection, should walk the +// collection array once for each time they see the IsAlias flag set, and use +// the last link collection as the index for the below accessor functions. +// +// NB: if IsAlias is set, then NextSibling should be one more than the current +// link collection node index. +// + +typedef PUCHAR PHIDP_REPORT_DESCRIPTOR; +typedef struct _HIDP_PREPARSED_DATA * PHIDP_PREPARSED_DATA; + +typedef struct _HIDP_CAPS +{ + USAGE Usage; + USAGE UsagePage; + USHORT InputReportByteLength; + USHORT OutputReportByteLength; + USHORT FeatureReportByteLength; + USHORT Reserved[17]; + + USHORT NumberLinkCollectionNodes; + + USHORT NumberInputButtonCaps; + USHORT NumberInputValueCaps; + USHORT NumberInputDataIndices; + + USHORT NumberOutputButtonCaps; + USHORT NumberOutputValueCaps; + USHORT NumberOutputDataIndices; + + USHORT NumberFeatureButtonCaps; + USHORT NumberFeatureValueCaps; + USHORT NumberFeatureDataIndices; +} HIDP_CAPS, *PHIDP_CAPS; + +typedef struct _HIDP_DATA +{ + USHORT DataIndex; + USHORT Reserved; + union { + ULONG RawValue; // for values + BOOLEAN On; // for buttons MUST BE TRUE for buttons. + }; +} HIDP_DATA, *PHIDP_DATA; +// +// The HIDP_DATA structure is used with HidP_GetData and HidP_SetData +// functions. +// +// The parser contiguously assigns every control (button or value) in a hid +// device a unique data index from zero to NumberXXXDataIndices, exclusive. +// This value is found in HidP_ButtonCaps and HIDP_VALUE_CAPS and +// HIDP_BUTTON_CAPS structures. +// +// Most clients will find the Get/Set Buttons / Value accessor functions +// sufficient to their needs, as it will allow them to access the data known +// to them, while ignoring the other controls. +// +// More complex clients, which actually read the Button / Value Caps, and which +// do a value add service to these routines (EG Direct Input), will need to +// access all the data in the device without interest in the individual usage +// or link collection location. These are the clients that will find +// HidP_Data useful. +// + +NTSTATUS __stdcall +HidP_GetCaps ( + IN PHIDP_PREPARSED_DATA PreparsedData, + OUT PHIDP_CAPS Capabilities + ); +/*++ +Routine Description: + Returns a list of capabilities of a given hid device as described by its + preparsed data. + +Arguments: + PreparsedData The preparsed data returned from Hidclass. + Capabilities a HIDP_CAPS structure + +Return Value: +· HIDP_STATUS_SUCCESS +· HIDP_STATUS_INVALID_PREPARSED_DATA +--*/ + +NTSTATUS __stdcall +HidP_GetLinkCollectionNodes ( + OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes, + IN OUT PULONG LinkCollectionNodesLength, + IN PHIDP_PREPARSED_DATA PreparsedData + ); +/*++ +Routine Description: + Return a list of PHIDP_LINK_COLLECTION_NODEs used to describe the link + collection tree of this hid device. See the above description of + struct _HIDP_LINK_COLLECTION_NODE. + +Arguments: + LinkCollectionNodes - a caller allocated array into which + HidP_GetLinkCollectionNodes will store the information + + LinKCollectionNodesLength - the caller sets this value to the length of the + the array in terms of number of elements. + HidP_GetLinkCollectionNodes sets this value to the actual + number of elements set. The total number of node required to + describe this HID device can be found in the + NumberLinkCollectionNodes field in the HIDP_CAPS structure. + +--*/ + +NTSTATUS __stdcall +HidP_GetButtonCaps ( + IN HIDP_REPORT_TYPE ReportType, + OUT PHIDP_BUTTON_CAPS ButtonCaps, + IN OUT PUSHORT ButtonCapsLength, + IN PHIDP_PREPARSED_DATA PreparsedData +); +#define HidP_GetButtonCaps(_Type_, _Caps_, _Len_, _Data_) \ + HidP_GetSpecificButtonCaps (_Type_, 0, 0, 0, _Caps_, _Len_, _Data_) +NTSTATUS __stdcall +HidP_GetSpecificButtonCaps ( + IN HIDP_REPORT_TYPE ReportType, + IN USAGE UsagePage, // Optional (0 => ignore) + IN USHORT LinkCollection, // Optional (0 => ignore) + IN USAGE Usage, // Optional (0 => ignore) + OUT PHIDP_BUTTON_CAPS ButtonCaps, + IN OUT PUSHORT ButtonCapsLength, + IN PHIDP_PREPARSED_DATA PreparsedData + ); +/*++ +Description: + HidP_GetButtonCaps returns all the buttons (binary values) that are a part + of the given report type for the Hid device represented by the given + preparsed data. + +Parameters: + ReportType One of HidP_Input, HidP_Output, or HidP_Feature. + + ButtonCaps A _HIDP_BUTTON_CAPS array contain information about all the + binary values in the given report. This buffer is provided by + the caller. + + ButtonLength Starts off as the length of the caller provided buffer, and + ends up the length of the button values. Both are in units + array elemenst, not byte length. The number of button caps + returned can be found in the HIDP_CAPS structure. + + PreparsedData The preparsed data returned from Hidclass. + + +Return Value +HidP_GetButtonCaps returns the following error codes: +· HIDP_STATUS_SUCCESS. +· HIDP_STATUS_BUFFER_TOO_SMALL + +--*/ + +NTSTATUS __stdcall +HidP_GetValueCaps ( + IN HIDP_REPORT_TYPE ReportType, + OUT PHIDP_VALUE_CAPS ValueCaps, + IN OUT PUSHORT ValueCapsLength, + IN PHIDP_PREPARSED_DATA PreparsedData +); +#define HidP_GetValueCaps(_Type_, _Caps_, _Len_, _Data_) \ + HidP_GetSpecificValueCaps (_Type_, 0, 0, 0, _Caps_, _Len_, _Data_) +NTSTATUS __stdcall +HidP_GetSpecificValueCaps ( + IN HIDP_REPORT_TYPE ReportType, + IN USAGE UsagePage, // Optional (0 => ignore) + IN USHORT LinkCollection, // Optional (0 => ignore) + IN USAGE Usage, // Optional (0 => ignore) + OUT PHIDP_VALUE_CAPS ValueCaps, + IN OUT PUSHORT ValueCapsLength, + IN PHIDP_PREPARSED_DATA PreparsedData + ); +/*++ +Description: + HidP_GetValueCaps returns all the values (non-binary) that are a part + of the given report type for the Hid device represented by the given + preparsed data. + +Parameters: + ReportType One of HidP_Input, HidP_Output, or HidP_Feature. + + ValueCaps A _HIDP_Value_CAPS array contain information about all the + binary values in the given report. This buffer is provided by + the caller. + + ValueLength Starts off as the length of the caller provided buffer, and + ends up the length of the button values. Both are in units + array elemenst, not byte length. The number returned + can be found in the HIDP_CAPS structure. + + PreparsedData The preparsed data returned from Hidclass. + + +Return Value +HidP_GetValueCaps returns the following error codes: +· HIDP_STATUS_SUCCESS. +· HIDP_STATUS_BUFFER_TOO_SMALL (all given entries however have been filled in) + +--*/ + +NTSTATUS __stdcall +HidP_SetData ( + IN HIDP_REPORT_TYPE ReportType, + IN PHIDP_DATA DataList, + IN OUT PULONG DataLength, + IN PHIDP_PREPARSED_DATA PreparsedData, + IN OUT PCHAR Report, + IN ULONG ReportLength + ); +/*++ + +Routine Description: + + Please Note: For obvious reasons HidP_SetData and HidP_GetData will not + access UsageValueArrays. + +Parameters: + +Return Value + HidP_SetData returns the following error codes. Upon an error the report + packet is in an unknown state. + +· HIDP_STATUS_SUCCESS upon successful insertion of usages into the report packet. +· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid. +· HIDP_STATUS_USAGE_NOT_FOUND if there exists a byte in the usage list for + which there is no corresponding control. +· HIDP_STATUS_INVALID_REPORT_LENGTH the length of the report packet is not the + size expected. +· HIDP_STATUS_BUFFER_TOO_SMALL if there are not enough entries in a given Main + Array Item to list all of the given usages. The user needs + to split his request to set usages up. +--*/ + +NTSTATUS __stdcall +HidP_GetData ( + IN HIDP_REPORT_TYPE ReportType, + OUT PHIDP_DATA DataList, + IN OUT PULONG DataLength, + IN PHIDP_PREPARSED_DATA PreparsedData, + IN PCHAR Report, + IN ULONG ReportLength + ); +/*++ + +Routine Description: + + Please Note: For obvious reasons HidP_SetData and HidP_GetData will not + access UsageValueArrays. + +Parameters: + +Return Value + +--*/ + +ULONG __stdcall +HidP_MaxDataListLength ( + IN HIDP_REPORT_TYPE ReportType, + IN PHIDP_PREPARSED_DATA PreparsedData + ); +/*++ +Routine Description: + + This function returns the maximum length of HIDP_DATA elements that + HidP_GetData could return for the given report type. + +Parameters: + + ReportType One of HidP_Input or HidP_Feature. + + UsagePage All of the usages in the usage array, for which HidP_GetUsage will + search in the report, refer to this same usage page. + + PreparsedData the preparsed data recevied from the HidClass device object. + +Return Value: + + The length of the usage list array required for the HidpGetUsage + function call. + + If UsagePage is set to zero, then MaxUsageListLength returns the number + of + +--*/ + +#define HidP_SetButtons(Rty, Up, Lco, ULi, ULe, Ppd, Rep, Rle) \ + HidP_SetUsages(Rty, Up, Lco, ULi, ULe, Ppd, Rep, Rle) + +NTSTATUS __stdcall +HidP_SetUsages ( + IN HIDP_REPORT_TYPE ReportType, + IN USAGE UsagePage, + IN USHORT LinkCollection, // Optional + IN PUSAGE UsageList, + IN OUT PULONG UsageLength, + IN PHIDP_PREPARSED_DATA PreparsedData, + IN OUT PCHAR Report, + IN ULONG ReportLength + ); +/*++ + +Routine Description: + This function sets binary values (buttons) in the report. Given an + initialized packet of correct length, it modifies the report packet so that + each element in the given list of usages has been set in the report packet. + For example, in an output report with 5 LED’s, each with a given usage, + an application could turn on any subset of these lights by placing their + usages in any order into the byte array (usageList). HidP_SetUsage would, + in turn, set the appropriate bit or add the corresponding byte into the + HID Main Array Item. + + A properly initialized Report packet is one of the correct byte length, + and all zeros. + +Parameters: + ReportType One of HidP_Output or HidP_Feature. + + UsagePage All of the usages in the usage array, which HidP_SetUsage will + set in the report, refer to this same usage page. + If the client wishes to set usages in a packet for multiple + usage pages then that client needs to make subsequent SetUsages + calls. + + UsageList A byte array containing the usages that HidP_SetUsage will set in + the report packet. + + UsageLength The length of the given byte array. + The parser sets this value to the position in the usage array at + where it stoped processing. In the successful case UsageList + will be unchanged. In any error condition this parameter + reflects how many of the usages in the usage list have + actually been set by the parser. This is useful for finding + the usage in the list which caused the error. However, in + the event of an error condition, the report packet itself is in + an unknown state. + + PreparsedData the preparsed data recevied from the HidClass device object. + + Report The report packet. + + ReportLength Length of the given report packet. + + +Return Value +HidP_SetUsage returns the following error codes. Upon an error the report +packet is in an unknown state. + +· HIDP_STATUS_SUCCESS upon successful insertion of usages into the report packet. +· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid. +· HIDP_STATUS_USAGE_NOT_FOUND if there exists a byte in the usage list for + which there is no corresponding control. +· HIDP_STATUS_INVALID_REPORT_LENGTH the length of the report packet is not the + size expected. +· HIDP_STATUS_BUFFER_TOO_SMALL if there are not enough entries in a given Main + Array Item to list all of the given usages. The user needs + to split his request to set usages up. +--*/ + +#define HidP_UnsetButtons(Rty, Up, Lco, ULi, ULe, Ppd, Rep, Rle) \ + HidP_UnsetUsages(Rty, Up, Lco, ULi, ULe, Ppd, Rep, Rle) + +NTSTATUS __stdcall +HidP_UnsetUsages ( + IN HIDP_REPORT_TYPE ReportType, + IN USAGE UsagePage, + IN USHORT LinkCollection, // Optional + IN PUSAGE UsageList, + IN OUT PULONG UsageLength, + IN PHIDP_PREPARSED_DATA PreparsedData, + IN OUT PCHAR Report, + IN ULONG ReportLength + ); +/*++ + +Routine Description: + This function sets binary values (buttons) in the report. Given an + initialized packet of correct length, it modifies the report packet so that + each element in the given list of usages has been set in the report packet. + For example, in an output report with 5 LED’s, each with a given usage, + an application could turn on any subset of these lights by placing their + usages in any order into the byte array (usageList). HidP_SetUsage would, + in turn, set the appropriate bit or add the corresponding byte into the + HID Main Array Item. + + A properly initialized Report packet is one of the correct byte length, + and all zeros. + +Parameters: + ReportType One of HidP_Output or HidP_Feature. + + UsagePage All of the usages in the usage array, which HidP_SetUsage will + set in the report, refer to this same usage page. + If the client wishes to set usages in a packet for multiple + usage pages then that client needs to make subsequent SetUsages + calls. + + UsageList A byte array containing the usages that HidP_SetUsage will set in + the report packet. + + UsageLength The length of the given byte array. + The parser sets this value to the position in the usage array at + where it stoped processing. In the successful case UsageList + will be unchanged. In any error condition this parameter + reflects how many of the usages in the usage list have + actually been set by the parser. This is useful for finding + the usage in the list which caused the error. However, in + the event of an error condition, the report packet itself is in + an unknown state. + + PreparsedData the preparsed data recevied from the HidClass device object. + + Report The report packet. + + ReportLength Length of the given report packet. + + +Return Value +HidP_SetUsage returns the following error codes. Upon an error the report +packet is in an unknown state. + +· HIDP_STATUS_SUCCESS upon successful insertion of usages into the report packet. +· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid. +· HIDP_STATUS_USAGE_NOT_FOUND if there exists a byte in the usage list for + which there is no corresponding control. +· HIDP_STATUS_INVALID_REPORT_LENGTH the length of the report packet is not the + size expected. +· HIDP_STATUS_BUFFER_TOO_SMALL if there are not enough entries in a given Main + Array Item to list all of the given usages. The user needs + to split his request to set usages up. +--*/ + +#define HidP_GetButtons(Rty, UPa, LCo, ULi, ULe, Ppd, Rep, RLe) \ + HidP_GetUsages(Rty, UPa, LCo, ULi, ULe, Ppd, Rep, RLe) + +NTSTATUS __stdcall +HidP_GetUsages ( + IN HIDP_REPORT_TYPE ReportType, + IN USAGE UsagePage, + IN USHORT LinkCollection, // Optional + OUT USAGE * UsageList, + IN OUT ULONG * UsageLength, + IN PHIDP_PREPARSED_DATA PreparsedData, + IN PCHAR Report, + IN ULONG ReportLength + ); + +/*++ + +Routine Description: +This function returns the binary values (buttons) in a HID report. +Given a report packet of correct length, it searches the report packet +for each usage for the given usage page and returns them in the usage list. + +Parameters: + + ReportType One of HidP_Output or HidP_Feature. + + UsagePage All of the usages in the usage array, which HidP_SetUsage will + retrieve in the report, refer to this same usage page. + If the client wishes to get usages in a packet for multiple + usage pages then that client needs to make subsequent getUsages + calls. + + UsageList A byte array containing the usages that HidP_GetUsage found in + the report packet. + + UsageLength The length of the given byte array. + This value initially describes the length of the usage list, + but HidP_GetUsage sets this value to the length of found usages. + Use HidP_MaxUsageListLength to determine the maximum length list + of usages that a given report packet may contain. + + PreparsedData the preparsed data recevied from the HidClass device object. + + Report The report packet. + + ReportLength Length of the given report packet. + + +Return Value +HidpGetUsage returns the following error codes: +· HIDP_STATUS_SUCCESS. +· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid. +· HIDP_STATUS_USAGE_NOT_FOUND if no control for this device matches the given + usagePage. +· HIDP_STATUS_BUFFER_TOO_SMALL if the given usageList is not long enough to + hold the usages found in the given report packet. + HidP_MaxUsageListLength should be used to prevent + this error. +· HIDP_STATUS_INVALID_PREPARSED_DATA if the given preparsed data is invalid +· HIDP_STATUS_INVALID_REPORT_LENGTH if the length of the report packet is not + the size expected. +--*/ + +#define HidP_GetButtonsEx(Rty, LCo, BLi, ULe, Ppd, Rep, RLe) \ + HidP_GetUsagesEx(Rty, LCo, BLi, ULe, Ppd, Rep, RLe) + +NTSTATUS __stdcall +HidP_GetUsagesEx ( + IN HIDP_REPORT_TYPE ReportType, + IN USHORT LinkCollection, // Optional + OUT PUSAGE_AND_PAGE ButtonList, + IN OUT ULONG * UsageLength, + IN PHIDP_PREPARSED_DATA PreparsedData, + IN PCHAR Report, + IN ULONG ReportLength + ); + +/*++ + +Routine Description: +This function returns the binary values (buttons) in a HID report. +Given a report packet of correct length, it searches the report packet +for each usage for the given usage page and returns them in the usage list. + +Parameters: + + ReportType One of HidP_Output or HidP_Feature. + + ButtonList An array of USAGE_AND_PAGE structures describing all the + buttons currently ``down'' in the device. + + UsageLength The length of the given array in terms of elements. + This value initially describes the length of the usage list, + but HidP_GetUsage sets this value to the length of found usages. + Use HidP_MaxUsageListLength to determine the maximum length list + of usages that a given report packet may contain. + + PreparsedData the preparsed data recevied from the HidClass device object. + + Report The report packet. + + ReportLength Length of the given report packet. + + +Return Value +HidpGetUsage returns the following error codes: +· HIDP_STATUS_SUCCESS. +· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid. +· HIDP_STATUS_USAGE_NOT_FOUND if no button controls are found for this device. +· HIDP_STATUS_BUFFER_TOO_SMALL if the given usageList is not long enough to + hold the usages found in the given report packet. + HidP_MaxUsageListLength should be used to prevent + this error. +· HIDP_STATUS_INVALID_PREPARSED_DATA if the given preparsed data is invalid +· HIDP_STATUS_INVALID_REPORT_LENGTH if the length of the report packet is not + the size expected. +--*/ + +#define HidP_GetButtonListLength(RTy, UPa, Ppd) \ + HidP_GetUsageListLength(Rty, UPa, Ppd) + +ULONG __stdcall +HidP_MaxUsageListLength ( + IN HIDP_REPORT_TYPE ReportType, + IN USAGE UsagePage, // Optional + IN PHIDP_PREPARSED_DATA PreparsedData + ); +/*++ +Routine Description: + + This function returns the maximum length of usages that a HidpGetUsage + could return for the given HID Report and Usage Page. + +Parameters: + + ReportType One of HidP_Input or HidP_Feature. + + UsagePage All of the usages in the usage array, for which HidP_GetUsage will + search in the report, refer to this same usage page. + + PreparsedData the preparsed data recevied from the HidClass device object. + +Return Value: + + The length of the usage list array required for the HidpGetUsage + function call. + + If UsagePage is set to zero, then MaxUsageListLength returns the number + of + +--*/ + +NTSTATUS __stdcall +HidP_SetUsageValue ( + IN HIDP_REPORT_TYPE ReportType, + IN USAGE UsagePage, + IN USHORT LinkCollection, // Optional + IN USAGE Usage, + IN ULONG UsageValue, + IN PHIDP_PREPARSED_DATA PreparsedData, + IN OUT PCHAR Report, + IN ULONG ReportLength + ); + +/*++ +Description: + HidpSetUsageValue inserts the given value into the given HID Report Packet, + in the field corresponding to the given usage page and usage. + HidP_SetUsageValue casts this value to the appropriate bit length. If there + are two channel in the report packet with the same usage and UsagePage, then + they can be destinguished with the optional LinkCollection Field. + +Parameters: + + ReportType One of HidP_Output or HidP_Feature. + + UsagePage The usage page to which the given usage refers. + + LinkCollection (Optional) If there are more than one channel with the + given usage and usage page, then the client may used this field + to distinguish them. A LinkValue of zero is ingnored. The + first channel that matches the given usage page, usage page, and + Link number is the one affected. + + Usage The usage whose value HidP_SetUsageValue will set. + + UsageValue The value. This value must be within the logical range or + null value specified by the Report Descriptor. + + PreparsedData The data retreived from the HID device + + Report The report packet. + + ReportLength Length of the given report packet. + + +Return Value: + HidpSetUsageValue returns the following error codes: + +· HIDP_STATUS_SUCCESS. +· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid. +· HIDP_STATUS_USAGE_NOT_FOUND if the given usage does not correspond to a + control on the device, or if it refers to a button + style control. +· HIDP_STATUS_INVALID_REPORT_LENGTH if the length of the report packet is not + the size expected given the HIDP_CHANNELS structure. +--*/ + + + +NTSTATUS __stdcall +HidP_SetScaledUsageValue ( + IN HIDP_REPORT_TYPE ReportType, + IN USAGE UsagePage, + IN USHORT LinkCollection, // Optional + IN USAGE Usage, + IN LONG UsageValue, + IN PHIDP_PREPARSED_DATA PreparsedData, + IN OUT PCHAR Report, + IN ULONG ReportLength + ); + +/*++ +Description: + HidpSetUsageValue inserts the given value into the given HID Report Packet, + in the field corresponding to the given usage page and usage. + HidP_SetUsageValue casts this value to the appropriate bit length. If there + are two channel in the report packet with the same usage and UsagePage, then + they can be destinguished with the optional LinkCollection Field. + ScaledUsageValue converts from the signed physical value given as UsageValue + to the logical value placed in the report. + +Parameters: + + ReportType One of HidP_Output or HidP_Feature. + + UsagePage The usage page to which the given usage refers. + + LinkCollection (Optional) If there are more than one channel with the + given usage and usage page, then the client may used this field + to distinguish them. A LinkValue of zero is ingnored. The + first channel that matches the given usage page, usage page, and + Link number is the one affected. + + Usage The usage whose value HidP_SetUsageValue will set. + + UsageValue The value. This value must be within the logical range or + null value specified by the Report Descriptor. + + PreparsedData The data retreived from the HID device + + Report The report packet. + + ReportLength Length of the given report packet. + + +Return Value: + HidpSetUsageValue returns the following error codes: + +· HIDP_STATUS_SUCCESS. +· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid. +· HIDP_STATUS_USAGE_NOT_FOUND if the given usage does not correspond to a + control on the device, or if it refers to a button + style control. +· HIDP_STATUS_INVALID_REPORT_LENGTH if the length of the report packet is not + the size expected given the HIDP_CHANNELS structure. +· HIDP_STATUS_VALUE_OUT_OF_RANGE The physical value given was out of range, + but this field does not accept null values. In this + case the field remains unchanged. +· HIDP_STATUS_BAD_LOG_PHY_VALUES +· HIDP_STATUS_NULL A null value was written into the field, because the + physical value given was out of range and this field + supports null values. The value written was outside the + range of LogicalMin and LogicalMax and is specifically + set to the most negative value. +--*/ + +NTSTATUS __stdcall +HidP_SetUsageValueArray ( + IN HIDP_REPORT_TYPE ReportType, + IN USAGE UsagePage, + IN USHORT LinkCollection, // Optional + IN USAGE Usage, + IN PCHAR UsageValue, + IN USHORT UsageValueByteLength, + IN PHIDP_PREPARSED_DATA PreparsedData, + OUT PCHAR Report, + IN ULONG ReportLength + ); + +/*++ +Routine Descripton: + The last usage in the list of usages describing a main item must be + repeated if there are less usages than there are report counts declared + for the given main item. In this case a single value cap is allocated + for that usage and the report count of that value cap is set to refect the + numer of fields to which that usage refers. + + HidP_SetUsageValueArray sets the raw bits for that usage which spans + more than one field in a report. + +Parameters: + + ReportType One of HidP_Output or HidP_Feature. + + UsagePage The usage page to which the given usage refers. + + LinkCollection (Optional) If there are more than one channel with the + given usage and usage page, then the client may used this field + to distinguish them. A LinkValue of zero is ingnored. The + first channel that matches the given usage page, usage page, and + Link number is the one affected. + + Usage The usage whose value HidP_SetUsageValueArray will set. + + UsageValue A pointer to an array characters where the value will be placed. + The number of BITS required is found by multiplying the + BitSize and ReportCount fields of the given Value Cap for this + control. The least significant bit of this control found in the + given report will be placed in the least significan bit location + of the array given (little-endian format), regardless of whether + or not the field is byte alligned or if the BitSize is a multiple + of sizeof (CHAR). + + UsageValueByteLength + the length of the given UsageValue buffer. + + PreparsedData The data retreived from the HID device + + Report The report packet. + + ReportLength Length of the given report packet. + + +Return Value: + Same as others + + HIDP_STATUS_NOT_VALUE_ARRAY this is not a value array control use instead + HidP_SetUsageValue. + +--*/ + + +NTSTATUS __stdcall +HidP_GetUsageValue ( + IN HIDP_REPORT_TYPE ReportType, + IN USAGE UsagePage, + IN USHORT LinkCollection, // Optional + IN USAGE Usage, + OUT PULONG UsageValue, + IN PHIDP_PREPARSED_DATA PreparsedData, + IN PCHAR Report, + IN ULONG ReportLength + ); + +/* +Description + HidP_GetUsageValue retrieves the given value from the given HID Report + Packet, for the specified usage. + +Parameters: + + ReportType One of HidP_Output or HidP_Feature. + + UsagePage The usage page to which the given usage refers. + + LinkCollection (Optional) If there are more than one channel with the + given usage and usage page, then the client may used this field + to distinguish them. A LinkValue of zero is ingnored. The + first channel that matches the given usage page, usage page, and + Link number is the one affected. + + Usage The usage whose value HidP_GetUsageValue will retreive. + + UsageValue The value. This value must be within the logical range or + null value specified by the Report Descriptor. + + PreparsedData The data retreived from the HID device + + Report The report packet. + + ReportLength Length of the given report packet. + + +Return Value: + HidpSetUsageValue returns the following error codes: + +· HIDP_STATUS_SUCCESS. +· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid. +· HIDP_STATUS_USAGE_NOT_FOUND if the given usage does not correspond to a + control on the device, or if it refers to a button + style control. +· HIDP_STATUS_INVALID_REPORT_LENGTH if the length of the report packet is + not the size expected given the HIDP_CHANNELS structure. +--*/ + + +NTSTATUS __stdcall +HidP_GetScaledUsageValue ( + IN HIDP_REPORT_TYPE ReportType, + IN USAGE UsagePage, + IN USHORT LinkCollection, // Optional + IN USAGE Usage, + OUT PLONG UsageValue, + IN PHIDP_PREPARSED_DATA PreparsedData, + IN PCHAR Report, + IN ULONG ReportLength + ); + +/*++ +Description + HidP_GetScaledUsageValue retrieves the given value from the given HID Report + Packet, for the specified usage. This function assums a linear + extrapolation between the physical Max/min and the Logical Max/min. + (Where logical is the values reported by the device, and physical is the + value returned by this function.) + If the data field requested is of fewer bytes than 32, then + HidP_GetScaledUsageValue will sign extend those bits to 32. + + +Parameters: + + ReportType One of HidP_Output or HidP_Feature. + + UsagePage The usage page to which the given usage refers. + + LinkCollection (Optional) If there are more than one channel with the + given usage and usage page, then the client may used this field + to distinguish them. A LinkValue of zero is ingnored. The + first channel that matches the given usage page, usage page, and + Link number is the one affected. + + Usage The usage whose value HidP_GetUsageValue will retreive. + + UsageValue The value. This value must be within the logical range or + null value specified by the Report Descriptor. + + PreparsedData The data retreived from the HID device + + Report The report packet. + + ReportLength Length of the given report packet. + + +Return Value: + HidpSetUsageValue returns the following error codes: + +· HIDP_STATUS_SUCCESS. +· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid. +· HIDP_STATUS_USAGE_NOT_FOUND if the given usage does not correspond to a + control on the device, or if it refers to a button + style control. +· HIDP_STATUS_INVALID_REPORT_LENGTH if the length of the report packet is + not the size expected given the HIDP_CHANNELS structure. +· HIDP_STATUS_VALUE_OUT_OF_RANGE +· HIDP_STATUS_BAD_LOG_PHY_VALUES +· HIDP_STATUS_NULL +--*/ + +NTSTATUS __stdcall +HidP_GetUsageValueArray ( + IN HIDP_REPORT_TYPE ReportType, + IN USAGE UsagePage, + IN USHORT LinkCollection, // Optional + IN USAGE Usage, + OUT PCHAR UsageValue, + IN USHORT UsageValueByteLength, + IN PHIDP_PREPARSED_DATA PreparsedData, + IN PCHAR Report, + IN ULONG ReportLength + ); + +/*++ +Routine Descripton: + The last usage in the list of usages describing a main item must be + repeated if there are less usages than there are report counts declared + for the given main item. In this case a single value cap is allocated + for that usage and the report count of that value cap is set to refect the + numer of fields to which that usage refers. + + HidP_GetUsageValueArray retrieved the raw bits for that usage which spans + more than one field in a report. + +Parameters: + + ReportType One of HidP_Output or HidP_Feature. + + UsagePage The usage page to which the given usage refers. + + LinkCollection (Optional) If there are more than one channel with the + given usage and usage page, then the client may used this field + to distinguish them. A LinkValue of zero is ingnored. The + first channel that matches the given usage page, usage page, and + Link number is the one affected. + + Usage The usage whose value HidP_GetUsageValueArray will retreive. + + UsageValue A pointer to an array characters where the value will be placed. + The number of BITS required is found by multiplying the + BitSize and ReportCount fields of the given Value Cap for this + control. The least significant bit of this control found in the + given report will be placed in the least significan bit location + of the array given (little-endian format), regardless of whether + or not the field is byte alligned or if the BitSize is a multiple + of sizeof (CHAR). + + UsageValueByteLength + the length of the given UsageValue buffer. + + PreparsedData The data retreived from the HID device + + Report The report packet. + + ReportLength Length of the given report packet. + + + +--*/ + +NTSTATUS __stdcall +HidP_UsageListDifference ( + IN PUSAGE PreviousUsageList, + IN PUSAGE CurrentUsageList, + OUT PUSAGE BreakUsageList, + OUT PUSAGE MakeUsageList, + IN ULONG UsageListLength + ); +/*++ +Routine Description: + Given two list of usages (as might be returned from HidP_GetUsages), + determine the difference; that is, return a list of usages that are in + the current list but not in the previous list (NewUsageList), as well as a + list of usages that are in the previous list but not the current list + (OldUsageList). + +Parameters: + + PreviousUsageList The list of usages before. + CurrentUsageList The list of usages now. + BreakUsageList Previous - Current. + MakeUsageList Current - Previous. + + All usage lists have a maximum of UsageListLength bytes. + Any zero found in the list indicates early termination of the list. + Any characters found after the first zero will be ignored. + +--*/ + +// +// Produce Make or Break Codes +// +typedef enum _HIDP_KEYBOARD_DIRECTION { + HidP_Keyboard_Break, + HidP_Keyboard_Make +} HIDP_KEYBOARD_DIRECTION; + +// +// A bitmap of the current shift state of the keyboard when using the +// below keyboard usages to i8042 translation function. +// +typedef struct _HIDP_KEYBOARD_MODIFIER_STATE { + union { + struct { + ULONG LeftControl: 1; + ULONG LeftShift: 1; + ULONG LeftAlt: 1; + ULONG LeftGUI: 1; + ULONG RightControl: 1; + ULONG RightShift: 1; + ULONG RightAlt: 1; + ULONG RigthGUI: 1; + ULONG CapsLock: 1; + ULONG ScollLock: 1; + ULONG NumLock: 1; + ULONG Reserved: 21; + }; + ULONG ul; + }; + +} HIDP_KEYBOARD_MODIFIER_STATE, * PHIDP_KEYBOARD_MODIFIER_STATE; + +// +// A call back function to give the i8042 scan codes to the caller of +// the below translation function. +// +typedef BOOLEAN (* PHIDP_INSERT_SCANCODES) ( + IN PVOID Context, // Some caller supplied context. + IN PCHAR NewScanCodes, // A list of i8042 scan codes. + IN ULONG Length // the length of the scan codes. + ); + +NTSTATUS __stdcall +HidP_TranslateUsagesToI8042ScanCodes ( + IN PUSAGE ChangedUsageList, + IN ULONG UsageListLength, + IN HIDP_KEYBOARD_DIRECTION KeyAction, + IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState, + IN PHIDP_INSERT_SCANCODES InsertCodesProcedure, + IN PVOID InsertCodesContext + ); +/*++ +Routine Description: +Parameters: +--*/ + + + +// +// Define NT Status codes with Facility Code of FACILITY_HID_ERROR_CODE +// + +// BUGBUG defined in ntstatus.h +#ifndef FACILITY_HID_ERROR_CODE +#define FACILITY_HID_ERROR_CODE 0x11 +#endif + +#define HIDP_ERROR_CODES(SEV, CODE) \ + ((NTSTATUS) (((SEV) << 28) | (FACILITY_HID_ERROR_CODE << 16) | (CODE))) + +#define HIDP_STATUS_SUCCESS (HIDP_ERROR_CODES(0x0,0)) +#define HIDP_STATUS_NULL (HIDP_ERROR_CODES(0x8,1)) +#define HIDP_STATUS_INVALID_PREPARSED_DATA (HIDP_ERROR_CODES(0xC,1)) +#define HIDP_STATUS_INVALID_REPORT_TYPE (HIDP_ERROR_CODES(0xC,2)) +#define HIDP_STATUS_INVALID_REPORT_LENGTH (HIDP_ERROR_CODES(0xC,3)) +#define HIDP_STATUS_USAGE_NOT_FOUND (HIDP_ERROR_CODES(0xC,4)) +#define HIDP_STATUS_VALUE_OUT_OF_RANGE (HIDP_ERROR_CODES(0xC,5)) +#define HIDP_STATUS_BAD_LOG_PHY_VALUES (HIDP_ERROR_CODES(0xC,6)) +#define HIDP_STATUS_BUFFER_TOO_SMALL (HIDP_ERROR_CODES(0xC,7)) +#define HIDP_STATUS_INTERNAL_ERROR (HIDP_ERROR_CODES(0xC,8)) +#define HIDP_STATUS_I8242_TRANS_UNKNOWN (HIDP_ERROR_CODES(0xC,9)) +#define HIDP_STATUS_INCOMPATIBLE_REPORT_ID (HIDP_ERROR_CODES(0xC,0xA)) +#define HIDP_STATUS_NOT_VALUE_ARRAY (HIDP_ERROR_CODES(0xC,0xB)) +#define HIDP_STATUS_IS_VALUE_ARRAY (HIDP_ERROR_CODES(0xC,0xC)) +#define HIDP_STATUS_DATA_INDEX_NOT_FOUND (HIDP_ERROR_CODES(0xC,0xD)) +#define HIDP_STATUS_DATA_INDEX_OUT_OF_RANGE (HIDP_ERROR_CODES(0xC,0xE)) +#define HIDP_STATUS_BUTTON_NOT_PRESSED (HIDP_ERROR_CODES(0xC,0xF)) +#define HIDP_STATUS_REPORT_DOES_NOT_EXIST (HIDP_ERROR_CODES(0xC,0x10)) +#define HIDP_STATUS_NOT_IMPLEMENTED (HIDP_ERROR_CODES(0xC,0x20)) + +#include + +#endif diff --git a/plugins/MirandaG15/LCDFramework/hid/hidsdi.h b/plugins/MirandaG15/LCDFramework/hid/hidsdi.h new file mode 100644 index 0000000000..f75e07dd21 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/hid/hidsdi.h @@ -0,0 +1,257 @@ +/*++ + +Copyright (c) 1996 Microsoft Corporation + +Module Name: + + HIDDLL.H + +Abstract: + + This module contains the PUBLIC definitions for the + code that implements the HID dll. + +Environment: + + Kernel & user mode + +Revision History: + + Aug-96 : created by Kenneth Ray + +--*/ + + +#ifndef _HIDSDI_H +#define _HIDSDI_H + +#include + +//#include "wtypes.h" + +//#include +//#include +//#include + +typedef LONG NTSTATUS; +#include "hidusage.h" +#include "hidpi.h" + +typedef struct _HIDD_CONFIGURATION { + PVOID cookie; + ULONG size; + ULONG RingBufferSize; +} HIDD_CONFIGURATION, *PHIDD_CONFIGURATION; + +typedef struct _HIDD_ATTRIBUTES { + ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES) + + // + // Vendor ids of this hid device + // + USHORT VendorID; + USHORT ProductID; + USHORT VersionNumber; + + // + // Additional fields will be added to the end of this structure. + // +} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES; + + +BOOLEAN __stdcall +HidD_GetAttributes ( + IN HANDLE HidDeviceObject, + OUT PHIDD_ATTRIBUTES Attributes + ); +/*++ +Routine Description: + Fill in the given HIDD_ATTRIBUTES structure with the attributes of the + given hid device. + +--*/ + + +void __stdcall +HidD_GetHidGuid ( + OUT LPGUID HidGuid + ); + +BOOLEAN __stdcall +HidD_GetPreparsedData ( + IN HANDLE HidDeviceObject, + OUT PHIDP_PREPARSED_DATA * PreparsedData + ); +/*++ +Routine Description: + Given a handle to a valid Hid Class Device Oject retrieve the preparsed data. + This routine will ``malloc'' the apropriately size buffer to hold this + preparsed data. It is up to the caller to then free that data at the + caller's conveniance. + +Arguments: + HidDeviceObject a handle to a HidDeviceObject. The client can obtain this + handle via a create file on a string name of a Hid device. + This string name can be obtained using standard PnP calls. + PreparsedData an opaque data used by other functions in this library to + retreive information about a given device. + +Return Value: + TRUE if successful. + + errors returned by DeviceIoControl + +--*/ + +BOOLEAN __stdcall +HidD_FreePreparsedData ( + IN PHIDP_PREPARSED_DATA PreparsedData + ); + +BOOLEAN __stdcall +HidD_FlushQueue ( + IN HANDLE HidDeviceObject + ); +/*++ +Routine Description: + Flush the input queue for the given HID device. + +Arguments: + HidDeviceObject a handle to a HidDeviceObject. The client can obtain this + handle via a create file on a string name of a Hid device. + This string name can be obtained using standard PnP calls. + +Return Value: + TRUE if successful + + errors returned by DeviceIoControl +--*/ + + +BOOLEAN __stdcall +HidD_GetConfiguration ( + IN HANDLE HidDeviceObject, + OUT PHIDD_CONFIGURATION Configuration, + IN ULONG ConfigurationLength + ); +/*++ +Routine Description: + Get the configuration information for this hid device + +Arguments: + HidDeviceObject a handle to a HidDeviceObject. + Configuration a configuration structure. You MUST call HidD_GetConfiguration + before you can modify the configuration and use + HidD_SetConfiguration. + ConfigurationLength that is ``sizeof (HIDD_CONFIGURATION)'' using this + parameter we can later increase the length of the configuration + array and maybe not break older apps. + +Return Value: +same as others +--*/ + +BOOLEAN __stdcall +HidD_SetConfiguration ( + IN HANDLE HidDeviceObject, + IN PHIDD_CONFIGURATION Configuration, + IN ULONG ConfigurationLength + ); +/*++ +Routine Description: + Set the configuration information for this hid device + +Arguments: + HidDeviceObject a handle to a HidDeviceObject. + Configuration a configuration structure. You MUST call HidD_GetConfiguration + before you can modify the configuration and use + HidD_SetConfiguration. + ConfigurationLength that is ``sizeof (HIDD_CONFIGURATION)'' using this + parameter will allow us later to inclrease the size of the + configuration structure. + + +Return Value: +same as others +--*/ + +BOOLEAN __stdcall +HidD_GetFeature ( + IN HANDLE HidDeviceObject, + OUT PVOID ReportBuffer, + IN ULONG ReportBufferLength + ); +/*++ +Routine Description: + Retrieve a feature report from a HID device. + +--*/ + +BOOLEAN __stdcall +HidD_SetFeature ( + IN HANDLE HidDeviceObject, + IN PVOID ReportBuffer, + IN ULONG ReportBufferLength + ); +/*++ +Routine Description: + Send a feature report to a HID device. + +--*/ + +BOOLEAN __stdcall +HidD_GetNumInputBuffers ( + IN HANDLE HidDeviceObject, + OUT PULONG NumberBuffers + ); +BOOLEAN __stdcall +HidD_SetNumInputBuffers ( + IN HANDLE HidDeviceObject, + OUT ULONG NumberBuffers + ); +/*++ + +Routine Description: + Number of hid packets actually retained + +--*/ + +BOOLEAN __stdcall +HidD_GetPhysicalDescriptor ( + IN HANDLE HidDeviceObject, + OUT PVOID Buffer, + IN ULONG BufferLength + ); + +BOOLEAN __stdcall +HidD_GetManufacturerString ( + IN HANDLE HidDeviceObject, + OUT PVOID Buffer, + IN ULONG BufferLength + ); + +BOOLEAN __stdcall +HidD_GetProductString ( + IN HANDLE HidDeviceObject, + OUT PVOID Buffer, + IN ULONG BufferLength + ); + +BOOLEAN __stdcall +HidD_GetIndexedString ( + IN HANDLE HidDeviceObject, + IN ULONG StringIndex, + OUT PVOID Buffer, + IN ULONG BufferLength + ); + +BOOLEAN __stdcall +HidD_GetSerialNumberString ( + IN HANDLE HidDeviceObject, + OUT PVOID Buffer, + IN ULONG BufferLength + ); + +#include + +#endif diff --git a/plugins/MirandaG15/LCDFramework/hid/hidusage.h b/plugins/MirandaG15/LCDFramework/hid/hidusage.h new file mode 100644 index 0000000000..190b7ae811 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/hid/hidusage.h @@ -0,0 +1,270 @@ +/*++ + +Copyright (c) 1996, 1997 Microsoft Corporation + +Module Name: + + HIDUSAGE.H + +Abstract: + + Public Definitions of HID USAGES. + +Environment: + + Kernel & user mode + +Revision History: + + Aug-1996 : created by Kenneth D. Ray + Jun-1997 : updated by Robert Ingman to reflect final HID 1.0 spec + and HID Usages Table 0.9 spec. + +--*/ + +#ifndef __HIDUSAGE_H__ +#define __HIDUSAGE_H__ + +// +// Usage Pages +// + +typedef USHORT USAGE, *PUSAGE; + +#define HID_USAGE_PAGE_GENERIC ((USAGE) 0x01) +#define HID_USAGE_PAGE_SIMULATION ((USAGE) 0x02) +#define HID_USAGE_PAGE_VR ((USAGE) 0x03) +#define HID_USAGE_PAGE_SPORT ((USAGE) 0x04) +#define HID_USAGE_PAGE_GAME ((USAGE) 0x05) +#define HID_USAGE_PAGE_KEYBOARD ((USAGE) 0x07) +#define HID_USAGE_PAGE_LED ((USAGE) 0x08) +#define HID_USAGE_PAGE_BUTTON ((USAGE) 0x09) +#define HID_USAGE_PAGE_ORDINAL ((USAGE) 0x0A) +#define HID_USAGE_PAGE_TELEPHONY ((USAGE) 0x0B) +#define HID_USAGE_PAGE_CONSUMER ((USAGE) 0x0C) +#define HID_USAGE_PAGE_DIGITIZER ((USAGE) 0x0D) +#define HID_USAGE_PAGE_UNICODE ((USAGE) 0x10) +#define HID_USAGE_PAGE_ALPHANUMERIC ((USAGE) 0x14) + + +// +// Usages from Generic Desktop Page (0x01) +// + +#define HID_USAGE_GENERIC_POINTER ((USAGE) 0x01) +#define HID_USAGE_GENERIC_MOUSE ((USAGE) 0x02) +#define HID_USAGE_GENERIC_JOYSTICK ((USAGE) 0x04) +#define HID_USAGE_GENERIC_GAMEPAD ((USAGE) 0x05) +#define HID_USAGE_GENERIC_KEYBOARD ((USAGE) 0x06) +#define HID_USAGE_GENERIC_KEYPAD ((USAGE) 0x07) +#define HID_USAGE_GENERIC_SYSTEM_CTL ((USAGE) 0x80) + +#define HID_USAGE_GENERIC_X ((USAGE) 0x30) +#define HID_USAGE_GENERIC_Y ((USAGE) 0x31) +#define HID_USAGE_GENERIC_Z ((USAGE) 0x32) +#define HID_USAGE_GENERIC_RX ((USAGE) 0x33) +#define HID_USAGE_GENERIC_RY ((USAGE) 0x34) +#define HID_USAGE_GENERIC_RZ ((USAGE) 0x35) +#define HID_USAGE_GENERIC_SLIDER ((USAGE) 0x36) +#define HID_USAGE_GENERIC_DIAL ((USAGE) 0x37) +#define HID_USAGE_GENERIC_WHEEL ((USAGE) 0x38) +#define HID_USAGE_GENERIC_HATSWITCH ((USAGE) 0x39) +#define HID_USAGE_GENERIC_COUNTED_BUFFER ((USAGE) 0x3A) +#define HID_USAGE_GENERIC_BYTE_COUNT ((USAGE) 0x3B) +#define HID_USAGE_GENERIC_MOTION_WAKEUP ((USAGE) 0x3C) +#define HID_USAGE_GENERIC_VX ((USAGE) 0x40) +#define HID_USAGE_GENERIC_VY ((USAGE) 0x41) +#define HID_USAGE_GENERIC_VZ ((USAGE) 0x42) +#define HID_USAGE_GENERIC_VBRX ((USAGE) 0x43) +#define HID_USAGE_GENERIC_VBRY ((USAGE) 0x44) +#define HID_USAGE_GENERIC_VBRZ ((USAGE) 0x45) +#define HID_USAGE_GENERIC_VNO ((USAGE) 0x46) +#define HID_USAGE_GENERIC_SYSCTL_POWER ((USAGE) 0x81) +#define HID_USAGE_GENERIC_SYSCTL_SLEEP ((USAGE) 0x82) +#define HID_USAGE_GENERIC_SYSCTL_WAKE ((USAGE) 0x83) +#define HID_USAGE_GENERIC_SYSCTL_CONTEXT_MENU ((USAGE) 0x84) +#define HID_USAGE_GENERIC_SYSCTL_MAIN_MENU ((USAGE) 0x85) +#define HID_USAGE_GENERIC_SYSCTL_APP_MENU ((USAGE) 0x86) +#define HID_USAGE_GENERIC_SYSCTL_HELP_MENU ((USAGE) 0x87) +#define HID_USAGE_GENERIC_SYSCTL_MENU_EXIT ((USAGE) 0x88) +#define HID_USAGE_GENERIC_SYSCTL_MENU_SELECT ((USAGE) 0x89) +#define HID_USAGE_GENERIC_SYSCTL_MENU_RIGHT ((USAGE) 0x8A) +#define HID_USAGE_GENERIC_SYSCTL_MENU_LEFT ((USAGE) 0x8B) +#define HID_USAGE_GENERIC_SYSCTL_MENU_UP ((USAGE) 0x8C) +#define HID_USAGE_GENERIC_SYSCTL_MENU_DOWN ((USAGE) 0x8D) + +// +// Usages from Simulation Controls Page (0x02) +// + +#define HID_USAGE_SIMULATION_RUDDER ((USAGE) 0xBA) +#define HID_USAGE_SIMULATION_THROTTLE ((USAGE) 0xBB) + +// +// Virtual Reality Controls Page (0x03) +// + + +// +// Sport Controls Page (0x04) +// + + +// +// Game Controls Page (0x05) +// + + +// +// Keyboard/Keypad Page (0x07) +// + + // Error "keys" +#define HID_USAGE_KEYBOARD_NOEVENT ((USAGE) 0x00) +#define HID_USAGE_KEYBOARD_ROLLOVER ((USAGE) 0x01) +#define HID_USAGE_KEYBOARD_POSTFAIL ((USAGE) 0x02) +#define HID_USAGE_KEYBOARD_UNDEFINED ((USAGE) 0x03) + + // Letters +#define HID_USAGE_KEYBOARD_aA ((USAGE) 0x04) +#define HID_USAGE_KEYBOARD_zZ ((USAGE) 0x1D) + // Numbers +#define HID_USAGE_KEYBOARD_ONE ((USAGE) 0x1E) +#define HID_USAGE_KEYBOARD_ZERO ((USAGE) 0x27) + // Modifier Keys +#define HID_USAGE_KEYBOARD_LCTRL ((USAGE) 0xE0) +#define HID_USAGE_KEYBOARD_LSHFT ((USAGE) 0xE1) +#define HID_USAGE_KEYBOARD_LALT ((USAGE) 0xE2) +#define HID_USAGE_KEYBOARD_LGUI ((USAGE) 0xE3) +#define HID_USAGE_KEYBOARD_RCTRL ((USAGE) 0xE4) +#define HID_USAGE_KEYBOARD_RSHFT ((USAGE) 0xE5) +#define HID_USAGE_KEYBOARD_RALT ((USAGE) 0xE6) +#define HID_USAGE_KEYBOARD_RGUI ((USAGE) 0xE7) +#define HID_USAGE_KEYBOARD_SCROLL_LOCK ((USAGE) 0x47) +#define HID_USAGE_KEYBOARD_NUM_LOCK ((USAGE) 0x53) +#define HID_USAGE_KEYBOARD_CAPS_LOCK ((USAGE) 0x39) + // Funtion keys +#define HID_USAGE_KEYBOARD_F1 ((USAGE) 0x3A) +#define HID_USAGE_KEYBOARD_F12 ((USAGE) 0x45) + +#define HID_USAGE_KEYBOARD_RETURN ((USAGE) 0x28) +#define HID_USAGE_KEYBOARD_ESCAPE ((USAGE) 0x29) +#define HID_USAGE_KEYBOARD_DELETE ((USAGE) 0x2A) + +#define HID_USAGE_KEYBOARD_PRINT_SCREEN ((USAGE) 0x46) + +// and hundreds more... + +// +// LED Page (0x08) +// + +#define HID_USAGE_LED_NUM_LOCK ((USAGE) 0x01) +#define HID_USAGE_LED_CAPS_LOCK ((USAGE) 0x02) +#define HID_USAGE_LED_SCROLL_LOCK ((USAGE) 0x03) +#define HID_USAGE_LED_COMPOSE ((USAGE) 0x04) +#define HID_USAGE_LED_KANA ((USAGE) 0x05) +#define HID_USAGE_LED_POWER ((USAGE) 0x06) +#define HID_USAGE_LED_SHIFT ((USAGE) 0x07) +#define HID_USAGE_LED_DO_NOT_DISTURB ((USAGE) 0x08) +#define HID_USAGE_LED_MUTE ((USAGE) 0x09) +#define HID_USAGE_LED_TONE_ENABLE ((USAGE) 0x0A) +#define HID_USAGE_LED_HIGH_CUT_FILTER ((USAGE) 0x0B) +#define HID_USAGE_LED_LOW_CUT_FILTER ((USAGE) 0x0C) +#define HID_USAGE_LED_EQUALIZER_ENABLE ((USAGE) 0x0D) +#define HID_USAGE_LED_SOUND_FIELD_ON ((USAGE) 0x0E) +#define HID_USAGE_LED_SURROUND_FIELD_ON ((USAGE) 0x0F) +#define HID_USAGE_LED_REPEAT ((USAGE) 0x10) +#define HID_USAGE_LED_STEREO ((USAGE) 0x11) +#define HID_USAGE_LED_SAMPLING_RATE_DETECT ((USAGE) 0x12) +#define HID_USAGE_LED_SPINNING ((USAGE) 0x13) +#define HID_USAGE_LED_CAV ((USAGE) 0x14) +#define HID_USAGE_LED_CLV ((USAGE) 0x15) +#define HID_USAGE_LED_RECORDING_FORMAT_DET ((USAGE) 0x16) +#define HID_USAGE_LED_OFF_HOOK ((USAGE) 0x17) +#define HID_USAGE_LED_RING ((USAGE) 0x18) +#define HID_USAGE_LED_MESSAGE_WAITING ((USAGE) 0x19) +#define HID_USAGE_LED_DATA_MODE ((USAGE) 0x1A) +#define HID_USAGE_LED_BATTERY_OPERATION ((USAGE) 0x1B) +#define HID_USAGE_LED_BATTERY_OK ((USAGE) 0x1C) +#define HID_USAGE_LED_BATTERY_LOW ((USAGE) 0x1D) +#define HID_USAGE_LED_SPEAKER ((USAGE) 0x1E) +#define HID_USAGE_LED_HEAD_SET ((USAGE) 0x1F) +#define HID_USAGE_LED_HOLD ((USAGE) 0x20) +#define HID_USAGE_LED_MICROPHONE ((USAGE) 0x21) +#define HID_USAGE_LED_COVERAGE ((USAGE) 0x22) +#define HID_USAGE_LED_NIGHT_MODE ((USAGE) 0x23) +#define HID_USAGE_LED_SEND_CALLS ((USAGE) 0x24) +#define HID_USAGE_LED_CALL_PICKUP ((USAGE) 0x25) +#define HID_USAGE_LED_CONFERENCE ((USAGE) 0x26) +#define HID_USAGE_LED_STAND_BY ((USAGE) 0x27) +#define HID_USAGE_LED_CAMERA_ON ((USAGE) 0x28) +#define HID_USAGE_LED_CAMERA_OFF ((USAGE) 0x29) +#define HID_USAGE_LED_ON_LINE ((USAGE) 0x2A) +#define HID_USAGE_LED_OFF_LINE ((USAGE) 0x2B) +#define HID_USAGE_LED_BUSY ((USAGE) 0x2C) +#define HID_USAGE_LED_READY ((USAGE) 0x2D) +#define HID_USAGE_LED_PAPER_OUT ((USAGE) 0x2E) +#define HID_USAGE_LED_PAPER_JAM ((USAGE) 0x2F) +#define HID_USAGE_LED_REMOTE ((USAGE) 0x30) +#define HID_USAGE_LED_FORWARD ((USAGE) 0x31) +#define HID_USAGE_LED_REVERSE ((USAGE) 0x32) +#define HID_USAGE_LED_STOP ((USAGE) 0x33) +#define HID_USAGE_LED_REWIND ((USAGE) 0x34) +#define HID_USAGE_LED_FAST_FORWARD ((USAGE) 0x35) +#define HID_USAGE_LED_PLAY ((USAGE) 0x36) +#define HID_USAGE_LED_PAUSE ((USAGE) 0x37) +#define HID_USAGE_LED_RECORD ((USAGE) 0x38) +#define HID_USAGE_LED_ERROR ((USAGE) 0x39) +#define HID_USAGE_LED_SELECTED_INDICATOR ((USAGE) 0x3A) +#define HID_USAGE_LED_IN_USE_INDICATOR ((USAGE) 0x3B) +#define HID_USAGE_LED_MULTI_MODE_INDICATOR ((USAGE) 0x3C) +#define HID_USAGE_LED_INDICATOR_ON ((USAGE) 0x3D) +#define HID_USAGE_LED_INDICATOR_FLASH ((USAGE) 0x3E) +#define HID_USAGE_LED_INDICATOR_SLOW_BLINK ((USAGE) 0x3F) +#define HID_USAGE_LED_INDICATOR_FAST_BLINK ((USAGE) 0x40) +#define HID_USAGE_LED_INDICATOR_OFF ((USAGE) 0x41) +#define HID_USAGE_LED_FLASH_ON_TIME ((USAGE) 0x42) +#define HID_USAGE_LED_SLOW_BLINK_ON_TIME ((USAGE) 0x43) +#define HID_USAGE_LED_SLOW_BLINK_OFF_TIME ((USAGE) 0x44) +#define HID_USAGE_LED_FAST_BLINK_ON_TIME ((USAGE) 0x45) +#define HID_USAGE_LED_FAST_BLINK_OFF_TIME ((USAGE) 0x46) +#define HID_USAGE_LED_INDICATOR_COLOR ((USAGE) 0x47) +#define HID_USAGE_LED_RED ((USAGE) 0x48) +#define HID_USAGE_LED_GREEN ((USAGE) 0x49) +#define HID_USAGE_LED_AMBER ((USAGE) 0x4A) +#define HID_USAGE_LED_GENERIC_INDICATOR ((USAGE) 0x3B) + +// +// Button Page (0x09) +// +// There is no need to label these usages. +// + + +// +// Ordinal Page (0x0A) +// +// There is no need to label these usages. +// + + +// +// Telephony Device Page (0x0B) +// + +#define HID_USAGE_TELEPHONY_PHONE ((USAGE) 0x01) +#define HID_USAGE_TELEPHONY_ANSWERING_MACHINE ((USAGE) 0x02) +#define HID_USAGE_TELEPHONY_MESSAGE_CONTROLS ((USAGE) 0x03) +#define HID_USAGE_TELEPHONY_HANDSET ((USAGE) 0x04) +#define HID_USAGE_TELEPHONY_HEADSET ((USAGE) 0x05) +#define HID_USAGE_TELEPHONY_KEYPAD ((USAGE) 0x06) +#define HID_USAGE_TELEPHONY_PROGRAMMABLE_BUTTON ((USAGE) 0x07) + +// +// and others... +// + + +#endif + diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDBar.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDBar.cpp new file mode 100644 index 0000000000..f5701edd35 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDBar.cpp @@ -0,0 +1,192 @@ +#include "stdafx.h" +#include "CLCDGfx.h" +#include "CLCDObject.h" +#include "CLCDBar.h" + +//************************************************************************ +// constructor +//************************************************************************ +CLCDBar::CLCDBar() +{ + m_iSliderSize = 0; + m_iPosition = 0; + m_iMin = 0; + m_iMax = 0; + m_iMode = MODE_SCROLLBAR; + m_iOrientation = DIRECTION_VERTICAL; + m_iAlignment = TOP; +} + +//************************************************************************ +// destructor +//************************************************************************ +CLCDBar::~CLCDBar() +{ +} + +//************************************************************************ +// initializes the bar +//************************************************************************ +bool CLCDBar::Initialize() +{ + return true; +} + +//************************************************************************ +// deinitializes the bar +//************************************************************************ +bool CLCDBar::Shutdown() +{ + return true; +} + +//************************************************************************ +// specifies the bar's mode ( scrollbar / progressbar ) +//************************************************************************ +void CLCDBar::SetMode(int iMode) +{ + m_iMode = iMode; +} + +//************************************************************************ +// specifies the orientation of the bar +//************************************************************************ +void CLCDBar::SetOrientation(int iOrientation) +{ + m_iOrientation = iOrientation; +} + +//************************************************************************ +// scrolls down/right +//************************************************************************ +bool CLCDBar::ScrollDown() +{ + if(m_iPosition < m_iMax) + { + m_iPosition++; + return true; + } + return false; +} + +//************************************************************************ +// scrolls up/left +//************************************************************************ +bool CLCDBar::ScrollUp() +{ + if(m_iPosition > m_iMin) + { + m_iPosition--; + return true; + } + return false; +} + +//************************************************************************ +// scrolls to the specified position +//************************************************************************ +bool CLCDBar::ScrollTo(int iPosition) +{ + if(iPosition >= m_iMin && iPosition <= m_iMax) + { + m_iPosition = iPosition; + return true; + } + return false; +} + +//************************************************************************ +// sets the size of the slider +//************************************************************************ +void CLCDBar::SetSliderSize(int iSize) +{ + m_iSliderSize = iSize; +} + +//************************************************************************ +// sets the alignment of the scrollbar position +//************************************************************************ +void CLCDBar::SetAlignment(int iAlignment) +{ + m_iAlignment = iAlignment; +} + +//************************************************************************ +// updates the bar +//************************************************************************ +bool CLCDBar::Update() +{ + return true; +} + +//************************************************************************ +// specifies the bar's range +//************************************************************************ +void CLCDBar::SetRange(int iMin, int iMax) +{ + m_iMin = iMin; + m_iMax = iMax; + if(m_iPosition < m_iMin) + m_iPosition = m_iMin; + else if(m_iPosition > m_iMax ) + m_iPosition = m_iMax; +} + +//************************************************************************ +// draws the bar +//************************************************************************ +bool CLCDBar::Draw(CLCDGfx *pGfx) +{ + if((m_iMode != MODE_SCROLLBAR || m_iSliderSize > 0) && m_iMax >= m_iMin) + { + // draw border + pGfx->DrawRect(0,0,GetWidth(),GetHeight()); + + // initialize variables + int iSize = (m_iMax - m_iMin)+1; + int iPosition = m_iPosition - m_iMin; + int iPixels = m_iOrientation == DIRECTION_VERTICAL?GetHeight():GetWidth(); + int iFirst=0,iLast=0; + + // generate scrollbar offsets + if(m_iMode == MODE_SCROLLBAR) + { + int iOffset = iPosition; + if(m_iSliderSize >= 2) + { + switch(m_iAlignment) + { + case CENTER: + iOffset -= (m_iSliderSize-1)/2; + break; + case BOTTOM: + iOffset -= (m_iSliderSize-1); + break; + case TOP: + break; + } + if(iOffset < 0) + iOffset = 0; + } + int iEnd = iOffset + m_iSliderSize; + if(iEnd > iSize) + iEnd = iSize; + + iFirst = iPixels*((float)iOffset/(float)iSize); + iLast = iPixels*((float)iEnd/(float)iSize); + } + // generate progressbar offsets + else if(m_iMode == MODE_PROGRESSBAR) + { + iFirst = 1; + iLast = iPixels*((float)iPosition/(float)iSize); + } + + // draw the bar + if(m_iOrientation == DIRECTION_VERTICAL) + pGfx->DrawFilledRect(1,iFirst,GetWidth()-1,iLast-iFirst); + else + pGfx->DrawFilledRect(iFirst,1,iLast-iFirst,GetHeight()-1); + } + return true; +} \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDBar.h b/plugins/MirandaG15/LCDFramework/src/CLCDBar.h new file mode 100644 index 0000000000..1afb446132 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDBar.h @@ -0,0 +1,64 @@ +#ifndef _CLCDBar_H_ +#define _CLCDBar_H_ + +#define TOP 1 +#define CENTER 2 +#define BOTTOM 3 + +#define MODE_PROGRESSBAR 0 +#define MODE_SCROLLBAR 1 + +#define DIRECTION_VERTICAL 0 +#define DIRECTION_HORIZONTAL 1 + +class CLCDBar : public CLCDObject +{ +public: + // constructor + CLCDBar(); + // destructor + ~CLCDBar(); + + // initializes the bar + bool Initialize(); + // deintializes the bar + bool Shutdown(); + + // draws the bar + bool Draw(CLCDGfx *pGfx); + // updates the bar + bool Update(); + + // specifies the bar's mode ( scrollbar / progressbar ) + void SetMode(int iMode); + // specifies the orientation of the bar + void SetOrientation(int iDirection); + + // sets the alignment of the scrollbar position + void SetAlignment(int iAlignment); + // sets the size of the slider + void SetSliderSize(int iSize); + + // scrolls up/left + bool ScrollUp(); + inline bool ScrollLeft() { return ScrollUp(); }; + // scrolls down/right + bool ScrollDown(); + inline bool ScrollRight() { return ScrollDown(); }; + + // scrolls to the specified position + bool ScrollTo(int iPosition); + // specifies the bar's range + void SetRange(int iMin,int iMax); + +private: + int m_iOrientation; + int m_iMode; + int m_iSliderSize; + int m_iMax; + int m_iMin; + int m_iPosition; + int m_iAlignment; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDBitmap.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDBitmap.cpp new file mode 100644 index 0000000000..5ce448769d --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDBitmap.cpp @@ -0,0 +1,48 @@ +#include "stdafx.h" +#include "CLCDBitmap.h" + +CLCDBitmap::CLCDBitmap() +{ + m_hBitmap = NULL; +} + +CLCDBitmap::~CLCDBitmap() +{ +} + +bool CLCDBitmap::Initialize() +{ + return true; +} + +bool CLCDBitmap::Shutdown() +{ + return true; +} + +bool CLCDBitmap::Update() +{ + return true; +} + +bool CLCDBitmap::Draw(CLCDGfx *pGfx) +{ + if(m_hBitmap) + { + HDC hCompatibleDC = CreateCompatibleDC(pGfx->GetHDC()); + HBITMAP hOldBitmap = (HBITMAP)SelectObject(hCompatibleDC, m_hBitmap); + + BitBlt(pGfx->GetHDC(), 0, 0, GetWidth(), GetHeight(), hCompatibleDC, 0, 0, SRCCOPY); + + // restores + SelectObject(hCompatibleDC, hOldBitmap); + DeleteDC(hCompatibleDC); + } + return true; +} + +void CLCDBitmap::SetBitmap(HBITMAP hBitmap) +{ + ASSERT(NULL != hBitmap); + m_hBitmap = hBitmap; +} \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDBitmap.h b/plugins/MirandaG15/LCDFramework/src/CLCDBitmap.h new file mode 100644 index 0000000000..d8c7813b81 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDBitmap.h @@ -0,0 +1,31 @@ +#ifndef _CLCDBITMAP_H_ +#define _CLCDBITMAP_H_ + +#include "CLCDGfx.h" +#include "CLCDObject.h" + +class CLCDBitmap : public CLCDObject +{ +public: + // constructor + CLCDBitmap(); + // destructor + ~CLCDBitmap(); + + // Initializes the bitmap + bool Initialize(); + // Deinitializes the bitmap + bool Shutdown(); + + // updates the bitmap + bool Update(); + // draws the bitmap + bool Draw(CLCDGfx *pGfx); + + // Sets the bitmap + void SetBitmap(HBITMAP hBitmap); +private: + HBITMAP m_hBitmap; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDConnection.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDConnection.cpp new file mode 100644 index 0000000000..cee754739c --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDConnection.cpp @@ -0,0 +1,173 @@ +#include "stdafx.h" +#include "CLCDConnection.h" + +//************************************************************************ +// Constructor +//************************************************************************ +CLCDConnection::CLCDConnection() +{ + m_bReconnect = true; +} + +//************************************************************************ +// Destructor +//************************************************************************ +CLCDConnection::~CLCDConnection() +{ +} + +//************************************************************************ +// Initializes the connection to the LCD +//************************************************************************ +bool CLCDConnection::Initialize(tstring strAppletName,bool bAutostart, bool bConfigDialog) +{ + return false; +} + +//************************************************************************ +// Closes the connection with the LCD +//************************************************************************ +bool CLCDConnection::Shutdown() +{ + return false; +} + +//************************************************************************ +// Update function +//************************************************************************ +bool CLCDConnection::Update() +{ + return false; +} + +//************************************************************************ +// returns the connections state +//************************************************************************ +int CLCDConnection::GetConnectionState() +{ + return DISCONNECTED; +} + +//************************************************************************ +// Returns the state of the specified Button +//************************************************************************ +bool CLCDConnection::GetButtonState(int iButton) +{ + return false; +} + +//************************************************************************ +// returns the id of the specified button +//************************************************************************ +int CLCDConnection::GetButtonId(int iButton) { + return 0; +} + +//************************************************************************ +// Hides the applet +//************************************************************************ +bool CLCDConnection::HideApplet() +{ + return false; +} + +//************************************************************************ +// Draws the specified bitmap on the LCD +//************************************************************************ +bool CLCDConnection::Draw() +{ + return false; +} + +//************************************************************************ +// Temporarily brings the applet to foreground +//************************************************************************ +void CLCDConnection::SetAlert(bool bAlert) +{ +} + +//************************************************************************ +// Activates the applet on the LCD +//************************************************************************ +void CLCDConnection::SetAsForeground(bool bSetAsForeground) +{ +} + +//************************************************************************ +// returns wether the applet is currently activated +//************************************************************************ +bool CLCDConnection::IsForeground() +{ + return false; +} + +//************************************************************************ +// Returns the display size +//************************************************************************ +SIZE CLCDConnection::GetDisplaySize() +{ + SIZE size; + size.cx = 0; + size.cy = 0; + return size; +} + +//************************************************************************ +// Returns the number of buttons for the display +//************************************************************************ +int CLCDConnection::GetButtonCount() +{ + return 0; +} + +//************************************************************************ +// Returns the number of available colors +//************************************************************************ +int CLCDConnection::GetColorCount() +{ + return 0; +} + +//************************************************************************ +// Get the pointer to the pixel buffer +//************************************************************************ +PBYTE CLCDConnection::GetPixelBuffer() +{ + return NULL; +} + +//************************************************************************ +// Get the pointer to the pixel buffer +//************************************************************************ +CLCDDevice* CLCDConnection::GetAttachedDevice(int iIndex) +{ + return NULL; +} + +//************************************************************************ +// Connects to the specified LCD +//************************************************************************ +bool CLCDConnection::Connect(int iIndex) { + return false; +} + +//************************************************************************ +// Connects to the specified LCD +//************************************************************************ +bool CLCDConnection::Disconnect() { + return false; +} + +//************************************************************************ +// Toggles the automatic reconnection +//************************************************************************ +void CLCDConnection::SetReconnect(bool bSet) { + m_bReconnect = bSet; +} + +//************************************************************************ +// returns a pointer to the current device +//************************************************************************ +CLCDDevice* CLCDConnection::GetConnectedDevice() { + return NULL; +} \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDConnection.h b/plugins/MirandaG15/LCDFramework/src/CLCDConnection.h new file mode 100644 index 0000000000..099f850ec9 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDConnection.h @@ -0,0 +1,74 @@ +#ifndef _CLCDCONNECTION_H_ +#define _CLCDCONNECTION_H_ + +#include "CLCDDevice.h" + +#define TYPE_LOGITECH 0 + +#define CONNECTED 1 +#define DISCONNECTED 0 + +class CLCDConnection +{ +protected: + bool m_bReconnect; + +public: + // returns the connection type + virtual int GetConnectionType()=0; + + // returns a pointer to a vector of LCDDevices + virtual CLCDDevice* GetAttachedDevice(int iIndex); + // returns a pointer to the current device + virtual CLCDDevice* GetConnectedDevice(); + + // Initializes the connection to the LCD + virtual bool Initialize(tstring strAppletName,bool bAutostart = false, bool bConfigDialog = false); + + // Connects to the specified LCD + virtual bool Connect(int iIndex = 0); + // Connects to the specified LCD + virtual bool Disconnect(); + + // toggles the automatic reconnection + void SetReconnect(bool bSet); + + // Closes the connection with the LCD + virtual bool Shutdown(); + // Update function + virtual bool Update(); + // Draws the specified bitmap on the LCD + virtual bool Draw(); + // Hides the applet + virtual bool HideApplet(); + + // returns the connections state + virtual int GetConnectionState(); + + // returns the id of the specified button + virtual int GetButtonId(int iButton); + // Returns the state of the specified Button + virtual bool GetButtonState(int iButton); + // Temporarily brings the applet to foreground + virtual void SetAlert(bool bAlert); + // Activates the applet on the LCD + virtual void SetAsForeground(bool bSetAsForeground); + // returns wether the applet is currently activated + virtual bool IsForeground(); + + // Returns the display size + virtual SIZE GetDisplaySize(); + // Returns the number of buttons for the display + virtual int GetButtonCount(); + // Returns the number of available colors + virtual int GetColorCount(); + + // Get the pointer to the pixel buffer + virtual PBYTE GetPixelBuffer(); + +public: + CLCDConnection(); + virtual ~CLCDConnection(); +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDConnectionLogitech.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDConnectionLogitech.cpp new file mode 100644 index 0000000000..7cbc355c99 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDConnectionLogitech.cpp @@ -0,0 +1,1023 @@ +#include "stdafx.h" +#include "CLCDConnectionLogitech.h" +#include "CLCDOutputManager.h" + +DWORD WINAPI softButtonCallback(IN int device, + IN DWORD dwButtons, + IN const PVOID pContext) { + ((CLCDConnectionLogitech*)pContext)->OnSoftButtonCB(dwButtons); + return 0; +} + +DWORD WINAPI notificationCallback(IN int connection, + IN const PVOID pContext, + IN DWORD notificationCode, + IN DWORD notifyParm1, + IN DWORD notifyParm2, + IN DWORD notifyParm3, + IN DWORD notifyParm4) { + ((CLCDConnectionLogitech*)pContext)->OnNotificationCB(notificationCode,notifyParm1,notifyParm2,notifyParm3,notifyParm4); + return 0; +} + + +DWORD WINAPI initializeDrawingThread( LPVOID pParam ) { + ((CLCDConnectionLogitech*)pParam)->runDrawingThread(); + return 0; +} + +void CLCDConnectionLogitech::runDrawingThread() { + m_hStopEvent = CreateEvent(NULL,FALSE,FALSE,NULL); + m_hDrawEvent = CreateEvent(NULL,FALSE,FALSE,NULL); + + DWORD dwRes = 0; + + while(1) { + HANDLE hArray[2] = { m_hStopEvent, m_hDrawEvent }; + dwRes = WaitForMultipleObjects(2, hArray, FALSE, INFINITE); + if(dwRes == WAIT_OBJECT_0) { + break; + } else if(dwRes == WAIT_OBJECT_0+1) { + DWORD rc; + if(GetConnectionState() != CONNECTED) { + continue; + } + // do a sync update if the applet is in the foreground, or every 500 ms + // the delay is there because sync updates can take up to 33ms to fail + if(m_dwForegroundCheck < GetTickCount()) + { + m_dwForegroundCheck = GetTickCount() + 500; + rc = lgLcdUpdateBitmap(m_hDevice, &m_lcdBitmap.hdr, LGLCD_SYNC_COMPLETE_WITHIN_FRAME(m_iPriority)); + if(rc == ERROR_ACCESS_DENIED) + { + rc = ERROR_SUCCESS; + m_bIsForeground = false; + } + else if(rc == ERROR_SUCCESS) + m_bIsForeground = true; + } + else + rc = lgLcdUpdateBitmap(m_hDevice, &m_lcdBitmap.hdr, LGLCD_ASYNC_UPDATE(m_iPriority)); + + if(rc != ERROR_SUCCESS) { + HandleErrorFromAPI(rc); + } + } + } + CloseHandle(m_hStopEvent); + CloseHandle(m_hDrawEvent); +} + +// the connection instance +CLCDConnectionLogitech *CLCDConnectionLogitech::m_pInstance = NULL; + +//************************************************************************ +// returns the connection type +//************************************************************************ +int CLCDConnectionLogitech::GetConnectionType() +{ + return TYPE_LOGITECH; +} + +//************************************************************************ +// Constructor +//************************************************************************ +CLCDConnectionLogitech::CLCDConnectionLogitech() +{ + m_iNumQVGADevices = 0; + m_iNumBWDevices = 0; + + m_pDrawingBuffer = NULL; + m_pConnectedDevice = NULL; + m_hKeyboardHook = NULL; + m_bVolumeWheelHook = false; + + m_dwButtonState = 0; + m_bConnected = false; + m_bSetAsForeground = false; + m_dwForegroundCheck = 0; + + m_hHIDDeviceHandle = NULL; + m_hConnection = LGLCD_INVALID_CONNECTION; + m_hDevice = LGLCD_INVALID_DEVICE; + + m_bIsForeground = false; + + m_hDrawEvent = NULL; + m_hStopEvent = NULL; + + CLCDConnectionLogitech::m_pInstance = this; + + m_hDrawingThread = CreateThread( 0, 0, initializeDrawingThread, (void*)this, 0, 0); +} + +//************************************************************************ +// Destructor +//************************************************************************ +CLCDConnectionLogitech::~CLCDConnectionLogitech() +{ + do { + SetEvent(m_hStopEvent); + } while(WaitForSingleObject(m_hDrawingThread,500) == WAIT_TIMEOUT); + + if(m_pDrawingBuffer != NULL) { + free(m_pDrawingBuffer); + } + SetVolumeWheelHook(false); +} + +//************************************************************************ +// Initializes the connection to the LCD +//************************************************************************ +bool CLCDConnectionLogitech::Initialize(tstring strAppletName,bool bAutostart, bool bConfigDialog) +{ + + m_strAppletName = strAppletName; + // initialize the library + if(lgLcdInit() != ERROR_SUCCESS) + return false; + + ZeroMemory(&m_connectContext, sizeof(m_connectContext)); + m_connectContext.connection = LGLCD_INVALID_CONNECTION; + + m_connectContext.appFriendlyName = m_strAppletName.c_str(); + m_connectContext.isAutostartable = bAutostart; + m_connectContext.isPersistent = bAutostart; + m_connectContext.dwAppletCapabilitiesSupported = LGLCD_APPLET_CAP_BW | LGLCD_APPLET_CAP_QVGA; + m_connectContext.onNotify.notificationCallback = notificationCallback; + m_connectContext.onNotify.notifyContext = (PVOID)this; + + if(bConfigDialog) { + m_connectContext.onConfigure.configCallback = CLCDOutputManager::configDialogCallback; + } else { + m_connectContext.onConfigure.configCallback = NULL; + } + m_connectContext.onConfigure.configContext = NULL; + + lgLcdSetDeviceFamiliesToUse(m_connectContext.connection,LGLCD_DEVICE_FAMILY_ALL,NULL); + + return true; +} + +//************************************************************************ +// returns the name of the attached device +//************************************************************************ +tstring CLCDConnectionLogitech::GetDeviceName() { + if(m_pConnectedDevice->GetIndex() == LGLCD_DEVICE_BW) { + return _T("G15/Z10"); + } else { + return _T("G19"); + } +} + +//************************************************************************ +// enumerates all attached devices +//************************************************************************ +CLgLCDDevice* CLCDConnectionLogitech::GetAttachedDevice(int iIndex) { + std::vector::iterator i = m_lcdDevices.begin(); + for(;i!=m_lcdDevices.end();i++) { + if((*i)->GetIndex() == iIndex) { + return *i; + } + } + + return NULL; +} + +//************************************************************************ +// disconnects the device +//************************************************************************ +bool CLCDConnectionLogitech::Disconnect() { + if(!m_bConnected) + return false; + + if(m_pConnectedDevice != NULL) { + delete m_pConnectedDevice; + m_pConnectedDevice = NULL; + } + + m_bReconnect = false; + + HIDDeInit(); + lgLcdClose(m_hDevice); + m_hDevice = LGLCD_INVALID_DEVICE; + + CLCDOutputManager::GetInstance()->OnDeviceDisconnected(); + + m_bConnected = false; + return true; +} + +//************************************************************************ +// returns a pointer to the current device +//************************************************************************ +CLgLCDDevice* CLCDConnectionLogitech::GetConnectedDevice() { + return m_pConnectedDevice; +} + +//************************************************************************ +// connects to the device +//************************************************************************ +bool CLCDConnectionLogitech::Connect(int iIndex) +{ + DWORD rc; + lgLcdOpenByTypeContext OpenContext; + if(m_bConnected && (iIndex == 0 || iIndex == GetConnectedDevice()->GetIndex())) + return true; + + if(m_hConnection == LGLCD_INVALID_CONNECTION) + { + rc = lgLcdConnectEx(&m_connectContext); + // establish the connection + if(ERROR_SUCCESS == rc) + { + m_hConnection = m_connectContext.connection; + m_hDevice = LGLCD_INVALID_CONNECTION; + + TRACE(_T("CLCDConnectionLogitech: Connection to LCDManager established successfully!\n")); + } + else { + return false; + } + } + + // check if the specified device exists + m_pConnectedDevice = GetAttachedDevice(iIndex); + if(m_pConnectedDevice == NULL) { + iIndex = (!iIndex || iIndex == LGLCD_DEVICE_BW) ? LGLCD_DEVICE_QVGA : LGLCD_DEVICE_BW; + m_pConnectedDevice = GetAttachedDevice(iIndex); + if(m_pConnectedDevice == NULL) { + return false; + } + } + + // close the lcd device before we open up another + if (LGLCD_INVALID_DEVICE != m_hDevice) { + Disconnect(); + } + + // Now lets open the LCD. We must initialize the g_OpenContext structure. + ZeroMemory(&OpenContext, sizeof(OpenContext)); + OpenContext.connection = m_hConnection; + OpenContext.deviceType = LGLCD_DEVICE_QVGA; + OpenContext.device = LGLCD_INVALID_DEVICE; + + // softbutton callbacks are not needed + OpenContext.onSoftbuttonsChanged.softbuttonsChangedCallback = softButtonCallback; + OpenContext.onSoftbuttonsChanged.softbuttonsChangedContext = (PVOID)this; + + // open the lcd + rc = lgLcdOpenByType(&OpenContext); + // failed to open the lcd + if(rc != ERROR_SUCCESS) + return false; + + m_hDevice = OpenContext.device; + + // Create the pixel buffer + m_lcdBitmap.hdr.Format = OpenContext.deviceType==LGLCD_DEVICE_QVGA?LGLCD_BMP_FORMAT_QVGAx32:LGLCD_BMP_FORMAT_160x43x1; + if(m_pDrawingBuffer != NULL) { + free(m_pDrawingBuffer); + } + + m_pPixels = OpenContext.deviceType==LGLCD_DEVICE_QVGA? m_lcdBitmap.bmp_qvga32.pixels:m_lcdBitmap.bmp_mono.pixels; + m_iPixels = OpenContext.deviceType==LGLCD_DEVICE_QVGA? sizeof(m_lcdBitmap.bmp_qvga32.pixels):sizeof(m_lcdBitmap.bmp_mono.pixels); + m_pDrawingBuffer = (PBYTE) malloc(m_iPixels); + ZeroMemory(m_pDrawingBuffer, m_iPixels); + + m_iPriority = LGLCD_PRIORITY_NORMAL; + m_bConnected = true; + + HIDInit(); + + m_bReconnect = true; + + CLCDOutputManager::GetInstance()->OnDeviceConnected(); + return true; +} + +//************************************************************************ +// Closes the connection with the LCD +//************************************************************************ +bool CLCDConnectionLogitech::Shutdown() +{ + m_bConnected = false; + + SetVolumeWheelHook(false); + + Disconnect(); + + if (LGLCD_INVALID_CONNECTION != m_hDevice) + lgLcdDisconnect(m_hConnection); + + lgLcdDeInit(); + + return true; +} + +//************************************************************************ +// Reads data from the keyboard HID device +//************************************************************************ +bool CLCDConnectionLogitech::HIDReadData(BYTE* data) { + static OVERLAPPED olRead; + static HANDLE hReadEvent = CreateEvent(NULL,false,true,_T("ReadEvent")); + static BYTE privateBuffer[9]; + + DWORD TransBytes; + if(!m_bConnected) { + SetEvent(hReadEvent); + return false; + } + + DWORD dwRes = WaitForSingleObject(hReadEvent,0); + if(dwRes == WAIT_OBJECT_0) { + bool bRes = false; + if(GetOverlappedResult(m_hHIDDeviceHandle,&olRead,&TransBytes,false)) { + memcpy(data,privateBuffer,9*sizeof(BYTE)); + bRes = true; + } + + memset(&olRead,0,sizeof(OVERLAPPED)); + olRead.hEvent = hReadEvent; + + if(!ReadFile(m_hHIDDeviceHandle,privateBuffer,9,&TransBytes,&olRead)) { + DWORD error = GetLastError(); + if(error != ERROR_IO_PENDING) { + return false; + } + } + return bRes; + } + + return false; +} + +void CLCDConnectionLogitech::OnSoftButtonCB(DWORD state) { + m_dwButtonState = state; +} + +void CLCDConnectionLogitech::OnNotificationCB( DWORD notificationCode, DWORD notifyParm1, DWORD notifyParm2, DWORD notifyParm3, DWORD notifyParm4) { + CLgLCDDevice *device; + + switch(notificationCode) { + case LGLCD_NOTIFICATION_DEVICE_ARRIVAL: { + int *counter = notifyParm1 == LGLCD_DEVICE_QVGA ? &m_iNumQVGADevices : &m_iNumBWDevices; + if(*counter == 0) { + SIZE size; + if(LGLCD_DEVICE_QVGA) { + size.cx = 320; + size.cy = 240; + device = new CLgLCDDevice(notifyParm1,size,7,4); + } else { + size.cx = 320; + size.cy = 240; + device = new CLgLCDDevice(notifyParm1,size,4,1); + } + m_lcdDevices.push_back(device); + } + + (*counter)++; + break; + } + case LGLCD_NOTIFICATION_DEVICE_REMOVAL: { + int *counter = notifyParm1 == LGLCD_DEVICE_QVGA ? &m_iNumQVGADevices : &m_iNumBWDevices; + (*counter)--; + if(*counter == 0) { + std::vector::iterator i = m_lcdDevices.begin(); + for(;i!=m_lcdDevices.end();i++) { + if((*i)->GetIndex() == notifyParm1) { + device = *i; + + if(device == m_pConnectedDevice) { + HandleErrorFromAPI(ERROR_DEVICE_NOT_CONNECTED); + } + + m_lcdDevices.erase(i); + delete device; + + break; + } + } + } + break; + } + } +} + +//************************************************************************ +// Update function +//************************************************************************ +bool CLCDConnectionLogitech::Update() +{ + // check for lcd devices + if (LGLCD_INVALID_DEVICE == m_hDevice ) + { + if(m_bReconnect) { + Connect(); + } + } + + BYTE buffer[9]; + if(HIDReadData(buffer)) { + int button = 0; + // mr key + if(buffer[7] & 0x40) { + button = 20; + // lightbulb key + } else if(buffer[1] & 0x80) { + button = 21; + } + // m1,m2,m3 + for(int i=0,w=1;i<3;i++,w*=2) { + if(buffer[6+i] & w) { + button = 30+i; + } + } + // g1 to g18 + if(buffer[8] & 0x40) { + button = 18; + } else { + for(int j=0;j<3;j++) { + int p = 1,w = 1; + if(j == 1) { + p = 2; + } else if(j == 2) { + w = 4; + } + + for(int i=0;i<6;i++,w*=2) { + if(buffer[p+i] & w) { + button = 1+j*6+i; + } + } + } + } + if(button != 0) { + TRACE(_T("GKey pressed: %d \n"),button); + } + } + + return true; +} + +//************************************************************************ +// returns the id of the specified button +//************************************************************************ +int CLCDConnectionLogitech::GetButtonId(int iButton) { + if(m_pConnectedDevice->GetIndex() == LGLCD_DEVICE_BW) { + switch(iButton) + { + case 0: return LGLCDBUTTON_BUTTON0; break; + case 1: return LGLCDBUTTON_BUTTON1; break; + case 2: return LGLCDBUTTON_BUTTON2; break; + case 3: return LGLCDBUTTON_BUTTON3; break; + case 4: return LGLCDBUTTON_BUTTON4; break; + case 5: return LGLCDBUTTON_BUTTON5; break; + case 6: return LGLCDBUTTON_BUTTON6; break; + case 7: return LGLCDBUTTON_BUTTON7; break; + } + } else { + switch(iButton) + { + case 0: return LGLCDBUTTON_LEFT; break; + case 1: return LGLCDBUTTON_RIGHT; break; + case 2: return LGLCDBUTTON_OK; break; + case 3: return LGLCDBUTTON_CANCEL; break; + case 4: return LGLCDBUTTON_UP; break; + case 5: return LGLCDBUTTON_DOWN; break; + case 6: return LGLCDBUTTON_MENU; break; + } + } + + return 0; +} + +//************************************************************************ +// Returns the state of the specified Button +//************************************************************************ +bool CLCDConnectionLogitech::GetButtonState(int iButton) +{ + if(!GetConnectionState()==CONNECTED) + return false; + + DWORD dwButton = GetButtonId(iButton); + + if(m_dwButtonState & dwButton) + return true; + return false; +} + +//************************************************************************ +// Hides the applet +//************************************************************************ +bool CLCDConnectionLogitech::HideApplet() +{ + if(!GetConnectionState()==CONNECTED) + return false; + + DWORD rc; + + rc = lgLcdUpdateBitmap(m_hDevice, &m_lcdBitmap.hdr, LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW)); + if(rc != ERROR_SUCCESS) + return false; + + return true; +} + +//************************************************************************ +// Draws the specified bitmap on the LCD +//************************************************************************ +bool CLCDConnectionLogitech::Draw() +{ + if(!GetConnectionState()==CONNECTED || !m_hDrawEvent) + return false; + + memcpy(m_pPixels,m_pDrawingBuffer,m_iPixels); + SetEvent(m_hDrawEvent); + return true; +} + +//************************************************************************ +// Temporarily brings the applet to foreground +//************************************************************************ +void CLCDConnectionLogitech::SetAlert(bool bAlert) +{ + m_iPriority = bAlert?LGLCD_PRIORITY_ALERT:LGLCD_PRIORITY_NORMAL; +} + +//************************************************************************ +// Activates the applet on the LCD +//************************************************************************ +void CLCDConnectionLogitech::SetAsForeground(bool bSetAsForeground) +{ + // TODO: Activate when 1.02 is out + DWORD dwSet = bSetAsForeground ? LGLCD_LCD_FOREGROUND_APP_YES : LGLCD_LCD_FOREGROUND_APP_NO; + m_bSetAsForeground = bSetAsForeground; + if (LGLCD_INVALID_DEVICE != m_hDevice) + { + lgLcdSetAsLCDForegroundApp(m_hDevice, bSetAsForeground); + } +} + +//************************************************************************ +// returns wether the applet is currently activated +//************************************************************************ +bool CLCDConnectionLogitech::IsForeground() +{ + return m_bIsForeground; +} + +//************************************************************************ +// Returns the display size +//************************************************************************ +SIZE CLCDConnectionLogitech::GetDisplaySize() +{ + SIZE size = {0,0}; + + if(!GetConnectionState()==CONNECTED) + return size; + + return m_pConnectedDevice->GetDisplaySize(); +} + +//************************************************************************ +// Returns the number of buttons for the display +//************************************************************************ +int CLCDConnectionLogitech::GetButtonCount() +{ + if(!GetConnectionState()==CONNECTED) + return 0; + + return m_pConnectedDevice->GetButtonCount(); +} + +//************************************************************************ +// Returns the number of available colors +//************************************************************************ +int CLCDConnectionLogitech::GetColorCount() +{ + if(!GetConnectionState()==CONNECTED) + return 0; + + return m_pConnectedDevice->GetColorCount(); +} + +//************************************************************************ +// Get the pointer to the pixel buffer +//************************************************************************ +PBYTE CLCDConnectionLogitech::GetPixelBuffer() +{ + if(!GetConnectionState()==CONNECTED) + return NULL; + + return (PBYTE)m_pDrawingBuffer; +} + +//************************************************************************ +// CLCDConnectionLogitech::HandleErrorFromAPI +//************************************************************************ +void CLCDConnectionLogitech::HandleErrorFromAPI(DWORD dwRes) +{ + switch(dwRes) + { + // all is well + case ERROR_SUCCESS: + break; + // we lost our device + case ERROR_DEVICE_NOT_CONNECTED: + TRACE(_T("CLCDConnectionLogitech::HandleErrorFromAPI(): Device was unplugged, closing device\n")); + Disconnect(); + SetReconnect(true); + SetVolumeWheelHook(false); + + break; + default: + TRACE(_T("CLCDConnectionLogitech::HandleErrorFromAPI(): FATAL ERROR, closing device and connection\n")); + Disconnect(); + SetReconnect(true); + + lgLcdDisconnect(m_hConnection); + m_hConnection = LGLCD_INVALID_CONNECTION; + + SetVolumeWheelHook(false); + break; + } +} + +//************************************************************************ +// returns the connection state +//************************************************************************ +int CLCDConnectionLogitech::GetConnectionState() +{ + return m_bConnected ? CONNECTED : DISCONNECTED; +} + +bool CLCDConnectionLogitech::HIDInit() +{ + if(GetConnectionState() != CONNECTED || + m_pConnectedDevice->GetIndex() != LGLCD_DEVICE_BW) //LGLCD_DEVICE_FAMILY_KEYBOARD_G15) + return false; + +// Logitech G15 + int VendorID = 0x046d; + int ProductID = 0xc222; + + //Use a series of API calls to find a HID with a specified Vendor IF and Product ID. + + HIDD_ATTRIBUTES Attributes; + DWORD DeviceUsage; + SP_DEVICE_INTERFACE_DATA devInfoData; + bool LastDevice = FALSE; + int MemberIndex = 0; + LONG Result; + + DWORD Length = 0; + PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL; + HANDLE hDevInfo =NULL; + GUID HidGuid; + ULONG Required = 0; + + bool MyDeviceDetected = false; + + /* + API function: HidD_GetHidGuid + Get the GUID for all system HIDs. + Returns: the GUID in HidGuid. + */ + + HidD_GetHidGuid(&HidGuid); + + /* + API function: SetupDiGetClassDevs + Returns: a handle to a device information set for all installed devices. + Requires: the GUID returned by GetHidGuid. + */ + + hDevInfo=SetupDiGetClassDevs + (&HidGuid, + NULL, + NULL, + DIGCF_PRESENT|DIGCF_INTERFACEDEVICE); + + devInfoData.cbSize = sizeof(devInfoData); + + //Step through the available devices looking for the one we want. + //Quit on detecting the desired device or checking all available devices without success. + + MemberIndex = 0; + LastDevice = FALSE; + + do + { + /* + API function: SetupDiEnumDeviceInterfaces + On return, MyDeviceInterfaceData contains the handle to a + SP_DEVICE_INTERFACE_DATA structure for a detected device. + Requires: + The DeviceInfoSet returned in SetupDiGetClassDevs. + The HidGuid returned in GetHidGuid. + An index to specify a device. + */ + + Result=SetupDiEnumDeviceInterfaces + (hDevInfo, + 0, + &HidGuid, + MemberIndex, + &devInfoData); + + if (Result != 0) + { + //A device has been detected, so get more information about it. + + /* + API function: SetupDiGetDeviceInterfaceDetail + Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure + containing information about a device. + To retrieve the information, call this function twice. + The first time returns the size of the structure in Length. + The second time returns a pointer to the data in DeviceInfoSet. + Requires: + A DeviceInfoSet returned by SetupDiGetClassDevs + The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces. + + The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure. + This application doesn't retrieve or use the structure. + If retrieving the structure, set + MyDeviceInfoData.cbSize = length of MyDeviceInfoData. + and pass the structure's address. + */ + + //Get the Length value. + //The call will return with a "buffer too small" error which can be ignored. + + Result = SetupDiGetDeviceInterfaceDetail + (hDevInfo, + &devInfoData, + NULL, + 0, + &Length, + NULL); + + //Allocate memory for the hDevInfo structure, using the returned Length. + + detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length); + + //Set cbSize in the detailData structure. + + detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); + + //Call the function again, this time passing it the returned buffer size. + + Result = SetupDiGetDeviceInterfaceDetail + (hDevInfo, + &devInfoData, + detailData, + Length, + &Required, + NULL); + + // Open a handle to the device. + // To enable retrieving information about a system mouse or keyboard, + // don't request Read or Write access for this handle. + + /* + API function: CreateFile + Returns: a handle that enables reading and writing to the device. + Requires: + The DevicePath in the detailData structure + returned by SetupDiGetDeviceInterfaceDetail. + */ + + m_hHIDDeviceHandle=CreateFile + (detailData->DevicePath, + FILE_GENERIC_READ | FILE_GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, + (LPSECURITY_ATTRIBUTES)NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); + + /* + API function: HidD_GetAttributes + Requests information from the device. + Requires: the handle returned by CreateFile. + Returns: a HIDD_ATTRIBUTES structure containing + the Vendor ID, Product ID, and Product Version Number. + Use this information to decide if the detected device is + the one we're looking for. + */ + + //Set the Size to the number of bytes in the structure. + + Attributes.Size = sizeof(Attributes); + + Result = HidD_GetAttributes + (m_hHIDDeviceHandle, + &Attributes); + + //Is it the desired device? + MyDeviceDetected = FALSE; + + if (Attributes.VendorID == VendorID) + { + if (Attributes.ProductID == ProductID) + { + //Both the Vendor ID and Product ID match. + MyDeviceDetected = TRUE; + } + else + CloseHandle(m_hHIDDeviceHandle); + + } + else + CloseHandle(m_hHIDDeviceHandle); + + //Free the memory used by the detailData structure (no longer needed). + free(detailData); + } + + else + LastDevice=TRUE; + + MemberIndex = MemberIndex + 1; + } //do + while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE)); + + if(MyDeviceDetected) + { + PHIDP_PREPARSED_DATA PreparsedData; + + HidD_GetPreparsedData + (m_hHIDDeviceHandle, + &PreparsedData); + + HidP_GetCaps + (PreparsedData, + &m_HIDCapabilities); + + HidD_FreePreparsedData(PreparsedData); + } + //Free the memory reserved for hDevInfo by SetupDiClassDevs. + + SetupDiDestroyDeviceInfoList(hDevInfo); + + return MyDeviceDetected; +} + +bool CLCDConnectionLogitech::HIDDeInit() +{ + if(!m_hHIDDeviceHandle) + return false; + + CloseHandle(m_hHIDDeviceHandle); + m_hHIDDeviceHandle = NULL; + return true; +} + +SG15LightStatus CLCDConnectionLogitech::GetLightStatus() +{ + SG15LightStatus status; + status.bMKey[0] = false; + status.bMKey[1] = false; + status.bMKey[2] = false; + status.bMRKey = false; + status.eKBDBrightness = KBD_OFF; + status.eLCDBrightness = LCD_OFF; + + if(GetConnectionState() != CONNECTED || + m_pConnectedDevice->GetIndex() != LGLCD_DEVICE_BW) //m_lcdDeviceDesc.deviceFamilyId != LGLCD_DEVICE_FAMILY_KEYBOARD_G15) + return status; + + byte *data = new byte[m_HIDCapabilities.FeatureReportByteLength]; + + data[0] = 0x02; + data[1] = 0x02; + data[2] = 0x00; + data[3] = 0x00; + + HidD_GetFeature(m_hHIDDeviceHandle,data,m_HIDCapabilities.FeatureReportByteLength); + + + // data[1] = Keys + status.eKBDBrightness = (EKBDBrightness)data[1]; + + // data[2] = LCD + switch(data[2]) + { + case 0x02: + status.eLCDBrightness = LCD_ON; + break; + case 0x01: + status.eLCDBrightness = LCD_MEDIUM; + break; + default: + status.eLCDBrightness = LCD_OFF; + break; + } + // MKeys + status.bMKey[0] = !(data[3] & G15_M1_LIGHT); + status.bMKey[1] = !(data[3] & G15_M2_LIGHT); + status.bMKey[2] = !(data[3] & G15_M3_LIGHT); + + // MRKey + status.bMRKey = !(data[3] & G15_MR_LIGHT); + + free(data); + + return status; +} + +void CLCDConnectionLogitech::SetMKeyLight(bool bM1,bool bM2,bool bM3,bool bMR) +{ + if(GetConnectionState() != CONNECTED || + m_pConnectedDevice->GetIndex() != LGLCD_DEVICE_BW) //m_lcdDeviceDesc.deviceFamilyId != LGLCD_DEVICE_FAMILY_KEYBOARD_G15) + return; + + byte *data = new byte[m_HIDCapabilities.FeatureReportByteLength]; + data[0] = 0x02; + data[1] = 0x04; + data[2] = 0x00; + + if(!bM1) + data[2] |= G15_M1_LIGHT; + if(!bM2) + data[2] |= G15_M2_LIGHT; + if(!bM3) + data[2] |= G15_M3_LIGHT; + if(!bMR) + data[2] |= G15_MR_LIGHT; + + data[3] = 0x00; + + HidD_SetFeature(m_hHIDDeviceHandle, data, m_HIDCapabilities.FeatureReportByteLength); + free(data); +} + +void CLCDConnectionLogitech::SetLCDBacklight(ELCDBrightness eBrightness) +{ + if(GetConnectionState() != CONNECTED || + m_pConnectedDevice->GetIndex() != LGLCD_DEVICE_BW) //m_lcdDeviceDesc.deviceFamilyId != LGLCD_DEVICE_FAMILY_KEYBOARD_G15) + return; + + byte *data = new byte[m_HIDCapabilities.FeatureReportByteLength]; + + data[0] = 0x02; + data[1] = 0x02; + data[2] = eBrightness; + data[3] = 0x00; + + HidD_SetFeature(m_hHIDDeviceHandle, data, m_HIDCapabilities.FeatureReportByteLength); + + free(data); +} + +void CLCDConnectionLogitech::SetKBDBacklight(EKBDBrightness eBrightness) +{ + if(GetConnectionState() != CONNECTED || + m_pConnectedDevice->GetIndex() != LGLCD_DEVICE_BW) //m_lcdDeviceDesc.deviceFamilyId != LGLCD_DEVICE_FAMILY_KEYBOARD_G15) + return; + + byte *data = new byte[m_HIDCapabilities.FeatureReportByteLength]; + + data[0] = 0x02; + data[1] = 0x01; + data[2] = eBrightness; + data[3] = 0x00; + + HidD_SetFeature(m_hHIDDeviceHandle, data, m_HIDCapabilities.FeatureReportByteLength); + + free(data); +} + +void CLCDConnectionLogitech::SetVolumeWheelHook(bool bEnable) +{ + if(bEnable == m_bVolumeWheelHook) + return; + m_bVolumeWheelHook = bEnable; + + if(bEnable) + m_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, CLCDConnectionLogitech::KeyboardHook, GetModuleHandle(NULL), 0); + else if(m_hKeyboardHook) + UnhookWindowsHookEx(m_hKeyboardHook); +} + +LRESULT CALLBACK CLCDConnectionLogitech::KeyboardHook(int Code, WPARAM wParam, LPARAM lParam) +{ + if(Code == HC_ACTION && wParam == WM_KEYDOWN) + { + KBDLLHOOKSTRUCT *key = reinterpret_cast(lParam); + if(key->vkCode == VK_VOLUME_UP || key->vkCode == VK_VOLUME_DOWN) + { + if(m_pInstance->IsForeground()) + { + if(key->vkCode == VK_VOLUME_UP) + CLCDOutputManager::GetInstance()->OnLCDButtonDown(LGLCDBUTTON_UP); + else if(key->vkCode == VK_VOLUME_DOWN) + CLCDOutputManager::GetInstance()->OnLCDButtonDown(LGLCDBUTTON_DOWN); + return 1; + } + } + } + return CallNextHookEx(m_pInstance->m_hKeyboardHook, Code, wParam, lParam); +} \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDConnectionLogitech.h b/plugins/MirandaG15/LCDFramework/src/CLCDConnectionLogitech.h new file mode 100644 index 0000000000..1eb8389ee2 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDConnectionLogitech.h @@ -0,0 +1,148 @@ +#ifndef _CLCDCONNECTIONLOGITECH_H_ +#define _CLCDCONNECTIONLOGITECH_H_ + +#include "CLCDDevice.h" +#include "CLCDConnection.h" +#include "../g15sdk/lglcd.h" + +#define G15_M1_LIGHT 0x01 +#define G15_M2_LIGHT 0x02 +#define G15_M3_LIGHT 0x04 +#define G15_MR_LIGHT 0x08 + +enum ELCDBrightness {LCD_ON=0x20,LCD_MEDIUM=0x10,LCD_OFF=0x00}; +enum EKBDBrightness {KBD_ON=0x02,KBD_MEDIUM=0x01,KBD_OFF=0x00}; + + +struct SG15LightStatus +{ + bool bMKey[3]; + bool bMRKey; + ELCDBrightness eLCDBrightness; + EKBDBrightness eKBDBrightness; +}; + +class CLCDConnectionLogitech : public CLCDConnection +{ +public: + // returns the connection type + int GetConnectionType(); + + // Constructor / Destructor + CLCDConnectionLogitech(); + ~CLCDConnectionLogitech(); + + // returns the name of the attached device + tstring GetDeviceName(); + + // returns a pointer to the device with that index + CLgLCDDevice* GetAttachedDevice(int iIndex); + // returns a pointer to the connected device + CLgLCDDevice* GetConnectedDevice(); + + // returns the connection state + int GetConnectionState(); + + // Initializes the connection to the LCD + bool Initialize(tstring strAppletName,bool bAutostart = false, bool bConfigDialog = false); + // connects to the device + bool Connect(int iIndex = 0); + // disconnects to the device + bool Disconnect(); + + // Closes the connection with the LCD + bool Shutdown(); + // Update function + bool Update(); + // Hides the applet + bool HideApplet(); + // Draws the specified bitmap on the LCD + bool Draw(); + + // returns the id of the specified button + int GetButtonId(int iButton); + // Returns the state of the specified button + bool GetButtonState(int iButton); + // Temporarily brings the applet to foreground + void SetAlert(bool bAlert); + // Activates the applet on the LCD + void SetAsForeground(bool bSetAsForeground); + // returns wether the applet is currently activated + bool IsForeground(); + + // Returns the display size + SIZE GetDisplaySize(); + // Returns the number of buttons for the display + int GetButtonCount(); + // Returns the number of available colors + int GetColorCount(); + + // Returns a pointer to the pixel buffer + PBYTE GetPixelBuffer(); + + //---------------------------------------------- + // Special functions to control the lights + SG15LightStatus GetLightStatus(); + + void SetMKeyLight(bool bM1,bool bM2,bool bM3,bool bMR); + void SetLCDBacklight(ELCDBrightness eBrightness); + void SetKBDBacklight(EKBDBrightness eBrightness); + //---------------------------------------------- + //---------------------------------------------- + // Special functions for callbacks + void OnSoftButtonCB(DWORD state); + void OnNotificationCB( DWORD notificationCode, DWORD notifyParm1, DWORD notifyParm2, DWORD notifyParm3, DWORD notifyParm4); + //---------------------------------------------- + // Special functions for the volume wheel hook + // Activates/Deactivates the volumewheel hook + void SetVolumeWheelHook(bool bEnable); + // the keyboard hook callback + static LRESULT CALLBACK KeyboardHook(int Code, WPARAM wParam, LPARAM lParam); + //---------------------------------------------- + void runDrawingThread(); +private: + PBYTE m_pDrawingBuffer; + + CLgLCDDevice *m_pConnectedDevice; + // the connection instance + static CLCDConnectionLogitech *m_pInstance; + + // HID variables + HANDLE m_hHIDDeviceHandle; + HIDP_CAPS m_HIDCapabilities; + + // HID functions + bool HIDInit(); + bool HIDDeInit(); + bool HIDReadData(BYTE* data); + + // Keyboard hook + HHOOK m_hKeyboardHook; + bool m_bVolumeWheelHook; + + // handles API Errors + void HandleErrorFromAPI(DWORD dwRes); + + int m_iNumQVGADevices; + int m_iNumBWDevices; + + bool m_bIsForeground; + lgLcdConnectContextExW m_connectContext; + tstring m_strAppletName; + bool m_bConnected; + lgLcdBitmap m_lcdBitmap; + BYTE *m_pPixels; + int m_iPixels; + int m_hDevice; + int m_hConnection; + DWORD m_dwButtonState; + int m_iPriority; + + DWORD m_dwForegroundCheck; + bool m_bSetAsForeground; + std::vector m_lcdDevices; + + HANDLE m_hDrawingThread; + HANDLE m_hStopEvent,m_hDrawEvent; +}; +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDDevice.h b/plugins/MirandaG15/LCDFramework/src/CLCDDevice.h new file mode 100644 index 0000000000..f7d9c15922 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDDevice.h @@ -0,0 +1,63 @@ +#ifndef _CLCDDEVICE_H_ +#define _CLCDDEVICE_H_ + +#include "../g15sdk/lglcd.h" + +class CLCDDevice { +private: + int m_iIndex; + +protected: + CLCDDevice(int iIndex) { + m_iIndex = iIndex; + } + +public: + int GetIndex() { + return m_iIndex; + } + + // Returns the display name + virtual tstring GetDisplayName() = NULL; + // Returns the display size + virtual SIZE GetDisplaySize() = NULL; + // Returns the number of buttons for the display + virtual int GetButtonCount() = NULL; + // Returns the number of available colors + virtual int GetColorCount() = NULL; +}; + +class CLgLCDDevice : public CLCDDevice { +private: + SIZE m_size; + int m_iButtons; + int m_iBPP; + +public: + CLgLCDDevice(DWORD type, SIZE size, int buttons, int BPP) : CLCDDevice(type) { + m_size = size; + m_iButtons = buttons; + m_iBPP = BPP; + } + + // Returns the display name + tstring GetDisplayName() { + return m_iBPP == 1? _T("G15") : _T("G19"); + } + + // Returns the display size + SIZE GetDisplaySize() { + return m_size; + } + // Returns the number of buttons for the display + int GetButtonCount() { + return m_iButtons; + } + + // Returns the number of available colors + int GetColorCount() { + return m_iBPP; + } +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDGfx.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDGfx.cpp new file mode 100644 index 0000000000..7240263a79 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDGfx.cpp @@ -0,0 +1,798 @@ +//************************************************************************ +// +// LCDGfx.cpp +// +// The CLCDGfx class abstracts GDI/bitmap details. It is used in the +// OnDraw event. +// +// Logitech LCD SDK +// +// Copyright 2005 Logitech Inc. +//************************************************************************ + +#include "StdAfx.h" +#include "CLCDGfx.h" +#include "math.h" + +#define TRANSITION_DURATION 800 + +//************************************************************************ +// CLCDGfx::CLCDGfx +//************************************************************************ +CLCDGfx::CLCDGfx(void) +{ + m_nWidth = 0; + m_nHeight = 0; + m_pBitmapInfo = NULL; + m_hDC = NULL; + m_hBitmap = NULL; + m_hPrevBitmap = NULL; + m_pBitmapBits = NULL; + m_pLcdBitmapBits = NULL; + m_pSavedBitmapBits = NULL; + m_bInitialized = false; + m_bTransition = false; + + m_dwTransitionStart = 0; + m_dwLastDraw = 0; + m_dWave = 0; +} + +//************************************************************************ +// CLCDGfx::~CLCDGfx +//************************************************************************ +CLCDGfx::~CLCDGfx(void) +{ + Shutdown(); +} + +//************************************************************************ +// CLCDGfx::Initialize +//************************************************************************ +bool CLCDGfx::Initialize(int nWidth, int nHeight, int nBPP, PBYTE pLcdBitmapBits) +{ + m_pLcdBitmapBits = pLcdBitmapBits; + + m_nWidth = nWidth; + m_nHeight = nHeight; + m_nBPP = nBPP; + + m_hDC = CreateCompatibleDC(NULL); + if(NULL == m_hDC) + { + TRACE(_T("CLCDGfx::Initialize(): failed to create compatible DC.\n")); + Shutdown(); + return false; + } + + int nBMISize = sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD); + m_pBitmapInfo = (BITMAPINFO *) new BYTE [nBMISize]; + if(NULL == m_pBitmapInfo) + { + TRACE(_T("CLCDGfx::Initialize(): failed to allocate bitmap info.\n")); + Shutdown(); + return false; + } + + ZeroMemory(m_pBitmapInfo, nBMISize); + m_pBitmapInfo->bmiHeader.biSize = sizeof(m_pBitmapInfo->bmiHeader); + m_pBitmapInfo->bmiHeader.biWidth = m_nWidth; + m_pBitmapInfo->bmiHeader.biHeight = -m_nHeight; + m_pBitmapInfo->bmiHeader.biPlanes = 1; + m_pBitmapInfo->bmiHeader.biBitCount = 8*m_nBPP; + m_pBitmapInfo->bmiHeader.biCompression = BI_RGB; + m_pBitmapInfo->bmiHeader.biSizeImage = m_pBitmapInfo->bmiHeader.biWidth * m_pBitmapInfo->bmiHeader.biHeight * m_nBPP; + m_pBitmapInfo->bmiHeader.biXPelsPerMeter = 3200; + m_pBitmapInfo->bmiHeader.biYPelsPerMeter = 3200; + m_pBitmapInfo->bmiHeader.biClrUsed = 256; + m_pBitmapInfo->bmiHeader.biClrImportant = 256; + + if(m_nBPP == 1) { + for(int nColor = 0; nColor < 256; ++nColor) + { + m_pBitmapInfo->bmiColors[nColor].rgbRed = (BYTE)((nColor > 128) ? 255 : 0); + m_pBitmapInfo->bmiColors[nColor].rgbGreen = (BYTE)((nColor > 128) ? 255 : 0); + m_pBitmapInfo->bmiColors[nColor].rgbBlue = (BYTE)((nColor > 128) ? 255 : 0); + m_pBitmapInfo->bmiColors[nColor].rgbReserved = 0; + } + } + + m_hBitmap = CreateDIBSection(m_hDC, m_pBitmapInfo, DIB_RGB_COLORS, (PVOID *) &m_pBitmapBits, NULL, 0); + if(NULL == m_hBitmap) + { + TRACE(_T("CLCDGfx::Initialize(): failed to create bitmap.\n")); + Shutdown(); + return false; + } + + m_bInitialized = true; + + return true; +} + +//************************************************************************ +// CLCDGfx::IsInitialized +//************************************************************************ +bool CLCDGfx::IsInitialized() +{ + return m_bInitialized; +} + +//************************************************************************ +// CLCDGfx::Shutdown +//************************************************************************ +bool CLCDGfx::Shutdown(void) +{ + EndTransition(); + + if(NULL != m_hBitmap) + { + DeleteObject(m_hBitmap); + m_hBitmap = NULL; + m_pBitmapBits = NULL; + } + + ASSERT(NULL == m_hPrevBitmap); + m_hPrevBitmap = NULL; + + if(NULL != m_pBitmapInfo) + { + delete [] m_pBitmapInfo; + m_pBitmapInfo = NULL; + } + + if(NULL != m_hDC) + { + DeleteDC(m_hDC); + m_hDC = NULL; + } + + m_nWidth = 0; + m_nHeight = 0; + + m_bInitialized = false; + + return true; +} +//************************************************************************ +// CLCDGfx::SetClipRegion +//************************************************************************ +void CLCDGfx::SetClipRegion(int iX,int iY,int iWidth,int iHeight) +{ + ASSERT(NULL != m_hPrevBitmap); + + m_rClipRegion.left = iX; + m_rClipRegion.right = iX+iWidth; + m_rClipRegion.top = iY; + m_rClipRegion.bottom = iY+iHeight; + + HRGN hRgn = CreateRectRgn(iX,iY,iX+iWidth,iY+iHeight); + SelectClipRgn(GetHDC(), hRgn); + DeleteObject(hRgn); +} + +//************************************************************************ +// CLCDGfx::GetClipRegion +//************************************************************************ +RECT CLCDGfx::GetClipRegion() +{ + return m_rClipRegion; +} + +//************************************************************************ +// CLCDGfx::BeginDraw +//************************************************************************ +void CLCDGfx::BeginDraw(void) +{ + ASSERT(NULL != m_hBitmap); + if(m_hPrevBitmap != NULL) + Sleep(1); + ASSERT(NULL == m_hPrevBitmap); + if(NULL == m_hPrevBitmap) + { + m_hPrevBitmap = (HBITMAP) SelectObject(m_hDC, m_hBitmap); + SetTextColor(m_hDC, RGB(255, 255, 255)); + SetBkColor(m_hDC, RGB(0, 0, 0)); + } +} + +//************************************************************************ +// CLCDGfx::ClearScreen +//************************************************************************ +void CLCDGfx::ClearScreen(void) +{ + // this means, we're inside BeginDraw()/EndDraw() + ASSERT(NULL != m_hPrevBitmap); + RECT rc = { 0, 0, m_nWidth, m_nHeight }; + FillRect(m_hDC, &rc, (HBRUSH) GetStockObject(BLACK_BRUSH)); +} + +//************************************************************************ +// CLCDGfx::GetPixel +//************************************************************************ +COLORREF CLCDGfx::GetPixel(int nX, int nY) { + return ::GetPixel(m_hDC,nX,nY); +} + +//************************************************************************ +// CLCDGfx::SetPixel +//************************************************************************ +void CLCDGfx::SetPixel(int nX, int nY, COLORREF color) { + // this means, we're inside BeginDraw()/EndDraw() + ASSERT(NULL != m_hPrevBitmap); + ::SetPixel(m_hDC, nX, nY, color); +} + +void CLCDGfx::SetPixel(int nX, int nY, BYTE r, BYTE g, BYTE b) +{ + COLORREF ref; + if(m_nBPP==1) { + ref = (r || g || b) ? RGB(255, 255, 255) : RGB(0, 0, 0); + } else { + ref = RGB(r,g,b); + } + SetPixel(nX,nY,ref); +} + + +//************************************************************************ +// CLCDGfx::DrawLine +//************************************************************************ +void CLCDGfx::DrawLine(int nX1, int nY1, int nX2, int nY2) +{ + // this means, we're inside BeginDraw()/EndDraw() + ASSERT(NULL != m_hPrevBitmap); + + HPEN hPrevPen = (HPEN) SelectObject(m_hDC, GetStockObject(WHITE_PEN)); + ::MoveToEx(m_hDC, nX1, nY1, NULL); + ::LineTo(m_hDC, nX2, nY2); + SelectObject(m_hDC, hPrevPen); +} + + +//************************************************************************ +// +// CLCDGfx::DrawFilledRect +// +//************************************************************************ +void CLCDGfx::DrawFilledRect(int nX, int nY, int nWidth, int nHeight) +{ + // this means, we're inside BeginDraw()/EndDraw() + ASSERT(NULL != m_hPrevBitmap); + + HBRUSH hPrevBrush = (HBRUSH) SelectObject(m_hDC, GetStockObject(WHITE_BRUSH)); + RECT r = { nX, nY, nX + nWidth, nY + nHeight }; + ::FillRect(m_hDC, &r, hPrevBrush); + SelectObject(m_hDC, hPrevBrush); +} + +//************************************************************************ +// CLCDGfx::DrawFilledRect +//************************************************************************ +void CLCDGfx::DrawRect(int iX, int iY, int iWidth, int iHeight) +{ + // this means, we're inside BeginDraw()/EndDraw() + ASSERT(NULL != m_hPrevBitmap); + + HBRUSH hPrevBrush = (HBRUSH) SelectObject(m_hDC, GetStockObject(WHITE_BRUSH)); + + // top line + DrawLine(iX+1,iY,iX+iWidth-1,iY); + // bottom line + DrawLine(iX+1,iY+iHeight-1,iX+iWidth-1,iY+iHeight-1); + // left line + DrawLine(iX,iY,iX,iY+iHeight); + // right line + DrawLine(iX+iWidth-1,iY,iX+iWidth-1,iY+iHeight); + + SelectObject(m_hDC, hPrevBrush); +} + +//************************************************************************ +// CLCDGfx::DrawText +//************************************************************************ +void CLCDGfx::DrawText(int nX, int nY, LPCTSTR sText) +{ + // map mode text, with transparency + int nOldMapMode = SetMapMode(m_hDC, MM_TEXT); + int nOldBkMode = SetBkMode(m_hDC, TRANSPARENT); + + DRAWTEXTPARAMS dtp; + ZeroMemory(&dtp, sizeof(DRAWTEXTPARAMS)); + dtp.cbSize = sizeof(DRAWTEXTPARAMS); + + RECT rBounds = {nX,nY,GetClipWidth(),GetClipHeight()}; + DrawTextEx(m_hDC,(LPTSTR)sText,lstrlen(sText),&rBounds,(DT_LEFT | DT_NOPREFIX),&dtp); + + // restores + SetMapMode(m_hDC, nOldMapMode); + SetBkMode(m_hDC, nOldBkMode); +} + +//************************************************************************ +// CLCDGfx::DrawText +//************************************************************************ +void CLCDGfx::DrawText(int nX,int nY,int nWidth,tstring strText) +{ + SIZE sizeChar = {0, 0}; + SIZE sizeLine = {0, 0}; + SIZE sizeCutOff = {0, 0}; + + GetTextExtentPoint(GetHDC(),_T("..."),3,&sizeCutOff); + + int *piWidths = new int[strText.length()]; + int iMaxChars = 0; + + GetTextExtentExPoint(GetHDC(),strText.c_str(),strText.length(),nWidth,&iMaxChars,piWidths,&sizeLine); + + if(iMaxChars < strText.length()) + { + for(iMaxChars--;iMaxChars>0;iMaxChars--) + { + if(piWidths[iMaxChars] + sizeCutOff.cx <= nWidth) + break; + } + DrawText(nX,nY,(strText.substr(0,iMaxChars) + _T("...")).c_str()); + } + else + DrawText(nX,nY,strText.c_str()); + free(piWidths); +} + +//************************************************************************ +// CLCDGfx::DrawBitmap +//************************************************************************ +void CLCDGfx::DrawBitmap(int nX, int nY,int nWidth, int nHeight, HBITMAP hBitmap) +{ + HDC hCompatibleDC = CreateCompatibleDC(GetHDC()); + HBITMAP hOldBitmap = (HBITMAP)SelectObject(hCompatibleDC, hBitmap); + + BitBlt(GetHDC(), nX, nY, nWidth, nHeight, hCompatibleDC, 0, 0, SRCCOPY); + + // restores + SelectObject(hCompatibleDC, hOldBitmap); + DeleteDC(hCompatibleDC); +} + +//************************************************************************ +// CLCDGfx::EndDraw +//************************************************************************ +void CLCDGfx::EndDraw(void) +{ + ASSERT(NULL != m_hPrevBitmap); + if(NULL != m_hPrevBitmap) + { + GdiFlush(); + m_hPrevBitmap = (HBITMAP) SelectObject(m_hDC, m_hPrevBitmap); + ASSERT(m_hPrevBitmap == m_hBitmap); + m_hPrevBitmap = NULL; + } + + if(m_nBPP != 1 || !m_bTransition) + memcpy(m_pLcdBitmapBits, m_pBitmapBits, m_nWidth * m_nHeight * m_nBPP); + else + { + if(m_dwTransitionStart == 0) { + Cache(); + } + + PBYTE pScreen1 = m_pSavedBitmapBits; + PBYTE pScreen2 = m_pBitmapBits; + + DWORD dwTimeElapsed = GetTickCount() - m_dwTransitionStart; + + /* if(m_eTransition == TRANSITION_BT || m_eTransition == TRANSITION_TB) + { + int iCols = ((float)dwTimeElapsed/(float)TRANSITION_DURATION)*m_nHeight; + + if(m_eTransition == TRANSITION_TB) + { + iCols = m_nHeight - iCols; + + pScreen1 = m_pBitmapBits; + pScreen2 = m_pSavedBitmapBits; + } + + if(iCols > m_nHeight) + iCols = m_nHeight; + if(iCols < 0) + iCols = 0; + + memcpy(m_pLcdBitmapBits,pScreen1+(iCols*m_nWidth),((m_nHeight-iCols)*m_nWidth)); + memcpy(m_pLcdBitmapBits+((m_nHeight-iCols)*m_nWidth),pScreen2,iCols *m_nWidth); + } + else if(m_eTransition == TRANSITION_LR || m_eTransition == TRANSITION_RL) + { + int iCols = ((float)dwTimeElapsed/(float)TRANSITION_DURATION)*m_nWidth; + + if(m_eTransition == TRANSITION_LR) + { + iCols = m_nWidth - iCols; + + pScreen1 = m_pBitmapBits; + pScreen2 = m_pSavedBitmapBits; + } + + if(iCols > m_nWidth) + iCols = m_nWidth; + if(iCols < 0) + iCols = 0; + + for(int i=0;i m_nHeight) + iCols = m_nHeight; + if(iCols < 2) + iCols = 2; + + memcpy(m_pLcdBitmapBits,pScreen1,m_nHeight*m_nWidth); + for(int i=0;i m_nWidth) + iCols = m_nWidth; + if(iCols < 2) + iCols = 2; + + memcpy(m_pLcdBitmapBits,pScreen1,m_nHeight*m_nWidth); + for(int i=0;i m_nHeight) + iCols = m_nHeight; + if(iCols < 2) + iCols = 2; + + int iCols2 = ((float)dwTimeElapsed/(float)TRANSITION_DURATION)*m_nWidth; + if(iCols2%2 == 1) + iCols2--; + + if(iCols2 > m_nWidth) + iCols2 = m_nWidth; + if(iCols2 < 2) + iCols2 = 2; + + memcpy(m_pLcdBitmapBits,pScreen1,m_nHeight*m_nWidth); + for(int i=0;i::iterator iter = m_LMovingPixels.begin(); + int iPosition = 0; + int iIndex = 0,iMoved = 0; + + double dTest = sin(3.14/2); + + while(iter != m_LMovingPixels.end()) + { + pPixel = *iter; + if(pPixel->Position.x != pPixel->Destination.x ||pPixel->Position.y != pPixel->Destination.y) { + iMoved++; + + dPixelPercent = dPercent * pPixel->dSpeed; + if(dPixelPercent > 1.0f) + dPixelPercent = 1.0f; + + if(pPixel->Start.x < pPixel->Destination.x) + pPixel->Position.x = pPixel->Start.x + dPixelPercent*(pPixel->Destination.x-pPixel->Start.x); + else if(pPixel->Start.x > pPixel->Destination.x) + pPixel->Position.x = pPixel->Start.x - dPixelPercent*(pPixel->Start.x-pPixel->Destination.x); + + if(pPixel->Start.y < pPixel->Destination.y) + pPixel->Position.y = pPixel->Start.y + dPixelPercent*(pPixel->Destination.y-pPixel->Start.y); + else if(pPixel->Start.y > pPixel->Destination.y) + pPixel->Position.y = pPixel->Start.y - dPixelPercent*(pPixel->Start.y-pPixel->Destination.y); + + } + iIndex = pPixel->Position.y*m_nWidth + pPixel->Position.x; + if(iIndex >= 0 && iIndex < m_nHeight * m_nWidth) + m_pLcdBitmapBits[iIndex] = pPixel->cValue; + + iter++; + } + + iter = m_LStaticPixels.begin(); + while(iter != m_LStaticPixels.end()) + { + pPixel = *iter; + + iIndex = pPixel->Position.y*m_nWidth + pPixel->Position.x; + m_pLcdBitmapBits[iIndex] = pPixel->cValue; + iter++; + } + if(iMoved == 0) + EndTransition(); + } + if(m_eTransition != TRANSITION_MORPH && dwTimeElapsed > TRANSITION_DURATION) { + EndTransition(); + } + } + m_dwLastDraw = GetTickCount(); +} + +//************************************************************************ +// CLCDGfx::GetHDC +//************************************************************************ +HDC CLCDGfx::GetHDC(void) +{ + ASSERT(NULL != m_hDC); + return m_hDC; +} + +//************************************************************************ +// CLCDGfx::GetBitmapInfo +//************************************************************************ +BITMAPINFO *CLCDGfx::GetBitmapInfo(void) +{ + ASSERT(NULL != m_pBitmapInfo); + return m_pBitmapInfo; +} + +//************************************************************************ +// CLCDGfx::GetHBITMAP +//************************************************************************ + +HBITMAP CLCDGfx::GetHBITMAP(void) +{ + ASSERT(NULL != m_hBitmap); + return m_hBitmap; +} + +int CLCDGfx::findNearestMatch(PBYTE targetArray,int iSourceIndex) { + int startY = iSourceIndex/m_nWidth; + int startX = iSourceIndex - (iSourceIndex/m_nWidth)*m_nWidth; + + int iIndex; + int iY=0,iX=0; + for(int iPass=1;iPass= m_nHeight || iX <0 || iX >= m_nWidth) + continue; + + iIndex = iY*m_nWidth + iX; + if(targetArray[iIndex] != 0) + return iIndex; + } + for(iX = startX-iPass;iX<=startX+iPass;iX+=iPass*2) + for(iY=startY-iPass;iY= m_nHeight || iX <0 || iX >= m_nWidth) + continue; + + iIndex = iY*m_nWidth + iX; + if(targetArray[iIndex] != 0) + return iIndex; + } + } + return -1; +} + +//************************************************************************ +// CLCDGfx::StartTransition +//************************************************************************ +void CLCDGfx::Cache() +{ + DWORD dwStart = GetTickCount(); + + // Initialize pixels + if(m_eTransition == TRANSITION_MORPH) + { + SLCDPixel *pPixel = NULL; + SLCDPixel *pSource = NULL; + + int iIndex = 0; + bool bBreak = false; + bool bSearch = true; + + int iTransitionPixels = 0; + + POINT pt; + for(int j=0;j<2;j++) + { + iIndex = 0; + for(int i=0;idSpeed = GetRandomDouble()*0.5 + 1; + if(!PtInRect(&m_rTransitionRegion,pt)) { + pPixel->cValue = m_pBitmapBits[i]; + } else { + pPixel->cValue = m_pSavedBitmapBits[i]; + } + pPixel->Start.y = pt.y; + pPixel->Start.x = pt.x; + pPixel->Position = pPixel->Start; + + bBreak = false; + if(j==1 && bSearch) + { + // search for a pixel in circles with increasing radius around the location + iIndex = findNearestMatch(m_pBitmapBits,i); + if(iIndex < 0) { + iIndex = i; + } else { + bBreak = true; + } + } + + if(j==0 || bBreak) + { + pPixel->Destination.y = iIndex/m_nWidth; + pPixel->Destination.x = iIndex - (iIndex/m_nWidth)*m_nWidth; + m_pBitmapBits[iIndex] = 0; + m_pSavedBitmapBits[i] = 0; + + if(bBreak) + iTransitionPixels++; + } + else + { + if(m_LMovingPixels.size() > 0 && iTransitionPixels > 0) + { + pSource = m_LMovingPixels[GetRandomInt(0,m_LMovingPixels.size()-1)]; + pPixel->Destination = pSource->Destination; + } + else + { + pPixel->Destination.x = GetRandomInt(0,m_nWidth-1); + pPixel->Destination.y = GetRandomInt(0,1)==1?-1:m_nHeight+1; + } + bSearch = false; + } + + if(j == 0) + m_LStaticPixels.push_back(pPixel); + else { + m_LMovingPixels.push_back(pPixel); + } + } + } + } + bool bRandom = false; + if(m_LMovingPixels.size() <= 0) + bRandom = true; + + for(iIndex=0;iIndexdSpeed = GetRandomDouble()*0.5 + 1; + pPixel->cValue = m_pBitmapBits[iIndex]; + + if(!bRandom) + { + pSource = m_LMovingPixels[GetRandomInt(0,m_LMovingPixels.size()-1)]; + pPixel->Start = pSource->Start; + } + else + { + pPixel->Start.x = GetRandomInt(0,m_nWidth-1); + pPixel->Start.y = GetRandomInt(0,1)==1?-1:m_nHeight+1; + } + + pPixel->Position = pPixel->Start; + + pPixel->Destination.y = iIndex/m_nWidth; + pPixel->Destination.x = iIndex - (iIndex/m_nWidth)*m_nWidth; + m_LMovingPixels.push_back(pPixel); + } + + } + + + m_dwTransitionStart = GetTickCount(); + TRACE(_T("Textmorphing: time consumed: %0.2f\n"),(double)(m_dwTransitionStart-dwStart)/(double)1000); +} + +//************************************************************************ +// CLCDGfx::StartTransition +//************************************************************************ +void CLCDGfx::StartTransition(ETransitionType eType,LPRECT rect) +{ + if(!m_bInitialized) + return; + + if(rect != NULL) { + m_rTransitionRegion.left = rect->left; + m_rTransitionRegion.right = rect->right; + m_rTransitionRegion.top = rect->top; + m_rTransitionRegion.bottom = rect->bottom; + } else { + SetRect(&m_rTransitionRegion,0,0,m_nWidth,m_nHeight); + } + + if(eType == TRANSITION_RANDOM) + m_eTransition = static_cast(GetRandomInt(0,2)); + else + m_eTransition = eType; + + if(m_bTransition) { + EndTransition(); + memcpy(m_pBitmapBits,m_pLcdBitmapBits,sizeof(BYTE)*m_nWidth*m_nHeight*m_nBPP); + } + + if(m_pSavedBitmapBits == NULL) + m_pSavedBitmapBits = (BYTE*)malloc(sizeof(BYTE)*m_nWidth*m_nHeight*m_nBPP); + + memcpy(m_pSavedBitmapBits, m_pBitmapBits,sizeof(BYTE)* m_nWidth * m_nHeight * m_nBPP); + + m_dwTransitionStart = 0; + + m_bTransition = true; +} + +void CLCDGfx::EndTransition() +{ + if(m_pSavedBitmapBits != NULL) + free(m_pSavedBitmapBits); + + m_pSavedBitmapBits = NULL; + + if(!m_LMovingPixels.empty()) + { + vector::iterator iter = m_LMovingPixels.begin(); + while(iter != m_LMovingPixels.end()) + { + delete *iter; + iter++; + } + m_LMovingPixels.clear(); + + iter = m_LStaticPixels.begin(); + while(iter != m_LStaticPixels.end()) + { + delete *iter; + iter++; + } + m_LStaticPixels.clear(); + } + + m_bTransition = false; +} \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDGfx.h b/plugins/MirandaG15/LCDFramework/src/CLCDGfx.h new file mode 100644 index 0000000000..bdca950718 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDGfx.h @@ -0,0 +1,82 @@ +#ifndef _CLCDGfx_H_ +#define _CLCDGfx_H_ + +enum ETransitionType {TRANSITION_FADE,TRANSITION_VLINES,TRANSITION_HLINES,TRANSITION_MORPH,TRANSITION_RANDOM}; + +struct SLCDPixel +{ + COLORREF cValue; + double dSpeed; + POINT Start; + POINT Destination; + POINT Position; +}; + +class CLCDGfx +{ +public: + CLCDGfx(void); + virtual ~CLCDGfx(void); + + bool Initialize(int nWidth, int nHeight, int nBPP, PBYTE pBitmapBits); + bool IsInitialized(); + bool Shutdown(void); + + void BeginDraw(void); + void ClearScreen(void); + COLORREF GetPixel(int nX, int nY); + void SetPixel(int nX, int nY, COLORREF color); + void SetPixel(int nX, int nY, BYTE r, BYTE g, BYTE b); + void DrawLine(int nX1, int nY1, int nX2, int nY2); + void DrawFilledRect(int nX, int nY, int nWidth, int nHeight); + void DrawRect(int iX, int iY, int iWidth, int iHeight); + void DrawText(int nX, int nY, LPCTSTR sText); + void DrawText(int nX,int nY,int iWidth,tstring strText); + void DrawBitmap(int nX,int nY,int nWidth, int nHeight,HBITMAP hBitmap); + void EndDraw(void); + + + void SetClipRegion(int iX,int iY,int iWidth,int iHeight); + RECT GetClipRegion(); + + inline int GetClipWidth() { return m_rClipRegion.right-m_rClipRegion.left; }; + inline int GetClipHeight() { return m_rClipRegion.bottom-m_rClipRegion.top; }; + + HDC GetHDC(void); + BITMAPINFO *GetBitmapInfo(void); + HBITMAP GetHBITMAP(void); + + void StartTransition(ETransitionType eType = TRANSITION_RANDOM,LPRECT rect = NULL); + +protected: + void Cache(); + int findNearestMatch(PBYTE targetArray,int iSourceIndex); + + void EndTransition(); + + RECT m_rClipRegion; + RECT m_rTransitionRegion; + + int m_nWidth; + int m_nHeight; + int m_nBPP; + BITMAPINFO *m_pBitmapInfo; + HDC m_hDC; + HBITMAP m_hBitmap; + HBITMAP m_hPrevBitmap; + PBYTE m_pBitmapBits,m_pLcdBitmapBits,m_pSavedBitmapBits; + + bool m_bInitialized; + + DWORD m_dwTransitionStart; + bool m_bTransition; + + ETransitionType m_eTransition; + vector m_LMovingPixels; + vector m_LStaticPixels; + + double m_dWave; + DWORD m_dwLastDraw; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDInput.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDInput.cpp new file mode 100644 index 0000000000..ab5350ec86 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDInput.cpp @@ -0,0 +1,857 @@ +#include "stdafx.h" +#include "CLCDInput.h" +#include "CLCDOutputManager.h" + +//************************************************************************ +// CLCDInput::CLCDInput +//************************************************************************ +CLCDInput::CLCDInput() +{ + m_lInputTime = 0; + m_iLinePosition = 0; + ZeroMemory(&m_Marker,2*sizeof(SMarker)); + + m_pScrollbar = NULL; + m_bShowSymbols = true; + m_iBreakKeys = KEYS_RETURN; + m_bShowMarker = false; + m_lBlinkTimer = 0; + + m_iLineCount = 0; +// SetScrollbarAlignment(TOP); + Reset(); +} + + +//************************************************************************ +// CLCDInput::~CLCDInput +//************************************************************************ +CLCDInput::~CLCDInput() +{ + m_vLineOffsets.clear(); +} + +//************************************************************************ +// CLCDInput::Initialize +//************************************************************************ +bool CLCDInput::Initialize() +{ + if(!CLCDTextObject::Initialize()) + return false; + +// m_pParent = pParent; + return true; +} + +//************************************************************************ +// CLCDInput::Shutdown +//************************************************************************ +bool CLCDInput::Shutdown() +{ + if(!CLCDTextObject::Shutdown()) + return false; + + + return true; +} +//************************************************************************ +// CLCDInput::Update +//************************************************************************ +void CLCDInput::SetScrollbar(CLCDBar *pScrollbar) +{ + m_pScrollbar = pScrollbar; + if(m_pScrollbar) + { + m_pScrollbar->SetSliderSize(m_iLineCount); + m_pScrollbar->SetRange(0,m_vLineOffsets.size()); + m_pScrollbar->ScrollTo(m_iLinePosition); + } +} + +//************************************************************************ +// CLCDInput::GetLastInputTime +//************************************************************************ +long CLCDInput::GetLastInputTime() +{ + return m_lInputTime; +} + +//************************************************************************ +// CLCDInput::Update +//************************************************************************ +bool CLCDInput::Update() +{ + if(!CLCDTextObject::Update()) + return false; + + if(m_lBlinkTimer + 500 <= GetTickCount()) + { + m_bShowMarker = !m_bShowMarker; + m_lBlinkTimer = GetTickCount(); + } + + return true; +} + +//************************************************************************ +// CLCDInput::Draw +//************************************************************************ +bool CLCDInput::Draw(CLCDGfx *pGfx) +{ + if(!CLCDTextObject::Draw(pGfx)) + return false; + + + SelectObject(pGfx->GetHDC(),m_hFont); + + RECT rBoundary = { 0, 0,0 + GetWidth(), 0 + GetHeight() }; + int iLine = m_iLinePosition; + int iEndLine = m_iLinePosition + m_iLineCount; + int iLen = 0; + TCHAR *pcOffset = NULL; + while(iLine < iEndLine && iLine < m_vLineOffsets.size()) + { + // Calculate the text length + if(iLine < m_vLineOffsets.size() -1) + { + iLen = m_vLineOffsets[iLine+1].iOffset - m_vLineOffsets[iLine].iOffset; + // Draw the linebreak marker + if(m_bShowSymbols && m_vLineOffsets[iLine+1].bLineBreak) + pGfx->DrawFilledRect(m_vLineOffsets[iLine].iWidth+1,rBoundary.top+m_iFontHeight/3,m_iFontHeight/3,m_iFontHeight/3); + } + else + iLen = m_strText.length() - m_vLineOffsets[iLine].iOffset; + + // Draw the text + pcOffset = (TCHAR*)m_strText.c_str() + m_vLineOffsets[iLine].iOffset; + DrawTextEx(pGfx->GetHDC(), + (LPTSTR)pcOffset, + iLen, + &rBoundary, + m_iTextFormat, + &m_dtp); + + // Draw the input cursor + if(m_pInput && m_bShowMarker && m_Marker[0].iLine == iLine) + { + // insert-mode cursor + if(m_bInsert ||m_Marker[0].iXWidth == 1) + { + pGfx->DrawFilledRect(m_Marker[0].iXLine, + m_iFontHeight*(iLine-m_iLinePosition), + 1, + m_iFontHeight); + } + // replace-mode cursor + else + { + RECT rMarker = {m_Marker[0].iXLine, + m_iFontHeight*(iLine-m_iLinePosition), + m_Marker[0].iXLine+m_Marker[0].iXWidth, + m_iFontHeight*(iLine-m_iLinePosition+1)}; + InvertRect(pGfx->GetHDC(),&rMarker); + } + } + + rBoundary.top += m_iFontHeight; + rBoundary.bottom += m_iFontHeight; + + iLine++; + } + return true; +} + +//************************************************************************ +// CLCDInput::ShowSymbols +//************************************************************************ +void CLCDInput::ShowSymbols(bool bShow) +{ + m_bShowSymbols = bShow; +} + +//************************************************************************ +// CLCDInput::SetBreakKeys +//************************************************************************ +void CLCDInput::SetBreakKeys(int iKeys) +{ + m_iBreakKeys = iKeys; +} + +//************************************************************************ +// returns wether the input is currently active +//************************************************************************ +bool CLCDInput::IsInputActive() +{ + return m_pInput != NULL; +} + + +//************************************************************************ +// CLCDInput::OnSizeChanged +//************************************************************************ +void CLCDInput::OnSizeChanged(SIZE OldSize) +{ + // if the width has changed, offsets need to be recalculated + if(GetWidth() != OldSize.cx) + OnFontChanged(); + // otherwise, just update scrollbar & linecount + else if(m_pScrollbar) + { + m_iLineCount = GetHeight() / m_iFontHeight; + m_pScrollbar->SetSliderSize(m_iLineCount); + } +} + +//************************************************************************ +// CLCDInput::OnFontChanged +//************************************************************************ +void CLCDInput::OnFontChanged() +{ + if(m_iFontHeight == 0) + return; + + if(m_pScrollbar) + m_pScrollbar->SetSliderSize(m_iLineCount); + + m_iLinePosition = 0; + m_iLineCount = GetHeight() / m_iFontHeight; + + if(m_pScrollbar) + m_pScrollbar->SetSliderSize(m_iLineCount); + + m_Marker[0].iLine = 0; + m_Marker[0].iPosition = 0; + m_Marker[0].iPosition = m_strText.length(); + + // Delete all offsets and recalculate them + m_vLineOffsets.clear(); + // Create a new offset + SLineEntry offset; + offset.bLineBreak = false; + offset.iOffset = 0; + m_vLineOffsets.push_back(offset); + + UpdateOffsets(0); + + UpdateMarker(); + if(m_iLineCount > 0) + ScrollToMarker(); +} + +//************************************************************************ +// CLCDInput::ActivateInput +//************************************************************************ +void CLCDInput::ActivateInput() +{ + if(m_pInput) + return; + + CLCDConnection *pLCDCon = CLCDOutputManager::GetInstance()->GetLCDConnection(); + pLCDCon->SetAsForeground(1); + + m_hKBHook = SetWindowsHookEx(WH_KEYBOARD_LL, CLCDInput::KeyboardHook, GetModuleHandle(NULL), 0); + if(!m_hKBHook) + return; + m_pInput = this; + GetKeyboardState(m_acKeyboardState); +} + +//************************************************************************ +// CLCDInput::DeactivateInput +//************************************************************************ +void CLCDInput::DeactivateInput() +{ + if(!m_pInput) + return; + UnhookWindowsHookEx(m_hKBHook); + m_hKBHook = NULL; + + m_pInput = NULL; + + CLCDConnection *pLCDCon = CLCDOutputManager::GetInstance()->GetLCDConnection(); + pLCDCon->SetAsForeground(0); +} + +//************************************************************************ +// CLCDInput::KeyboardHook +//************************************************************************ +CLCDInput* CLCDInput::m_pInput = NULL; + +LRESULT CALLBACK CLCDInput::KeyboardHook(int Code, WPARAM wParam, LPARAM lParam) +{ + return m_pInput->ProcessKeyEvent(Code,wParam,lParam); +} + +//************************************************************************ +// CLCDInput::ProcessKeyEvent +//************************************************************************ +LRESULT CLCDInput::ProcessKeyEvent(int Code, WPARAM wParam, LPARAM lParam) +{ + // Event verarbeiten + if(Code == HC_ACTION) + { + KBDLLHOOKSTRUCT *key = (KBDLLHOOKSTRUCT *)(lParam); + + bool bKeyDown = !(key->flags & LLKHF_UP); + bool bToggled = (m_acKeyboardState[key->vkCode] & 0x0F); + if(bKeyDown) + bToggled = !bToggled; + m_acKeyboardState[key->vkCode] = (bKeyDown?0x80:0x00) | (bToggled?0x01:0x00); + if(key->vkCode == VK_LSHIFT || key->vkCode == VK_RSHIFT) + m_acKeyboardState[VK_SHIFT] = m_acKeyboardState[key->vkCode]; + else if(key->vkCode == VK_LCONTROL || key->vkCode == VK_RCONTROL) + m_acKeyboardState[VK_CONTROL] = m_acKeyboardState[key->vkCode]; + else if(key->vkCode == VK_LMENU || key->vkCode == VK_RMENU) + m_acKeyboardState[VK_MENU] = m_acKeyboardState[key->vkCode]; + + /* + if(bKeyDown) + TRACE(_T("Key pressed: %i\n"),key->vkCode); + else + TRACE(_T("Key released: %i\n"),key->vkCode); + */ + // Only handle Keyup + if(bKeyDown) + { + // Actions with Control/Menu keys + if((m_acKeyboardState[VK_LMENU] & 0x80 || m_acKeyboardState[VK_CONTROL] & 0x80) + && m_acKeyboardState[VK_SHIFT] & 0x80) + { + ActivateKeyboardLayout((HKL)HKL_NEXT,0);//KLF_SETFORPROCESS); + TRACE(_T("Keyboardlayout switched!\n")); + return 1; + } + + int res = 0,size = 0,dir = MARKER_HORIZONTAL,scroll = 0; +/* + if(key->vkCode == VK_DELETE) { + dir = MARKER_HOLD; + res = -1; + if(m_strText[m_Marker[0].iPosition] == '\r') + res = -2; + if(m_strText.length() >= m_Marker[0].iPosition + -res) { + m_strText.erase(m_Marker[0].iPosition,-res); + scroll = 1; + size = 1; + } else { + res = 0; + } + } + else */if(key->vkCode == VK_BACK ) + { + if(m_Marker[0].iPosition != 0) + { + res = -1; + if(m_strText[m_Marker[0].iPosition+res] == '\n') + res = -2; + + m_strText.erase(m_Marker[0].iPosition+res,-res); + scroll = 1; + size = res; + } + } + // Marker navigation + else if (key->vkCode == VK_INSERT) + { + m_bInsert = !m_bInsert; + } + else if(key->vkCode == VK_HOME) + { + res = m_vLineOffsets[m_Marker[0].iLine].iOffset - m_Marker[0].iPosition; + scroll = 1; + } + else if(key->vkCode == VK_END) + { + if(m_vLineOffsets.size()-1 == m_Marker[0].iLine) + res = m_strText.length() - m_Marker[0].iPosition; + else + { + res = (m_vLineOffsets[m_Marker[0].iLine+1].iOffset - 1 - m_vLineOffsets[m_Marker[0].iLine+1].bLineBreak) -m_Marker[0].iPosition; + } + scroll = 1; + } + else if(key->vkCode == VK_UP) + { + res = -1; + dir = MARKER_VERTICAL; + } + else if(key->vkCode == VK_DOWN) + { + res = 1; + dir = MARKER_VERTICAL; + } + else if(key->vkCode == VK_LEFT) + res = -1; + else if(key->vkCode == VK_RIGHT) + res = 1; + + else + { + +#ifdef _UNICODE + TCHAR output[4]; +#else + unsigned char output[2]; +#endif + + if(key->vkCode == VK_RETURN) + { + bool bCtrlDown = (bool)(m_acKeyboardState[VK_CONTROL] & 0x80); + if( bCtrlDown != (m_iBreakKeys == KEYS_RETURN)) + { + DeactivateInput(); + //m_pParent->OnInputFinished(); + return 1; + } + else + { + res = 2; + output[0] = '\r'; + output[1] = '\n'; + output[2] = 0; + } + } + else + { +#ifdef _UNICODE + res = ToUnicode(key->vkCode,key->scanCode,m_acKeyboardState,output,4,0); +#else + res = ToAscii( key->vkCode,key->scanCode,m_acKeyboardState,(WORD*)output,0); +#endif + } + + if(res <= 0) + res = 0; + else + { + if(output[0] != '\r' && output[0] <= 0x001F) + return 1; + + if(m_bInsert || m_strText[m_Marker[0].iPosition] == '\r') + m_strText.insert(m_Marker[0].iPosition,(TCHAR*)output,res); + else + m_strText.replace(m_Marker[0].iPosition,res,(TCHAR*)output); + + scroll = 1; + size = res; + } + } + if(res != 0) + { + if(dir != MARKER_HOLD) { + MoveMarker(dir,res); + } + UpdateOffsets(size); + UpdateMarker(); + ScrollToMarker(); + m_lInputTime = GetTickCount(); + } + //WrapLine(); + // ---- + + + + // Block this KeyEvent + } + return 1; + } + return CallNextHookEx(m_hKBHook, Code, wParam, lParam); +} + +//************************************************************************ +// CLCDInput::MoveMarker +//************************************************************************ +void CLCDInput::MoveMarker(int iDir,int iMove,bool bShift) +{ + // Just cursor + if(!bShift) + { + m_lBlinkTimer = GetTickCount(); + m_bShowMarker = true; + + if(iDir == MARKER_HORIZONTAL) + { + m_Marker[0].iPosition += iMove; + + } + if(iDir == MARKER_VERTICAL) + { + if(iMove < 0 && m_Marker[0].iLine == 0) + return; + if(iMove > 0 && m_Marker[0].iLine == m_vLineOffsets.size()-1) + return; + + m_Marker[0].iLine += iMove; + + int iX = 0,iX2 = 0; + + SIZE sizeChar = {0,0}; + int iBegin = m_vLineOffsets[m_Marker[0].iLine].iOffset; + int iLen = 0; + if(m_Marker[0].iLine < m_vLineOffsets.size() -1) + iLen = m_vLineOffsets[m_Marker[0].iLine+1].iOffset - m_vLineOffsets[m_Marker[0].iLine].iOffset; + else + iLen = m_strText.length() - m_vLineOffsets[m_Marker[0].iLine].iOffset; + + HDC hDC = CreateCompatibleDC(NULL); + if(NULL == hDC) + return; + SelectObject(hDC, m_hFont); + m_Marker[0].iXWidth = 1; + m_Marker[0].iPosition = -1; + + int *piWidths = new int[iLen]; + int iMaxChars; + int iChar=iBegin; + + GetTextExtentExPoint(hDC,m_strText.c_str() + iBegin,iLen,GetWidth(),&iMaxChars,piWidths,&sizeChar); + for(;iChar= 0 && + iChar >= m_Marker[0].iPosition) + { + m_Marker[0].iXWidth = sizeChar.cx; + break; + } + + if(iX >= m_Marker[0].iXLine || (iChar < iBegin+iLen -1 && m_strText[iChar+1] == 10)) + { + if( m_Marker[0].iXLine - iX2 <= iX - m_Marker[0].iXLine) + { + m_Marker[0].iPosition = iChar; + m_Marker[0].iXLine = iX2; + m_Marker[0].iXWidth = sizeChar.cx; + break; + } + else + { + m_Marker[0].iPosition = iChar+1; + m_Marker[0].iXLine = iX; + } + } + } + + free(piWidths); + + if(m_Marker[0].iPosition == -1) + { + m_Marker[0].iPosition = iChar; + m_Marker[0].iXLine = iX; + } + DeleteObject(hDC); + } + + for(int i=0;i<2;i++) + { + if(m_Marker[i].iPosition < 0) + m_Marker[i].iPosition = 0; + else if(m_Marker[i].iPosition > m_strText.length() ) + m_Marker[i].iPosition = m_strText.length(); + } + if(m_Marker[0].iPosition > 0 && m_strText[m_Marker[0].iPosition-1] == '\r') + m_Marker[0].iPosition+= (iDir == MARKER_HORIZONTAL && iMove>0)?1:-1; + + } +} + +//************************************************************************ +// CLCDInput::GetText +//************************************************************************ +tstring CLCDInput::GetText() +{ + return m_strText; +} + +//************************************************************************ +// CLCDInput::Reset +//************************************************************************ +void CLCDInput::Reset() +{ + m_lInputTime = 0; + m_bInsert = true; + + ZeroMemory(&m_Marker[0],sizeof(SMarker)); + + m_strText = _T(""); + m_vLineOffsets.clear(); + m_iLinePosition = 0; + SLineEntry offset; + offset.bLineBreak = false; + offset.iOffset = 0; + m_vLineOffsets.push_back(offset); + + if(m_pScrollbar) + { + m_pScrollbar->ScrollTo(0); + m_pScrollbar->SetRange(0,0); + m_pScrollbar->SetSliderSize(m_iLineCount); + } +} + +//************************************************************************ +// CLCDInput::UpdateOffsets +//************************************************************************ +void CLCDInput::UpdateOffsets(int iModified) +{ + if(m_vLineOffsets.size() == 0 && m_strText.empty()) + return; + + // Reset the marker + m_Marker[0].iXLine = 0; + m_Marker[0].iXWidth = 1; + + // Initialize variables + int iLen = m_strText.length(); + int *piWidths = new int[iLen]; + TCHAR *pszText = (TCHAR*)m_strText.c_str(); + tstring::size_type pos = 0; + int iMaxChars = 0; + + SIZE sizeWord = {0, 0}; + SIZE sizeChar = {0, 0}; + SIZE sizeLine = {0, 0}; + HDC hDC = CreateCompatibleDC(NULL); + if(NULL == hDC) + return; + SelectObject(hDC, m_hFont); + + int iLine = -1; + // Find the first line to update + for(int i=m_vLineOffsets.size()-1;i>=0;i--) + if(m_vLineOffsets[i].iOffset <= m_Marker[0].iPosition) + { + iLine = i; + break; + } + + if(iModified < 0 && iLine-1 >= 0) + iLine--; + + bool bLineClosed = false; + + // TRACE(_T("InputText: Begin Update at #%i\n"),iLine); + for(;iLine iLen) + { + // TRACE(_T("InputText: Deleted offset #%i\n"),iLine); + m_vLineOffsets.erase(m_vLineOffsets.begin()+iLine); + continue; + } + + sizeLine.cx = 0; + sizeWord.cx = 0; + iWordOffset = iChar+1; + + while(iChar= iChar && pos <= iChar + iMaxChars) + { + iWordOffset = pos + 1; + iMaxChars = pos - iChar; + } + // if the string doesnt fit, try to wrap the last word to the next line + else + { + // find the last space in the line + pos = m_strText.rfind(_T(" "),iChar + iMaxChars); + if(pos != tstring::npos && pos >= iChar) + iWordOffset = pos +1; + else + iWordOffset = iChar+iMaxChars; + } + + if(m_Marker[0].iPosition >= iChar && m_Marker[0].iPosition <= iChar + iMaxChars) + { + if(m_Marker[0].iPosition > iChar) + { + m_Marker[0].iXLine = piWidths[m_Marker[0].iPosition -1 - iChar]; + if(m_strText[m_Marker[0].iPosition -1] == '\n' ) + m_Marker[0].iXLine = 0; + } + if(m_Marker[0].iPosition < iChar + iMaxChars) + { + if(m_strText[m_Marker[0].iPosition] > 0x001F) + m_Marker[0].iXWidth = piWidths[m_Marker[0].iPosition - iChar]-m_Marker[0].iXLine; + } + } + + iChar += iMaxChars; + + if(m_strText[iChar] == '\n' || sizeLine.cx > GetWidth()) + { + + bLineClosed = true; + + int iDistance = INFINITE; + + + // Check if a matching offset already exists + for(int iLine2 = iLine+1;iLine2 0) + { + if(m_strText[iChar] == '\n' && iMaxChars >= 2) + m_vLineOffsets[iLine].iWidth = piWidths[iMaxChars-2]; + else + m_vLineOffsets[iLine].iWidth = piWidths[iMaxChars-1]; + } + else + m_vLineOffsets[iLine].iWidth = 0; + + // TRACE(_T("InputText: shifted offsets #%i to end %i position(s)\n"),iLine+1,iDistance); + for(iLine++;iLine 0) + { + if(m_strText[iChar] == '\n' && iMaxChars >= 2) + m_vLineOffsets[iLine].iWidth = piWidths[iMaxChars-2]; + else + m_vLineOffsets[iLine].iWidth = piWidths[iMaxChars-1]; + } + else + m_vLineOffsets[iLine].iWidth = 0; + + if(iLine != m_vLineOffsets.size() - 1 && !bLineClosed) + { + // TRACE(_T("InputText: Deleted offsets #%i to #%i\n"),iLine+1,m_vLineOffsets.size()-1); + m_vLineOffsets.erase(m_vLineOffsets.begin()+iLine+1,m_vLineOffsets.end()); + } + + } + +finished: + free(piWidths); + DeleteObject(hDC); + + if(m_pScrollbar) + m_pScrollbar->SetRange(0,m_vLineOffsets.size()-1); +} + +//************************************************************************ +// CLCDInput::UpdateMarker +//************************************************************************ +void CLCDInput::UpdateMarker() +{ + // Adjust the markers propertys + for(int i=m_vLineOffsets.size()-1;i>= 0;i--) + if(m_Marker[0].iPosition >= m_vLineOffsets[i].iOffset) + { + if(m_Marker[0].iPosition == m_vLineOffsets[i].iOffset) + m_Marker[0].iXLine = 0; + m_Marker[0].iLine = i; + break; + } +} + +//************************************************************************ +// CLCDInput::ScrollLine +//************************************************************************ +bool CLCDInput::ScrollLine(bool bDown) +{ + if(bDown && m_iLinePosition + (m_iLineCount-1) < m_vLineOffsets.size() -1) + m_iLinePosition++; + else if(!bDown && m_iLinePosition > 0) + m_iLinePosition--; + else + return false; + + if(m_pScrollbar) + m_pScrollbar->ScrollTo(m_iLinePosition); + return true; +} + + +//************************************************************************ +// CLCDInput::ScrollToMarker +//************************************************************************ +void CLCDInput::ScrollToMarker() +{ + if(m_Marker[0].iLine < m_iLinePosition) + m_iLinePosition = m_Marker[0].iLine; + if(m_Marker[0].iLine > m_iLinePosition + (m_iLineCount-1)) + { + ScrollLine(); + if(m_Marker[0].iLine > m_iLinePosition + (m_iLineCount-1)) + m_iLinePosition = (m_Marker[0].iLine / m_iLineCount )*m_iLineCount; + } + + if(m_iLinePosition > m_vLineOffsets.size()-1) + m_iLinePosition = m_vLineOffsets.size() -1; + if(m_iLinePosition < 0) + m_iLinePosition = 0; + + if(m_pScrollbar) + m_pScrollbar->ScrollTo(m_iLinePosition); +} + +//************************************************************************ +// CLCDInput::GetLineCount +//************************************************************************ +int CLCDInput::GetLineCount() +{ + return m_vLineOffsets.size(); +} + +//************************************************************************ +// CLCDInput::GetLine +//************************************************************************ +int CLCDInput::GetLine() +{ + return m_iLinePosition; +} \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDInput.h b/plugins/MirandaG15/LCDFramework/src/CLCDInput.h new file mode 100644 index 0000000000..ccf9def536 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDInput.h @@ -0,0 +1,108 @@ +#ifndef _LCDINPUTTEXT_H_INCLUDED_ +#define _LCDINPUTTEXT_H_INCLUDED_ + +#define MARKER_HOLD 0 +#define MARKER_HORIZONTAL 1 +#define MARKER_VERTICAL 2 + +#define KEYS_RETURN 0 +#define KEYS_CTRL_RETURN 1 + +#include "CLCDTextObject.h" +#include "CLCDBar.h" + +struct SMarker +{ + int iPosition; + int iXLine; + int iXWidth; + int iLine; +}; + +struct SLineEntry +{ + int iOffset; + int iWidth; + bool bLineBreak; +}; + +class CLineEntry +{ +public: + tstring strLine; + vector vWrapLineOffsets; +}; + +class CLCDInput : public CLCDTextObject +{ +public: + CLCDInput(); + ~CLCDInput(); + + bool Initialize(); + bool Shutdown(); + + bool Draw(CLCDGfx *pGfx); + bool Update(); + + void ShowSymbols(bool bShow); + void SetBreakKeys(int iKeys); + void SetScrollbar(CLCDBar *pScrollbar); + + void ActivateInput(); + void DeactivateInput(); + bool IsInputActive(); + + tstring GetText(); + void Reset(); + + static LRESULT CALLBACK KeyboardHook(int Code, WPARAM wParam, LPARAM lParam); + + int GetLineCount(); + int GetLine(); + + bool ScrollLine(bool bDown=true); + void ScrollToMarker(); + long GetLastInputTime(); + +protected: + void OnFontChanged(); + void OnSizeChanged(SIZE OldSize); + + LRESULT ProcessKeyEvent(int Code, WPARAM wParam, LPARAM lParam); + + void UpdateOffsets(int iModified); + + void UpdateMarker(); + void MoveMarker(int iDir,int iMove,bool bShift=false); +protected: + bool m_bShowSymbols; + bool m_iBreakKeys; + + int m_iLineCount; + long m_lInputTime; + bool m_bInsert; + + long m_lBlinkTimer; + bool m_bShowMarker; + + int m_iLinePosition; + SMarker m_Marker[2]; + + // Text variables + tstring m_strText; + vector m_vLineOffsets; + + // Input variables + static CLCDInput* m_pInput; + HHOOK m_hKBHook; + BYTE m_acKeyboardState[256]; + + // Scrollbar + CLCDBar *m_pScrollbar; +}; + + +#endif // !_LCDTEXT_H_INCLUDED_ + +//** end of LCDText.h **************************************************** diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDLabel.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDLabel.cpp new file mode 100644 index 0000000000..6451f76665 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDLabel.cpp @@ -0,0 +1,228 @@ +#include "stdafx.h" +#include "CLCDGfx.h" +#include "CLCDObject.h" +#include "CLCDTextObject.h" +#include "CLCDLabel.h" +#include "math.h" + +//************************************************************************ +// constructor +//************************************************************************ +CLCDLabel::CLCDLabel() +{ + m_strText = _T(""); + m_bCutOff = true; +} + +//************************************************************************ +// destructor +//************************************************************************ +CLCDLabel::~CLCDLabel() +{ +} + +//************************************************************************ +// initializes the label +//************************************************************************ +bool CLCDLabel::Initialize() +{ + if(!CLCDTextObject::Initialize()) + return false; + + return true; +} + +//************************************************************************ +// deinitializes the label +//************************************************************************ +bool CLCDLabel::Shutdown() +{ + if(!CLCDTextObject::Shutdown()) + return false; + + return true; +} + +//************************************************************************ +// updates the label +//************************************************************************ +bool CLCDLabel::Update() +{ + if(!CLCDTextObject::Update()) + return false; + + return true; +} + +//************************************************************************ +// draws the label +//************************************************************************ +bool CLCDLabel::Draw(CLCDGfx *pGfx) +{ + if(!CLCDTextObject::Draw(pGfx)) + return false; + + SelectObject(pGfx->GetHDC(),m_hFont); + + int iTop = (int)(GetHeight()-(m_vLines.size()*m_iFontHeight))/2;///2;//()/2; + RECT rBoundary = {0,iTop,GetWidth(), GetHeight()-iTop}; + + vector::iterator iter = m_vLines.begin(); + while(!m_vLines.empty() && iter != m_vLines.end()) + { + DrawTextEx(pGfx->GetHDC(), (LPTSTR)(*iter).c_str(), (*iter).length(), &rBoundary, m_iTextFormat, &m_dtp); + rBoundary.top += m_iFontHeight; + iter++; + } + return true; +} + +//************************************************************************ +// sets the label's text +//************************************************************************ +void CLCDLabel::SetText(tstring strText) +{ + m_strText = strText; + + UpdateCutOffIndex(); +} + +//************************************************************************ +// called when the labels font has changed +//************************************************************************ +void CLCDLabel::OnFontChanged() +{ + UpdateCutOffIndex(); +} + +//************************************************************************ +// called when the labels size has changed +//************************************************************************ +void CLCDLabel::OnSizeChanged(SIZE OldSize) +{ + if(GetWidth() == OldSize.cx && GetHeight() == OldSize.cy) + return; + UpdateCutOffIndex(); +} + +//************************************************************************ +// sets the wordwrap mode +//************************************************************************ +void CLCDLabel::SetWordWrap(bool bEnable) +{ + m_bWordWrap = bEnable; +} + +//************************************************************************ +// updates the cutoff index +//************************************************************************ +void CLCDLabel::UpdateCutOffIndex() +{ + int iLen = m_strText.length(); + + m_vLines.clear(); + + if(iLen <= 0) + { + m_strCutOff = _T(""); + m_iCutOffIndex = 0; + return; + } + // variables + + HDC hDC = CreateCompatibleDC(NULL); + SelectObject(hDC, m_hFont); + + if(NULL == hDC) + return; + + int iWidth = GetWidth(); + SIZE sizeChar = {0, 0}; + SIZE sizeLine = {0, 0}; + SIZE sizeWord = {0,0}; + SIZE sizeCutOff = {0, 0}; + + int iAvailableLines = GetHeight()/m_iFontHeight; + // unitialized or too small labels need to be handled + if(iAvailableLines <= 0) + iAvailableLines = 1; + + // process wordwrapping + int i = 0; + if(m_bWordWrap && GetWidth() > 0) + { + int *piExtents = new int[m_strText.length()]; + TCHAR *szString = (TCHAR*)m_strText.c_str(); + int iMaxChars = 0; + tstring::size_type pos = 0; + + while(i= i && pos != i+iMaxChars) + iMaxChars = 1 + pos - i; + // if the string doesnt fit, try to wrap the last word to the next line + else if(iMaxChars < iLen - i || sizeLine.cx >= GetWidth()) + { + // find the last space in the line ( substract -1 from offset to ignore spaces as last chars ) + pos = m_strText.rfind(_T(" "),i + iMaxChars -1 ); + if(pos != tstring::npos && pos != i && pos >= i & pos != i+iMaxChars) + iMaxChars = 1 + pos - i; + } + + if(m_vLines.size() == iAvailableLines-1) + iMaxChars = iLen - i; + + m_vLines.push_back(m_strText.substr(i,iMaxChars)); + i += iMaxChars; + } + free(piExtents); + } + else + m_vLines.push_back(m_strText); + + // calculate the cutoff position + + GetTextExtentPoint(hDC,_T("..."),3,&sizeCutOff); + + int *piWidths = new int[(*--m_vLines.end()).length()]; + int iMaxChars = 0; + + GetTextExtentExPoint(hDC,(*--m_vLines.end()).c_str(),(*--m_vLines.end()).length(),iWidth,&iMaxChars,piWidths,&sizeLine); + + if(iMaxChars < (*--m_vLines.end()).length()) + { + for(iMaxChars--;iMaxChars>0;iMaxChars--) + { + if(piWidths[iMaxChars] + sizeCutOff.cx <= iWidth) + break; + } + (*--m_vLines.end()) = (*--m_vLines.end()).substr(0,iMaxChars) + _T("..."); + } + free(piWidths); + + DeleteObject(hDC); + + //if(GetWidth() == 0) + m_iLineCount = 1; + //else + // m_iLineCount = ceil((double)(sizeLine.cx + sizeCutOff.cx)/GetWidth()); + + //if(m_iLineCount > GetHeight()/m_iFontHeight) + // m_iLineCount = GetHeight()/m_iFontHeight; +} + +//************************************************************************ +// sets the cutoff mode +//************************************************************************ +void CLCDLabel::SetCutOff(bool bEnable) +{ + m_bCutOff = bEnable; +} \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDLabel.h b/plugins/MirandaG15/LCDFramework/src/CLCDLabel.h new file mode 100644 index 0000000000..b2bcc5bc3b --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDLabel.h @@ -0,0 +1,52 @@ +#ifndef _CLCDLABEL_H_ +#define _CLCDLABEL_H_ + +#include "CLCDTextObject.h" + +class CLCDLabel : public CLCDTextObject +{ +public: + // constructor + CLCDLabel(); + // destructor + ~CLCDLabel(); + + // initializes the label + bool Initialize(); + // deinitializes the label + bool Shutdown(); + + // update the label + bool Update(); + // draw the label + bool Draw(CLCDGfx *pGfx); + + // sets the label's text + void SetText(tstring strText); + + // sets the cutoff mode + void SetCutOff(bool bEnable); + + // sets the wordwrap mode + void SetWordWrap(bool bEnable); + +private: + // updates the cutoff index + void UpdateCutOffIndex(); + // called when the labels size has changed + void OnSizeChanged(SIZE OldSize); + // called when the labels font has changed + void OnFontChanged(); + + bool m_bWordWrap; + + bool m_bCutOff; + int m_iCutOffIndex; + tstring m_strText; + tstring m_strCutOff; + int m_iLineCount; + + vector m_vLines; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDList.h b/plugins/MirandaG15/LCDFramework/src/CLCDList.h new file mode 100644 index 0000000000..ae019fe914 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDList.h @@ -0,0 +1,943 @@ +#ifndef _CLCDLIST_H_ +#define _CLCDLIST_H_ + +#include "CLCDTextObject.h" +#include "CLCDBar.h" +#include + + +enum EListEntryType { ROOT = 0,CONTAINER = 1,ITEM = 2}; + +template class CListEntry +{ +public: + CListEntry(CListEntry *pParent) + { + m_iIndex = -1; + m_iEntryCount = 0; + m_Position = NULL; + m_pParent = pParent; + if(pParent == NULL) + { + m_iLevel = 0; + m_eType = ROOT; + m_pRoot = this; + } + else + m_iLevel = m_pParent->GetLevel()+1; + } + + virtual ~CListEntry() + { + + } + + int GetLevel() + { + return m_iLevel; + } + + virtual CListEntry *GetNextEntry() + { + if(m_pParent == NULL) + return NULL; + + return m_pParent->GetNextEntry(this); + } + + virtual CListEntry *GetPreviousEntry() + { + if(m_pParent == NULL) + return NULL; + + return m_pParent->GetPreviousEntry(this); + } + + virtual CListEntry *GetNextEntry(CListEntry *pEntry) + { + return NULL; + } + + virtual CListEntry *GetPreviousEntry(CListEntry *pEntry) + { + return NULL; + } + + EListEntryType GetType() + { + return m_eType; + } + + int GetEntryCount() + { + return m_iEntryCount; + } + + virtual void UpdateEntryCount() + { + m_iEntryCount = 0; + } + + void SetRoot(CListEntry* pRoot) + { + m_pRoot = pRoot; + } + + virtual void DeleteItem(T Entry) + { + } + + virtual void DeleteGroup(G Group) + { + } + + CListEntry *GetPosition() + { + return m_Position; + } + + virtual void SetPosition(CListEntry *pPosition) + { + m_Position = pPosition; + } + + CListEntry *GetParent() + { + return m_pParent; + } + + int GetIndex() + { + return m_iIndex; + } + + void SetIndex(int iIndex) + { + m_iIndex = iIndex; + } + +protected: + int m_iIndex; + int m_iEntryCount; + int m_iLevel; + EListEntryType m_eType; + CListEntry *m_pParent; + CListEntry *m_pRoot; + CListEntry *m_Position; +}; + +template class CListItem : public CListEntry +{ +public: + CListItem(CListEntry *pParent,T Entry) : CListEntry(pParent) + { + m_Item = Entry; + m_eType = ITEM; + } + + ~CListItem() + { + m_pRoot->DeleteItem(GetItemData()); + } + + T GetItemData() + { + return m_Item; + } +private: + T m_Item; +}; + +template class CListContainer : public CListEntry +{ +public: + typedef typename list* >::iterator iterator; + + typename list* >::iterator end() + { + return m_Entrys.end(); + } + + typename list* >::iterator begin() + { + return m_Entrys.begin(); + } + + typename list* >::size_type size() + { + return m_Entrys.size(); + } + + bool empty() + { + bool b = m_Entrys.empty(); + return m_Entrys.empty(); + } + + CListContainer(CListEntry *pParent) : CListEntry(pParent) + { + if(m_pParent != NULL) + { + m_eType = CONTAINER; + m_bOpen = false; + } + else + m_bOpen = true; + } + + ~CListContainer() + { + if(m_pRoot != NULL) { + m_pRoot->DeleteGroup(GetGroupData()); + } + Clear(); + } + + void Clear() + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListItem *pItem = NULL; + CListContainer *pContainer = NULL; + + while(iter != m_Entrys.end()) + { + delete *iter; + if(m_pRoot && m_pRoot->GetPosition() == *iter) + { + if(GetType() == ROOT) + m_pRoot->SetPosition(NULL); + else + m_pRoot->SetPosition(this); + } + + iter++; + } + m_Entrys.clear(); + } + + void SetGroupData(G GroupData) + { + m_GroupData = GroupData; + } + + bool IsEmpty() + { + return m_Entrys.empty(); + } + + CListEntry *GetLastOwnEntry() + { + if(m_Entrys.empty()) + return NULL; + + return *(--m_Entrys.end()); + } + + CListEntry *GetLastEntry() + { + if(!m_Entrys.empty()) + { + + CListEntry *pEntry = *(--m_Entrys.end()); + if(pEntry->GetType() == ITEM || !((CListContainer*)pEntry)->IsOpen() || ((CListContainer*)pEntry)->IsEmpty()) + return pEntry; + return ((CListContainer*)pEntry)->GetLastEntry(); + } + return NULL; + } + + CListEntry *GetFirstEntry() + { + if(!m_Entrys.empty()) + return *(m_Entrys.begin()); + return NULL; + } + + CListEntry *GetNextEntry() + { + if(!IsOpen() || m_Entrys.empty()) + { + if(!m_pParent) + return NULL; + return m_pParent->GetNextEntry(this); + } + + return *m_Entrys.begin(); + } + + CListEntry *GetNextEntry(CListEntry *pEntry) + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + while(iter != m_Entrys.end()) + { + if((CListEntry*)(*iter) == pEntry) + { + if(++iter == m_Entrys.end()) + { + if(m_pParent == NULL) + return NULL; + return m_pParent->GetNextEntry(this); + } + else + return *iter; + } + iter++; + } + return NULL; + } + + CListEntry *GetPreviousEntry(CListEntry *pEntry) + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + + while(iter != m_Entrys.end()) + { + if((CListEntry*)(*iter) == pEntry) + { + if(iter == m_Entrys.begin()) + { + if(m_pParent == NULL) + return NULL; + return this; + } + else + { + iter--; + if((*iter)->GetType() == CONTAINER) + { + CListContainer* pContainer = (CListContainer*)*iter; + if(pContainer->IsOpen() && !pContainer->IsEmpty()) + return pContainer->GetLastEntry(); + } + return *iter; + } + } + iter++; + } + return NULL; + } + + virtual CListItem *InsertItem(iterator _Where,T Entry) + { + CListItem *pItem = new CListItem(this,Entry); + pItem->SetRoot(m_pRoot); + m_Entrys.insert(_Where,pItem); + + m_pRoot->UpdateEntryCount(); + + return pItem; + } + + virtual CListContainer *InsertGroup(iterator _Where,G Group) + { + CListContainer *pGroup = new CListContainer(this); + pGroup->SetGroupData(Group); + pGroup->SetRoot(m_pRoot); + m_Entrys.insert(_Where,(CListEntry*)pGroup); + + m_pRoot->UpdateEntryCount(); + + return pGroup; + } + + virtual CListItem * AddItem(T Entry) + { + return InsertItem(end(),Entry); + } + + virtual CListContainer * AddGroup(G Group) + { + return InsertGroup(end(),Group); + } + + + + virtual void RemoveGroup(G Group) + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListContainer *pContainer = NULL; + while(iter != m_Entrys.end()) + { + if((*iter)->GetType() == CONTAINER) + { + pContainer = (CListContainer*)(*iter); + if(pContainer->GetGroupData() == Group) + { + pContainer->Clear(); + if(m_pRoot && m_pRoot->GetPosition() == *iter) + { + CListEntry *pPosition = (*iter)->GetPreviousEntry(); + if(!pPosition) + pPosition = (*iter)->GetNextEntry(); + m_pRoot->SetPosition(pPosition); + } + delete *iter; + m_Entrys.erase(iter); + m_pRoot->UpdateEntryCount(); + return; + } + } + iter++; + } + } + + virtual void RemoveItem(T Entry) + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListItem *pItem = NULL; + while(iter != m_Entrys.end()) + { + if((*iter)->GetType() == ITEM) + { + pItem = (CListItem*)(*iter); + if(pItem->GetItemData() == Entry) + { + if(m_pRoot && m_pRoot->GetPosition() == *iter) + { + CListEntry *pPosition = (*iter)->GetPreviousEntry(); + if(!pPosition) + pPosition = (*iter)->GetNextEntry(); + m_pRoot->SetPosition(pPosition); + } + delete *iter; + + m_Entrys.erase(iter); + m_pRoot->UpdateEntryCount(); + return; + } + } + iter++; + } + } + + CListContainer *GetGroup(G Group) + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListContainer *pContainer = NULL; + while(iter != m_Entrys.end()) + { + if((*iter)->GetType() == CONTAINER) + { + pContainer = (CListContainer*)(*iter); + if(pContainer->GetGroupData() == Group) + return pContainer; + } + iter++; + } + return NULL; + } + + G GetGroupData() + { + return m_GroupData; + } + + bool IsOpen() + { + return m_bOpen; + } + + void ToggleOpen() + { + m_bOpen = !m_bOpen; + + m_pRoot->UpdateEntryCount(); + if(m_pRoot) + m_pRoot->SetPosition(this); + } + + void SetOpen(bool bOpen = true) + { + if(bOpen == m_bOpen) + return; + + m_bOpen = bOpen; + + m_pRoot->UpdateEntryCount(); + if(m_pRoot) + m_pRoot->SetPosition(this); + } + + void CollapseAll() + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListContainer* pContainer = NULL; + while(iter != m_Entrys.end()) + { + if((*iter)->GetType() == CONTAINER) + { + pContainer = (CListContainer*)(*iter); + pContainer->CollapseAll(); + pContainer->SetOpen(false); + } + iter++; + } + } + + void ExpandAll() + { + list< CListEntry* >::iterator iter = m_Entrys.begin(); + CListContainer* pContainer = NULL; + while(iter != m_Entrys.end()) + { + if((*iter)->GetType() == CONTAINER) + { + pContainer = (CListContainer*)(*iter); + pContainer->ExpandAll(); + pContainer->SetOpen(true); + } + iter++; + } + } + + void UpdateEntryCount() + { + m_iEntryCount = 0; + + int iIndex = GetIndex()+1; + + if(!IsOpen()) + return; + + list< CListEntry* >::iterator iter = m_Entrys.begin(); + while(iter != m_Entrys.end()) + { + (*iter)->SetIndex(iIndex+m_iEntryCount); + (*iter)->UpdateEntryCount(); + m_iEntryCount += 1+(*iter)->GetEntryCount(); + + iter++; + } + + if(GetType() == ROOT) + { + if(GetPosition() == NULL && !m_Entrys.empty()) + SetPosition(*m_Entrys.begin()); + else + SetPosition(GetPosition()); + } + } + + template + void sort(_Pr3 _Pred) { + m_Entrys.sort(_Pred); + UpdateEntryCount(); + m_pRoot->SetPosition(m_pRoot->GetPosition()); + } + +private: + typename list< CListEntry* > m_Entrys; + G m_GroupData; + bool m_bOpen; +}; + + +template class CLCDList : public CLCDTextObject, public CListContainer +{ +friend CListContainer; +friend CListItem; +public: + //************************************************************************ + // Constructor + //************************************************************************ + CLCDList() : CListContainer(NULL) + { + m_pScrollbar = NULL; + m_iIndention = 10; + m_iColumns = 1; + m_bDrawTreeLines = true; + m_iEntryHeight = 10; + } + + //************************************************************************ + // Destructor + //************************************************************************ + ~CLCDList() + { + } + + //************************************************************************ + // Initializes the list + //************************************************************************ + bool Initialize() + { + if(!CLCDTextObject::Initialize()) + return false; + + return true; + } + + //************************************************************************ + // Deinitializes the list + //************************************************************************ + bool Shutdown() + { + if(!CLCDTextObject::Shutdown()) + return false; + + Clear(); + + return true; + } + + //************************************************************************ + // updates the list + //************************************************************************ + bool Update() + { + if(!CLCDTextObject::Update()) + return false; + + return true; + } + + //************************************************************************ + // draws the list + //************************************************************************ + bool Draw(CLCDGfx *pGfx) + { + if(!CLCDTextObject::Draw(pGfx)) + return false; + + SelectObject(pGfx->GetHDC(),m_hFont); + + POINT ptPrevViewportOrg = { 0, 0 }; + HRGN hRgn = NULL; + int iHeight = 0,iLimit=0; + int iYOffset = 0, iXOffset=0; + int iColWidth = (GetWidth()- (m_iColumns-1)*3)/m_iColumns; + int iSpace = GetHeight() - (GetHeight()/m_iEntryHeight)*m_iEntryHeight; + int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; + + int iEntriesDrawn = 0; + CListEntry *pPosition = m_Position; + + // if nothing is selected, skip drawing + if(pPosition == NULL) + return true; + + bool bDrawGroup = false; + bool bSelected = false; + + // calculate the start offset + + if(m_iStartIndex < pPosition->GetIndex()) + { + while(pPosition && pPosition->GetIndex() != m_iStartIndex) + pPosition = pPosition->GetPreviousEntry(); + } + + if(m_iStartIndex > 0 && pPosition->GetIndex() > 0) + pPosition = pPosition->GetPreviousEntry(); + + for(int iCol = 0;iColGetIndex() < m_iStartIndex) + iHeight -= m_iEntryHeight-iSpace; + else if(GetEntryCount() >= (iPerPage/m_iColumns) +1) + iHeight = iSpace; + } + + // bottom selection + while(pPosition != NULL ) + { + iYOffset = iHeight; + + bSelected = m_Position == pPosition; + bDrawGroup = pPosition->GetType() == CONTAINER; + + // ~~~~~~~~~~~~~~~~~~~~~~ + // Draw tree lines + // ~~~~~~~~~~~~~~~~~~~~~~ + + // set the clip region for the entry + int iClipHeight = m_iEntryHeight; + if(GetOrigin().y+iYOffset+iClipHeight > GetOrigin().y + GetHeight()) + iClipHeight = GetHeight() - iYOffset; + + pGfx->SetClipRegion(GetOrigin().x+iXOffset,GetOrigin().y+iYOffset, + iColWidth, iClipHeight); + + // offset the control at its origin so entry use (0,0) + SetViewportOrgEx(pGfx->GetHDC(), + GetOrigin().x+iXOffset, + GetOrigin().y+iYOffset, + &ptPrevViewportOrg); + + if(m_bDrawTreeLines) + { + for(int i=1;iGetLevel();i++) + { + if(i == pPosition->GetLevel()-1) + { + // - + pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight/2,i*m_iIndention,m_iEntryHeight/2); + // | + if(pPosition == ((CListContainer*)pPosition->GetParent())->GetLastOwnEntry()) + pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight/2); + // | + // | + else + pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight); + } + else + { + CListEntry *pPosition2 = pPosition; + for(int j = pPosition->GetLevel();j>i+1;j--) + pPosition2 = pPosition2->GetParent(); + // | + // | + if(pPosition2 != ((CListContainer*)pPosition2->GetParent())->GetLastOwnEntry()) + pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight); + } + } + } + + // ~~~~~~~~~~~~~~~~~~~~~~ + // Draw the entry + // ~~~~~~~~~~~~~~~~~~~~~~ + pGfx->SetClipRegion(GetOrigin().x+(pPosition->GetLevel()-1)*m_iIndention+iXOffset, + GetOrigin().y+iYOffset, + iColWidth-(pPosition->GetLevel()-1)*m_iIndention, + iClipHeight); + // set the offset + SetViewportOrgEx(pGfx->GetHDC(), + GetOrigin().x+(pPosition->GetLevel()-1)*m_iIndention+iXOffset, + GetOrigin().y+iYOffset, + &ptPrevViewportOrg); + + // draw the entry + if(!bDrawGroup) + DrawEntry(pGfx,((CListItem*)pPosition)->GetItemData(),bSelected); + else + // draw the group + DrawGroup(pGfx,((CListContainer*)pPosition)->GetGroupData(),((CListContainer*)pPosition)->IsOpen(),bSelected); + + // ~~~~~~~~~~~~~~~~~~~~~~ + + if(pPosition->GetIndex() >= m_iStartIndex && iHeight + m_iEntryHeight <= GetHeight()) + iEntriesDrawn++; + + iHeight += m_iEntryHeight; + pPosition = pPosition->GetNextEntry(); + + if(iHeight >= GetHeight()) + break; + } + if(iCol != m_iColumns-1) + { + pGfx->SetClipRegion(GetOrigin().x, + GetOrigin().y, + GetWidth(), + GetHeight()); + // set the offset + SetViewportOrgEx(pGfx->GetHDC(), + GetOrigin().x, + GetOrigin().y, + &ptPrevViewportOrg); + + pGfx->DrawLine(iCol*3 + iColWidth + 1,0,iCol*3 + iColWidth + 1,GetHeight()); + } + iXOffset += 3 + iColWidth; + } + + if(m_pScrollbar) + { + m_pScrollbar->ScrollTo(m_iStartIndex); + m_pScrollbar->SetSliderSize(iEntriesDrawn); + } + return true; + } + + + void SetPosition(CListEntry *pEntry) + { + CListContainer::SetPosition(pEntry); + + if(pEntry == NULL) + return; + + int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; + m_iStartIndex = pEntry->GetIndex(); + if(m_iStartIndex + (iPerPage-1) > GetEntryCount()-1) + m_iStartIndex = (GetEntryCount()-1)-(iPerPage-1); + if(m_iStartIndex < 0) + m_iStartIndex = 0; + } + + //************************************************************************ + // scrolls up + //************************************************************************ + bool ScrollUp() + { + if(m_Position != NULL) + { + CListEntry *pEntry = m_Position->GetPreviousEntry(); + if(pEntry != NULL) + { + m_Position = pEntry; + + int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; + if(m_Position->GetIndex() < m_iStartIndex) + m_iStartIndex--; + return true; + } + } + return false; + } + + //************************************************************************ + // scrolls down + //************************************************************************ + bool ScrollDown() + { + if(m_Position != NULL) + { + CListEntry *pEntry = m_Position->GetNextEntry(); + if(pEntry != NULL) + { + m_Position = pEntry; + + int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns; + if(m_Position->GetIndex() >= m_iStartIndex + iPerPage) + m_iStartIndex++; + return true; + } + } + return false; + } + + //************************************************************************ + // returns the selected list entry + //************************************************************************ + CListEntry *GetSelectedEntry() + { + return m_Position; + } + + //************************************************************************ + // associates a scrollbar with the list + //************************************************************************ + void SetScrollbar(CLCDBar *pScrollbar) + { + m_pScrollbar = pScrollbar; + if(m_pScrollbar) + { + m_pScrollbar->SetRange(0,m_iEntryCount-1); + m_pScrollbar->ScrollTo(m_Position != NULL?m_Position->GetIndex():0); + + m_pScrollbar->SetAlignment(TOP); + } + } + + //************************************************************************ + // sets the group indention in pixels + //************************************************************************ + void SetIndention(int iIndention) + { + m_iIndention = iIndention; + } + + //************************************************************************ + // sets the lists entry height + //************************************************************************ + void SetEntryHeight(int iEntryHeight) + { + m_iEntryHeight = iEntryHeight; + } + + //************************************************************************ + // returns the lists entry height + //************************************************************************ + int GetEntryHeight() + { + return m_iEntryHeight; + } + + //************************************************************************ + // enables/disables drawing of treelines + //************************************************************************ + void SetDrawTreeLines(bool bDraw) + { + m_bDrawTreeLines = bDraw; + } + + //************************************************************************ + // sets the amount of columns the list uses + //************************************************************************ + void SetColumns(int iColumns) + { + if(m_iColumns == iColumns) + return; + m_iColumns = iColumns; + SetPosition(GetPosition()); + } +protected: + //************************************************************************ + // called when the lists size has changed + //************************************************************************ + void OnSizeChanged() + { + SetPosition(GetPosition()); + } + + //************************************************************************ + // updates the list's entry count + //************************************************************************ + void UpdateEntryCount() + { + CListContainer::UpdateEntryCount(); + if(m_pScrollbar) + { + m_pScrollbar->SetRange(0,m_iEntryCount-1); + if(GetPosition() != NULL) + m_pScrollbar->ScrollTo(GetPosition()->GetIndex()); + } + } + + //************************************************************************ + // Called to delete the specified entry + //************************************************************************ + virtual void DeleteEntry(T Entry) + { + + } + + //************************************************************************ + // Called to delete the specified group + //************************************************************************ + virtual void DeleteGroup(G Group) + { + + } + + //************************************************************************ + // Called to draw the specified entry + //************************************************************************ + virtual void DrawEntry(CLCDGfx *pGfx,T Entry, bool bSelected) + { + } + + //************************************************************************ + // Called to draw the specified entry + //************************************************************************ + virtual void DrawGroup(CLCDGfx *pGfx,G Group, bool bOpen, bool bSelected) + { + } + + + +protected: + int m_iStartIndex; + int m_iColumns; + + bool m_bDrawTreeLines; + int m_iIndention; + int m_iEntryHeight; + CLCDBar *m_pScrollbar; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDObject.h b/plugins/MirandaG15/LCDFramework/src/CLCDObject.h new file mode 100644 index 0000000000..13dbb5a101 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDObject.h @@ -0,0 +1,52 @@ +#ifndef _CLCDOBJECT_H_ +#define _CLCDOBJECT_H_ + +#include "CLCDGfx.h" + +class CLCDObject +{ +public: + // Constructor + CLCDObject(); + // Destructor + ~CLCDObject(); + + // Initialize the object + virtual bool Initialize(); + // Shutdown the object + virtual bool Shutdown(); + + // Set the origin of the object + void SetOrigin(int iX,int iY); + void SetOrigin(POINT p); + // Get the origin of the object + POINT GetOrigin(); + // Set the size of the object + void SetSize(int iWidth,int iHeight); + void SetSize(SIZE s); + // Get the size of the object + SIZE GetSize(); + int GetWidth(); + int GetHeight(); + + // Set the visibility + void Show(bool bShow); + // Check the visibility + bool IsVisible(); + + // Update the object + virtual bool Update(); + // Draw the object + virtual bool Draw(CLCDGfx *pGfx); + +protected: + // Called when the size of the object has changed + virtual void OnSizeChanged(SIZE OldSize); + +private: + POINT m_Origin; + SIZE m_Size; + bool m_bShow; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDOutputManager.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDOutputManager.cpp new file mode 100644 index 0000000000..e1cc493a16 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDOutputManager.cpp @@ -0,0 +1,451 @@ +#include "stdafx.h" + +#include "CLCDGfx.h" +#include "CLCDObject.h" +#include "CLCDScreen.h" + +#include "CLCDConnection.h" +#include "CLCDConnectionLogitech.h" +#include "CLCDOutputManager.h" +#include + +CLCDOutputManager *CLCDOutputManager::m_pInstance = NULL; + +//************************************************************************ +// Constructor +//************************************************************************ +CLCDOutputManager::CLCDOutputManager() +{ + ASSERT(m_pInstance == NULL); + + m_pInstance = this; + m_strAppletName = _T(""); + m_pbButtonStates = NULL; + m_pActiveScreen = NULL; + m_bInitialized = false; + + m_dwButtonRepeatDelay = 300; + m_dwLastUpdate = 0; +} + +//************************************************************************ +// Destructor +//************************************************************************ +CLCDOutputManager::~CLCDOutputManager() +{ + m_pInstance = NULL; +} + +//************************************************************************ +// Gets the OutputManager Instance +//************************************************************************ +CLCDOutputManager* CLCDOutputManager::GetInstance() +{ + ASSERT(m_pInstance != NULL); + + return m_pInstance; +} + +//************************************************************************ +// returns the active lcdconnection +//************************************************************************ +CLCDConnection *CLCDOutputManager::GetLCDConnection() +{ + ASSERT(m_pLcdConnection != NULL); + return m_pLcdConnection; +} + +//************************************************************************ +// returns the active scren +//************************************************************************ +CLCDScreen *CLCDOutputManager::GetActiveScreen() +{ + return m_pActiveScreen; +} + +//************************************************************************ +// Initializes the OutputManager +//************************************************************************ +bool CLCDOutputManager::Initialize(tstring strAppletName,bool bAutostart, bool bConfigDialog) +{ + srand ( time(NULL) ); + + InitDebug(); + + m_strAppletName = strAppletName; + + m_pGfx = new CLCDGfx(); + + m_pLcdConnection = new CLCDConnectionLogitech(); + if(!m_pLcdConnection->Initialize(m_strAppletName,bAutostart,bConfigDialog)) + return false; + + + m_bInitialized = true; + + m_dwLastUpdate = GetTickCount(); + return true; +} + +//************************************************************************ +// return wether the Outputmanager is initialized +//************************************************************************ +bool CLCDOutputManager::IsInitialized() +{ + return m_bInitialized; +} + +//************************************************************************ +// Deinitializes the Outputmanager +//************************************************************************ +bool CLCDOutputManager::Shutdown() +{ + ASSERT(NULL != m_pLcdConnection); + ASSERT(NULL != m_pGfx); + + // Shutdown all screens + vector::iterator iter = m_Screens.begin(); + while(iter != m_Screens.end()) + { + (*(iter))->Shutdown(); + iter++; + } + + m_pLcdConnection->Shutdown(); + + + delete m_pLcdConnection; + + UnInitDebug(); + m_bInitialized = false; + return true; +} + +//************************************************************************ +// called by CLCDConnection when connected to a device +//************************************************************************ +void CLCDOutputManager::OnDeviceConnected() { + InitializeGfxObject(); + OnConnectionChanged(CONNECTED); +} + +//************************************************************************ +// called by CLCDConnection when disconnected from a device +//************************************************************************ +void CLCDOutputManager::OnDeviceDisconnected() { + DeinitializeGfxObject(); + OnConnectionChanged(DISCONNECTED); +} + +//************************************************************************ +// Initializes the CGfx Object +//************************************************************************ +void CLCDOutputManager::InitializeGfxObject() { + if(m_pGfx->IsInitialized()) + return; + + TRACE(_T("CLCDOutputManager::UpdateGfxObject(): initializing CLCDGfx\n")); + SIZE size; + size = m_pLcdConnection->GetDisplaySize(); + + m_pGfx->Initialize(size.cx,size.cy,m_pLcdConnection->GetColorCount(), m_pLcdConnection->GetPixelBuffer()); + + int iButtonCount = m_pLcdConnection->GetButtonCount(); + + m_pbButtonStates = (bool*)malloc(sizeof(bool)*iButtonCount); + m_pdwButtonRepeatTimers = (DWORD*)malloc(sizeof(DWORD)*iButtonCount); + m_pdwButtonRepeatStarts = (DWORD*)malloc(sizeof(DWORD)*iButtonCount); + for(int i=0;i::iterator iter = m_Screens.begin(); + while(iter != m_Screens.end()) + { + (*(iter))->OnSizeChanged(); + iter++; + } + + OnLCDConnected(); +} + +//************************************************************************ +// Deinitializes the CGfx Object +//************************************************************************ +void CLCDOutputManager::DeinitializeGfxObject() { + if(!m_pGfx->IsInitialized()) + return; + + TRACE(_T("CLCDOutputManager::UpdateGfxObject(): shutting down CLCDGfx\n")); + + m_pGfx->Shutdown(); + free(m_pbButtonStates); + free(m_pdwButtonRepeatTimers); + free(m_pdwButtonRepeatStarts); + + OnLCDDisconnected(); +} + +//************************************************************************ +// Update all Screens & draw +//************************************************************************ +bool CLCDOutputManager::Update() +{ + ASSERT(m_bInitialized); + + DWORD dwElapsed = GetTickCount() - m_dwLastUpdate; + + // Update the active screen + if(m_pActiveScreen != NULL) + { + m_pActiveScreen->Update(); + // Check if the active screen has expired + if(m_pActiveScreen->HasExpired()) + { + // Call event handlers + DeactivateScreen(); + return true; + } + } + + // Update + m_pLcdConnection->Update(); + + // skip button checking and drawing if there is no connection to a device + if(!m_pLcdConnection || m_pLcdConnection->GetConnectionState() != CONNECTED) + return true; + + + // Handle buttons + bool bState = false; + int iId = 0; + for(int i = 0; i< m_pLcdConnection->GetButtonCount();i++) + { + // get current state + bState = m_pLcdConnection->GetButtonState(i); + // handle input event + if(bState != m_pbButtonStates[i]) + { + iId = m_pLcdConnection->GetButtonId(i); + if(bState) { + OnLCDButtonDown(iId); + } else { + OnLCDButtonUp(iId); + } + m_pdwButtonRepeatStarts[i] = GetTickCount(); + m_pdwButtonRepeatTimers[i] = m_pdwButtonRepeatStarts[i] + m_dwButtonRepeatDelay; + } + // check if repeat event should be sent + else if(bState && m_pdwButtonRepeatTimers[i] <= GetTickCount()) + { + iId = m_pLcdConnection->GetButtonId(i); + + // reduce the delay by 5% per second + DWORD dwNewDelay = m_dwButtonRepeatDelay - ((float)m_dwButtonRepeatDelay * 0.05 * (GetTickCount() - m_pdwButtonRepeatStarts[i]) / 250); + // delay may not be less than 25% of the original value + if(dwNewDelay < m_dwButtonRepeatDelay * 0.25) + dwNewDelay = m_dwButtonRepeatDelay * 0.25; + + m_pdwButtonRepeatTimers[i] = GetTickCount() + dwNewDelay; + + OnLCDButtonRepeated(iId); + } + // save the current state + m_pbButtonStates[i] = bState; + } + + // Draw + + if(m_pActiveScreen != NULL && m_pGfx->IsInitialized()) + { + m_pGfx->BeginDraw(); + m_pGfx->ClearScreen(); + m_pActiveScreen->Draw(m_pGfx); + m_pGfx->EndDraw(); + + m_pLcdConnection->SetAlert(m_pActiveScreen->GetAlert()); + m_pLcdConnection->Draw(); + } + else + m_pLcdConnection->HideApplet(); + + m_dwLastUpdate = GetTickCount(); + return true; +} + +//************************************************************************ +// Deactivates the active screen +//************************************************************************ +bool CLCDOutputManager::DeactivateScreen() +{ + if(m_pActiveScreen == NULL) + return false; + + CLCDScreen *pActiveScreen = m_pActiveScreen; + m_pActiveScreen = NULL; + + if(pActiveScreen->HasExpired()) + { + pActiveScreen->OnExpiration(); + OnScreenExpired(pActiveScreen); + } + else + { + OnScreenDeactivated(pActiveScreen); + pActiveScreen->OnDeactivation(); + } + return true; +} + +//************************************************************************ +// Activates the specified screen +//************************************************************************ +bool CLCDOutputManager::ActivateScreen(CLCDScreen *pScreen) +{ + if(m_pActiveScreen == pScreen) + return false; + + // If another screen is currently active, deactivate it + if(m_pActiveScreen != NULL) + DeactivateScreen(); + + m_pActiveScreen = pScreen; + m_pActiveScreen->OnActivation(); + return true; +} + +//************************************************************************ +// Adds a screen to the managers list +//************************************************************************ +bool CLCDOutputManager::AddScreen(CLCDScreen *pScreen) +{ + // Check if the screen is already managed + vector::iterator iter = m_Screens.begin(); + while(iter != m_Screens.end()) + { + if(*(iter) == pScreen) + return false; + iter++; + } + + m_Screens.push_back(pScreen); + return true; +} + +//************************************************************************ +// Removes a screen from the managers list +//************************************************************************ +bool CLCDOutputManager::RemoveScreen(CLCDScreen *pScreen) +{ + if(m_Screens.empty()) + return false; + + // Find the screen and remove it from the list of managed screens + vector::iterator iter = m_Screens.begin(); + while(iter != m_Screens.end()) + { + if(*(iter) == pScreen) + { + m_Screens.erase(iter); + return true; + } + iter++; + } + return false; +} + +//************************************************************************ +// starts a screen transition +//************************************************************************ +void CLCDOutputManager::StartTransition(ETransitionType eTransition,LPRECT rect) +{ + m_pGfx->StartTransition(eTransition,rect); +} + +//************************************************************************ +// specifies the button repeat delay +//************************************************************************ +void CLCDOutputManager::SetButtonRepeatDelay(DWORD dwDelay) +{ + m_dwButtonRepeatDelay = dwDelay; +} + +//************************************************************************ +// Called when a screen has been deactivated +//************************************************************************ +void CLCDOutputManager::OnScreenDeactivated(CLCDScreen *pScreen) +{ +} + +//************************************************************************ +// Called when a screen has expired +//************************************************************************ +void CLCDOutputManager::OnScreenExpired(CLCDScreen *pScreen) +{ +} + +//************************************************************************ +// Called when an LCD button is repeated +//************************************************************************ +void CLCDOutputManager::OnLCDButtonRepeated(int iButton) +{ + if(m_pActiveScreen) { + m_pActiveScreen->OnLCDButtonRepeated(iButton); + } +} + +//************************************************************************ +// Called when an LCD button is pressed +//************************************************************************ +void CLCDOutputManager::OnLCDButtonDown(int iButton) +{ + if(m_pActiveScreen) + m_pActiveScreen->OnLCDButtonDown(iButton); +} + +//************************************************************************ +// Called when an LCD button is released +//************************************************************************ +void CLCDOutputManager::OnLCDButtonUp(int iButton) +{ + if(m_pActiveScreen) + m_pActiveScreen->OnLCDButtonUp(iButton); +} + +//************************************************************************ +// Called when the connection state has changed +//************************************************************************ +void CLCDOutputManager::OnConnectionChanged(int iConnectionState) +{ +} + +//************************************************************************ +// Called when the LCD has been plugged in +//************************************************************************ +void CLCDOutputManager::OnLCDConnected() +{ +} + +//************************************************************************ +// Called when the LCD has been unplugged +//************************************************************************ +void CLCDOutputManager::OnLCDDisconnected() +{ +} + +//************************************************************************ +// Called by the LCDManager to open a config dialog +//************************************************************************ +DWORD WINAPI CLCDOutputManager::configDialogCallback(IN int connection,IN const PVOID pContext) { + return CLCDOutputManager::GetInstance()->OnConfigDialogRequest(connection,pContext); +} +//************************************************************************ +// Called when a config dialog is requested +//************************************************************************ +DWORD CLCDOutputManager::OnConfigDialogRequest(int connection, const PVOID pContext) { + return 0; +} \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDOutputManager.h b/plugins/MirandaG15/LCDFramework/src/CLCDOutputManager.h new file mode 100644 index 0000000000..1011e5d551 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDOutputManager.h @@ -0,0 +1,102 @@ +#ifndef _CLCDOUTPUTMANAGER_H_ +#define _CLCDOUTPUTMANAGER_H_ + +#include "CLCDGfx.h" +#include "CLCDScreen.h" +#include "CLCDConnection.h" +#include "CLCDDevice.h" + +class CLCDOutputManager +{ +friend CLCDConnection; +friend class CLCDConnectionLogitech; + +public: + // constructor + CLCDOutputManager(); + // destructor + ~CLCDOutputManager(); + + // Get the OutputManager Instance + static CLCDOutputManager *GetInstance(); + + // Initializes the Outputmanager + virtual bool Initialize(tstring strAppletName,bool bAutostart=false, bool bConfigDialog=false); + // return wether the Outputmanager is initialized + virtual bool IsInitialized(); + + // Deinitializes the Outputmanager + virtual bool Shutdown(); + // Updates the Outputmanager + virtual bool Update(); + + // Add a screen to the managers list + bool AddScreen(CLCDScreen *pScreen); + // Removes a screen from the managers list + bool RemoveScreen(CLCDScreen *pScreen); + + // Activates the specified screen + bool ActivateScreen(CLCDScreen *pScreen); + // Deactivates the active screen + bool DeactivateScreen(); + // returns the active scren + CLCDScreen *GetActiveScreen(); + + // returns the active lcdconnection + CLCDConnection *GetLCDConnection(); + + // specifies the button repeat delay + void SetButtonRepeatDelay(DWORD dwDelay); + + // starts a screen transition + void StartTransition(ETransitionType eTransition = TRANSITION_RANDOM,LPRECT rect = NULL); + + // called by CLCDConnection when connected to a device + void OnDeviceConnected(); + // called by CLCDConnection when disconnected from a device + void OnDeviceDisconnected(); + + // Called by the LCDManager to open a config dialog + static DWORD WINAPI configDialogCallback(IN int connection,IN const PVOID pContext); +protected: + void InitializeGfxObject(); + void DeinitializeGfxObject(); + + // Called when the connection state has changed + virtual void OnConnectionChanged(int iConnectionState); + + // Called when the LCD has been plugged in + virtual void OnLCDConnected(); + // Called when the LCD has been unplugged + virtual void OnLCDDisconnected(); + + // Called when an LCD button is pressed + virtual void OnLCDButtonDown(int iButton); + // Called when an LCD button is released + virtual void OnLCDButtonUp(int iButton); + // Called when an LCD button is repeated + virtual void OnLCDButtonRepeated(int iButton); + + virtual void OnScreenExpired(CLCDScreen *pScreen); + virtual void OnScreenDeactivated(CLCDScreen *pScreen); + + // Called when a config dialog is requested + virtual DWORD OnConfigDialogRequest(int connection, const PVOID pContext); + CLCDGfx *m_pGfx; +private: + DWORD m_dwLastUpdate; + DWORD m_dwButtonRepeatDelay; + bool m_bInitialized; + static CLCDOutputManager* m_pInstance; + bool *m_pbButtonStates; + DWORD *m_pdwButtonRepeatTimers; + DWORD *m_pdwButtonRepeatStarts; + tstring m_strAppletName; + CLCDConnection *m_pLcdConnection; + + + vector m_Screens; + CLCDScreen *m_pActiveScreen; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDScreen.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDScreen.cpp new file mode 100644 index 0000000000..fa1a59e49a --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDScreen.cpp @@ -0,0 +1,282 @@ +#include "stdafx.h" +#include "CLCDOutputManager.h" +#include "CLCDGfx.h" +#include "CLCDObject.h" +#include "CLCDScreen.h" + +//************************************************************************ +// Constructor +//************************************************************************ +CLCDScreen::CLCDScreen() +{ + m_dwExpiration = INFINITE; + m_bAlert = false; + + // Set a default screen size to use if no device is plugged in + m_Size.cx = 160; + m_Size.cy = 43; +} + +//************************************************************************ +// Destructor +//************************************************************************ +CLCDScreen::~CLCDScreen() +{ + +} + +//************************************************************************ +// Initializes the screen +//************************************************************************ +bool CLCDScreen::Initialize() +{ + CLCDConnection *pConnection = CLCDOutputManager::GetInstance()->GetLCDConnection(); + if(pConnection->GetConnectionState() == CONNECTED) { + m_Size = pConnection->GetDisplaySize(); + } + + return true; +} + +//************************************************************************ +// Shuts down the screen +//************************************************************************ +bool CLCDScreen::Shutdown() +{ + // Shutdown all Objects + vector::iterator iter = m_Objects.begin(); + while(iter != m_Objects.end()) + { + (*(iter))->Shutdown(); + iter++; + } + return true; +} + +//************************************************************************ +// called when the screens size has changed +//************************************************************************ +void CLCDScreen::OnSizeChanged() +{ + CLCDConnection *pConnection = CLCDOutputManager::GetInstance()->GetLCDConnection(); + if(!pConnection) + return; + + m_Size = pConnection->GetDisplaySize(); +} + +//************************************************************************ +// Updates the screen +//************************************************************************ +bool CLCDScreen::Update() +{ + // Loop through all objects and call their update function + vector::iterator iter = m_Objects.begin(); + CLCDObject *pObject = NULL; + while(iter != m_Objects.end()) + { + pObject = *(iter); + pObject->Update(); + + iter++; + } + return true; +} + +//************************************************************************ +// Draws the screen +//************************************************************************ +bool CLCDScreen::Draw(CLCDGfx *pGfx) +{ + POINT ptPrevViewportOrg = { 0, 0 }; + // Loop through all objects and call their draw function + vector::iterator iter = m_Objects.begin(); + CLCDObject *pObject = NULL; + while(iter != m_Objects.end()) + { + pObject = *(iter); + // Only draw visible objects + if(!pObject->IsVisible()) + { + iter++; + continue; + } + + // create the clip region + pGfx->SetClipRegion(pObject->GetOrigin().x, pObject->GetOrigin().y, + pObject->GetWidth(), + pObject->GetHeight()); + + // offset the control at its origin so controls use (0,0) + SetViewportOrgEx(pGfx->GetHDC(), + pObject->GetOrigin().x, + pObject->GetOrigin().y, + &ptPrevViewportOrg); + + /* +// allow controls to supply additional translation + // this allows controls to move freely within the confined viewport + OffsetViewportOrgEx(pGfx->GetHDC(), + 0, + 0, + NULL); +*/ + pObject->Draw(pGfx); + + iter++; + } + // set the clipping region to nothing + SelectClipRgn(pGfx->GetHDC(), NULL); + + // restore the viewport origin + SetViewportOrgEx(pGfx->GetHDC(), + 0, + 0, + NULL); + + return true; +} + +//************************************************************************ +// Set the screen's time until expiration +//************************************************************************ +void CLCDScreen::SetExpiration(DWORD dwTime) +{ + if(dwTime == INFINITE) + m_dwExpiration = INFINITE; + else + m_dwExpiration = GetTickCount() + dwTime; +} + +//************************************************************************ +// checks if the screen has expired +//************************************************************************ +bool CLCDScreen::HasExpired() +{ + if(m_dwExpiration == INFINITE) + return false; + + if(m_dwExpiration <= GetTickCount()) + return true; + return false; +} + +//************************************************************************ +// Set the alert status of the screen +//************************************************************************ +void CLCDScreen::SetAlert(bool bAlert) +{ + m_bAlert = bAlert; +} + +//************************************************************************ +// gets the alert status of the scren +//************************************************************************ +bool CLCDScreen::GetAlert() +{ + return m_bAlert; +} + +//************************************************************************ +// add an object to the screen's object list +//************************************************************************ +bool CLCDScreen::AddObject(CLCDObject *pObject) +{ + // Check if the object is already managed + vector::iterator iter = m_Objects.begin(); + while(iter != m_Objects.end()) + { + if(*(iter) == pObject) + return false; + iter++; + } + m_Objects.push_back(pObject); + return true; +} + +//************************************************************************ +// remove an object from the screen's object list +//************************************************************************ +bool CLCDScreen::RemoveObject(CLCDObject *pObject) +{ + if(m_Objects.empty()) + return false; + + // Find and remove the specified object + vector::iterator iter = m_Objects.begin(); + while(iter != m_Objects.end()) + { + if(*(iter) == pObject) + { + m_Objects.erase(iter); + return true; + } + iter++; + } + return false; +} + +//************************************************************************ +// gets the screen's height +//************************************************************************ +int CLCDScreen::GetHeight() +{ + return m_Size.cy; +} + +//************************************************************************ +// gets the screen's width +//************************************************************************ +int CLCDScreen::GetWidth() +{ + return m_Size.cx; +} + + +//************************************************************************ +// Called when the screen is activated +//************************************************************************ +void CLCDScreen::OnActivation() +{ + +} + +//************************************************************************ +// Called when the screen is deactivated +//************************************************************************ +void CLCDScreen::OnDeactivation() +{ + +} + +//************************************************************************ +// Called when the screen has expired +//************************************************************************ +void CLCDScreen::OnExpiration() +{ + +} + +//************************************************************************ +// Called when an LCD-button is pressed +//************************************************************************ +void CLCDScreen::OnLCDButtonDown(int iButton) +{ + +} + +//************************************************************************ +// Called when an LCD-button event is repeated +//************************************************************************ +void CLCDScreen::OnLCDButtonRepeated(int iButton) +{ + +} + +//************************************************************************ +// Called when an LCD-button is released +//************************************************************************ +void CLCDScreen::OnLCDButtonUp(int iButton) +{ + +} \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDScreen.h b/plugins/MirandaG15/LCDFramework/src/CLCDScreen.h new file mode 100644 index 0000000000..1f8b431a73 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDScreen.h @@ -0,0 +1,67 @@ +#ifndef _CLCDSCREEN_H_ +#define _CLCDSCREEN_H_ + +#include "CLCDGfx.h" +#include "CLCDObject.h" + +class CLCDScreen +{ +public: + // Constructor + CLCDScreen(); + // Destructor + ~CLCDScreen(); + + // Initializes the screen + virtual bool Initialize(); + // Shutdown the scren + virtual bool Shutdown(); + // Updates the screen + virtual bool Update(); + // Draws the screen + virtual bool Draw(CLCDGfx *pGfx); + + // Sets the screen's time until expiration + void SetExpiration(DWORD dwTime); + // Check if the screen has expired + bool HasExpired(); + + // Sets the alert status of the screen + void SetAlert(bool bAlert); + // gets the alert status of the scren + bool GetAlert(); + + // adds an object to the screen's object list + bool AddObject(CLCDObject *pObject); + // removes an object from the screen's object list + bool RemoveObject(CLCDObject *pObject); + + // get the screen's height + int GetHeight(); + // get the screen's width + int GetWidth(); + + // called when the screens size has changed + virtual void OnSizeChanged(); +public: + // Called when an LCD-button is pressed + virtual void OnLCDButtonDown(int iButton); + // Called when an LCD-button event is repeated + virtual void OnLCDButtonRepeated(int iButton); + // Called when an LCD-button is released + virtual void OnLCDButtonUp(int iButton); + // Called when the screen is activated + virtual void OnActivation(); + // Called when the screen is deactivated + virtual void OnDeactivation(); + // Called when the screen has expired + virtual void OnExpiration(); + +private: + SIZE m_Size; + vector m_Objects; + bool m_bAlert; + DWORD m_dwExpiration; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDTextLog.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDTextLog.cpp new file mode 100644 index 0000000000..d1abb9d704 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDTextLog.cpp @@ -0,0 +1,440 @@ +#include "StdAfx.h" +#include "CLCDTextLog.h" + + +//************************************************************************ +// Constructor +//************************************************************************ +CLCDTextLog::CLCDTextLog() +{ + m_dwLastScroll = 0; + + m_iLogSize = 10; + m_iPosition = 0; + m_iTextLines = 0; + m_pScrollbar = NULL; + m_eExpandMode = EXPAND_SCROLL; + m_eAutoScroll = SCROLL_MESSAGE; + m_iLastScrollDirection = 0; +} + +//************************************************************************ +// Destructor +//************************************************************************ +CLCDTextLog::~CLCDTextLog() +{ + ClearLog(); +} + +//************************************************************************ +// Initializes the log +//************************************************************************ +bool CLCDTextLog::Initialize() +{ + if(!CLCDTextObject::Initialize()) + return false; + + + return true; +} + +//************************************************************************ +// Deinitializes the log +//************************************************************************ +bool CLCDTextLog::Shutdown() +{ + if(!CLCDTextObject::Shutdown()) + return false; + + return true; +} + +//************************************************************************ +// updates the log +//************************************************************************ +bool CLCDTextLog::Update() +{ + if(!CLCDTextObject::Update()) + return false; + + return true; +} + +//************************************************************************ +// draws the log +//************************************************************************ +bool CLCDTextLog::Draw(CLCDGfx *pGfx) +{ + if(!CLCDTextObject::Draw(pGfx)) + return false; + + if (m_Entrys.empty()) + return true; + + // select current font + SelectObject(pGfx->GetHDC(), m_hFont); + + int iLineCount = (GetHeight()/m_iFontHeight); + int iSpacing = (GetHeight() - iLineCount*m_iFontHeight)/2; + + list::iterator iter = m_Entrys.begin(); + CLogEntry *pEntry = NULL; + RECT rBoundary = { 0, iSpacing,GetWidth() , GetHeight()-iSpacing}; + int iPosition = 0; + int iLinesDrawn = 0; + while(iLinesDrawn < iLineCount && iter != m_Entrys.end()) + { + pEntry = *(iter++); + // This Message has something to draw + if(iPosition + pEntry->iLines > m_iPosition ) + { + int iLine = (m_iPosition + iLinesDrawn) - iPosition; + for(;iLinesDrawn < iLineCount && iLine < pEntry->iLines;iLine++) + { + DrawTextEx(pGfx->GetHDC(), (LPTSTR)pEntry->vLines[iLine].c_str(), pEntry->vLines[iLine].size(), &rBoundary, m_iTextFormat, &m_dtp); + rBoundary.top += m_iFontHeight; + rBoundary.bottom += m_iFontHeight; + iLinesDrawn++; + } + } + iPosition += pEntry->iLines; + } + return true; +} + +//************************************************************************ +// associates a scrollbar with the log +//************************************************************************ +void CLCDTextLog::SetScrollbar(CLCDBar *pScrollbar) +{ + m_pScrollbar = pScrollbar; + if(m_pScrollbar) + { + m_pScrollbar->SetSliderSize(GetHeight()/m_iFontHeight); + m_pScrollbar->SetRange(0,m_iTextLines-1); + m_pScrollbar->ScrollTo(m_iPosition); + m_pScrollbar->SetAlignment(TOP); + } +} + +//************************************************************************ +// sets the autoscrolling mode +//************************************************************************ +void CLCDTextLog::SetAutoscrollMode(EScrollMode eMode) +{ + m_eAutoScroll = eMode; +} + +//************************************************************************ +// sets the expand mode +//************************************************************************ +void CLCDTextLog::SetExpandMode(EExpandMode eMode) +{ + m_eExpandMode = eMode; +} + +//************************************************************************ +// sets the logs text +//************************************************************************ +void CLCDTextLog::SetText(tstring strText) +{ + ClearLog(); + AddText(strText); +} + +//************************************************************************ +// adds some text to the log +//************************************************************************ +void CLCDTextLog::AddText(tstring strText,bool bForceAutoscroll) +{ + CLogEntry *pEntry = new CLogEntry(); + pEntry->strString = strText; + pEntry->iLines = 0; + WrapMessage(pEntry); + m_Entrys.push_back(pEntry); + + if(m_Entrys.size() > m_iLogSize) + { + CLogEntry *pOldestEntry = *(m_Entrys.begin()); + m_Entrys.pop_front(); + + if(m_iPosition >= pOldestEntry->iLines) + m_iPosition -= pOldestEntry->iLines; + else + m_iPosition = 0; + + m_iTextLines -= pOldestEntry->iLines; + + delete pOldestEntry; + } + m_iTextLines += pEntry->iLines; + + // Autoscrolling + if(m_dwLastScroll + 10000 < GetTickCount() || bForceAutoscroll) + { + int iLineCount = (GetHeight()/m_iFontHeight); + if(m_eAutoScroll == SCROLL_LINE) + ScrollTo(m_iTextLines - iLineCount); + else if(m_eAutoScroll == SCROLL_MESSAGE) + ScrollTo(m_iTextLines - pEntry->iLines); + + if(m_eAutoScroll != SCROLL_NONE) + m_iLastScrollDirection = 1; + } + + if(m_pScrollbar) + { + m_pScrollbar->SetRange(0,m_iTextLines-1); + m_pScrollbar->ScrollTo(m_iPosition); + } +} + +//************************************************************************ +// sets the maximum number of log entrys +//************************************************************************ +void CLCDTextLog::SetLogSize(int iSize) +{ + m_iLogSize = iSize; +} + +//************************************************************************ +// clears the log +//************************************************************************ +void CLCDTextLog::ClearLog() +{ + m_dwLastScroll = 0; + + m_iTextLines = 0; + m_iPosition = 0; + CLogEntry *pEvent; + while(!m_Entrys.empty()) + { + pEvent = *(m_Entrys.begin()); + m_Entrys.pop_front(); + delete pEvent; + } + + if(m_pScrollbar) + { + m_pScrollbar->SetRange(0,0); + m_pScrollbar->ScrollTo(0); + } +} + +//************************************************************************ +// scrolls one line up +//************************************************************************ +bool CLCDTextLog::ScrollUp() +{ + if(m_iPosition > 0) + { + m_iPosition--; + if(m_pScrollbar) + m_pScrollbar->ScrollUp(); + + m_dwLastScroll = GetTickCount(); + m_iLastScrollDirection = -1; + return true; + } + return false; +} + +//************************************************************************ +// scrolls one line down +//************************************************************************ +bool CLCDTextLog::ScrollDown() +{ + int iLineCount = (GetHeight()/m_iFontHeight); + + if(m_iPosition < m_iTextLines - iLineCount) + { + m_iPosition++; + if(m_pScrollbar) + m_pScrollbar->ScrollDown(); + + m_iLastScrollDirection = 1; + m_dwLastScroll = GetTickCount(); + return true; + } + return false; +} + +//************************************************************************ +// scrolls to the specified line +//************************************************************************ +bool CLCDTextLog::ScrollTo(int iIndex) +{ + int m_iOldPosition = m_iPosition; + + m_iPosition = iIndex; + + int iLineCount = (GetHeight()/m_iFontHeight); + + if(m_iPosition > m_iTextLines - iLineCount) + m_iPosition = m_iTextLines - iLineCount; + if( m_iPosition < 0) + m_iPosition = 0; + + if(m_pScrollbar) + m_pScrollbar->ScrollTo(m_iPosition); + + bool bRes = m_iOldPosition != m_iPosition; + return bRes; +} + +//************************************************************************ +// wraps the specified log entry +//************************************************************************ +void CLCDTextLog::WrapMessage(CLogEntry *pEntry) +{ + pEntry->iLines = 0; + pEntry->vLines.clear(); + + tstring strString = pEntry->strString; + HDC hDC = CreateCompatibleDC(NULL); + SelectObject(hDC, m_hFont); + + if(NULL == hDC) + return; + + int iLen = strString.size(); + int i = 0; + tstring strLine = _T(""); + tstring strWord = _T(""); + SIZE sizeWord = {0, 0}; + SIZE sizeChar = {0, 0}; + SIZE sizeLine = {0, 0}; + + int *piExtents = new int[strString.length()]; + TCHAR *szString = (TCHAR*)strString.c_str(); + int iMaxChars = 0; + tstring::size_type pos = 0; + + if(GetWidth() == 0) + pEntry->vLines.push_back(strString); + else + { + while(i= i && pos != i+iMaxChars) + iMaxChars = 1 + pos - i; + // if the string doesnt fit, try to wrap the last word to the next line + else if(iMaxChars < iLen - i || sizeLine.cx >= GetWidth()) + { + // find the last space in the line ( substract -1 from offset to ignore spaces as last chars ) + pos = strString.rfind(_T(" "),i + iMaxChars -1 ); + if(pos != tstring::npos && pos != i && pos >= i & pos != i+iMaxChars) + iMaxChars = 1 + pos - i; + } + pEntry->vLines.push_back(strString.substr(i,iMaxChars)); + i += iMaxChars; + } + } + free(piExtents); + /* + while(i<=iLen) + { + if(i != iLen && strString[i] != 13 && strString[i] != 10) + strWord += strString[i]; + + GetTextExtentPoint(hDC,&(strString[i]),1,&sizeChar); + sizeWord.cx += sizeChar.cx; + + if(i == iLen || strString[i] == ' ' || strString[i] == 10) + { + sizeLine.cx += sizeWord.cx; + + strLine += strWord; + strWord = _T(""); + sizeWord.cx = 0; + } + + if(i == iLen || strString[i] == '\n' || sizeLine.cx + sizeWord.cx >= GetWidth()) + { + if(sizeWord.cx >= GetWidth()) + { + strLine += strWord.substr(0,strWord.length()-1); + strWord = strString[i]; + sizeWord.cx = sizeChar.cx; + } + pEntry->vLines.push_back(strLine); + + strLine = _T(""); + sizeLine.cx = 0; + } + i++; + } + */ + DeleteObject(hDC); + + pEntry->iLines = pEntry->vLines.size(); +} + +//************************************************************************ +// called when the logs font has changed +//************************************************************************ +void CLCDTextLog::OnFontChanged() +{ + RefreshLines(); +} + +//************************************************************************ +// called when the logs size has changed +//************************************************************************ +void CLCDTextLog::OnSizeChanged(SIZE OldSize) +{ + // check in which direction the log should expand on height changes + int iLines = GetHeight()/m_iFontHeight; + int iOldLines = OldSize.cy/m_iFontHeight; + + int iPosition =m_iPosition; + + if(m_eExpandMode == EXPAND_UP || (m_eExpandMode == EXPAND_SCROLL && m_iLastScrollDirection == 1)) + iPosition = (m_iPosition + iOldLines) - iLines; + + // revalidate position + ScrollTo(iPosition); + + // update the scrollbar + if(m_pScrollbar) + m_pScrollbar->SetSliderSize(GetHeight()/m_iFontHeight); + + // if the width hasn't changed, return + if(GetWidth() == OldSize.cx) + return; + + RefreshLines(); +} + +//************************************************************************ +// rewraps all textlines +//************************************************************************ +void CLCDTextLog::RefreshLines() +{ + if(m_Entrys.empty()) + return; + + m_iTextLines = 0; + + CLogEntry *pEntry = NULL; + list::iterator iter = m_Entrys.begin(); + while(iter != m_Entrys.end()) + { + pEntry = *(iter); + WrapMessage(pEntry); + m_iTextLines += pEntry->iLines; + iter++; + } + + ScrollTo(m_iPosition); + + SetScrollbar(m_pScrollbar); +} diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDTextLog.h b/plugins/MirandaG15/LCDFramework/src/CLCDTextLog.h new file mode 100644 index 0000000000..312ec8a992 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDTextLog.h @@ -0,0 +1,90 @@ +#ifndef _CLCDTEXTLOG_H_ +#define _CLCDTEXTLOG_H_ + +#include "CLCDTextObject.h" +#include "CLCDBar.h" + + +enum EScrollMode {SCROLL_NONE, SCROLL_MESSAGE,SCROLL_LINE }; +enum EExpandMode { EXPAND_SCROLL, EXPAND_UP,EXPAND_DOWN }; + +class CLCDTextLog : public CLCDTextObject +{ +public: + + + // Constructor + CLCDTextLog(); + // Destructor + ~CLCDTextLog(); + + // Initializes the log + bool Initialize(); + // Deinitializes the log + bool Shutdown(); + + // updates the log + bool Update(); + // draws the log + bool Draw(CLCDGfx *pGfx); + + // sets the logs text + void SetText(tstring strText); + // adds some text to the log + void AddText(tstring strText,bool bForceAutoscroll=false); + // sets the maximum number of log entrys + void SetLogSize(int iSize); + // clears the log + void ClearLog(); + + // scrolls one line up + bool ScrollUp(); + // scrolls one line down + bool ScrollDown(); + // scrolls to the specified line + bool ScrollTo(int iIndex); + + // associates a scrollbar with the log + void SetScrollbar(CLCDBar *pScrollbar); + + // sets the autoscrolling mode + void SetAutoscrollMode(EScrollMode eMode); + // sets the expand mode + void SetExpandMode(EExpandMode eMode); + +protected: + // called when the logs font has changed + void OnFontChanged(); + // called when the logs size has changed + void OnSizeChanged(SIZE OldSize); + + // rewraps all textlines + void RefreshLines(); +private: + // the log entry class + class CLogEntry + { + public: + tstring strString; + int iLines; + vector vLines; + }; + + // wraps the specified log entry + void WrapMessage(CLogEntry *pEntry); + + EScrollMode m_eAutoScroll; + EExpandMode m_eExpandMode; + + int m_iLogSize; + int m_iPosition; + int m_iTextLines; + int m_iLastScrollDirection; + + DWORD m_dwLastScroll; + + list m_Entrys; + CLCDBar *m_pScrollbar; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDTextObject.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDTextObject.cpp new file mode 100644 index 0000000000..1e06d87774 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDTextObject.cpp @@ -0,0 +1,187 @@ +#include "stdafx.h" +#include "CLCDGfx.h" +#include "CLCDObject.h" +#include "CLCDTextObject.h" + +//************************************************************************ +// constructor +//************************************************************************ +CLCDTextObject::CLCDTextObject() +{ + m_hFont = NULL; + m_iFontHeight = 0; + // Initialize DRAWTEXTPARAMS + ZeroMemory(&m_dtp, sizeof(DRAWTEXTPARAMS)); + m_dtp.cbSize = sizeof(DRAWTEXTPARAMS); + // Initialize alignment + m_iTextFormat = m_iTextAlignment = (DT_LEFT | DT_NOPREFIX); +} + +//************************************************************************ +// destructor +//************************************************************************ +CLCDTextObject::~CLCDTextObject() +{ + if(m_hFont) + { + DeleteObject(m_hFont); + } +} + +//************************************************************************ +// initializes the textobject +//************************************************************************ +bool CLCDTextObject::Initialize() +{ + m_hFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT); + if(NULL != m_hFont) + { + SetFontFaceName(_T("Small Fonts")); + SetFontPointSize(6); + } + return true; +} + +//************************************************************************ +// deinitializes the textobject +//************************************************************************ +bool CLCDTextObject::Shutdown() +{ + return true; +} + +//************************************************************************ +// draws the textobject +//************************************************************************ +bool CLCDTextObject::Draw(CLCDGfx *pGfx) +{ + return true; +} + +//************************************************************************ +// updates the textobject +//************************************************************************ +bool CLCDTextObject::Update() +{ + return true; +} + +//************************************************************************ +// sets the textobject's font +//************************************************************************ +bool CLCDTextObject::SetFont(LOGFONT& lf) +{ + if (m_hFont) + { + DeleteObject(m_hFont); + m_hFont = NULL; + } + + m_hFont = CreateFontIndirect(&lf); + + if(!m_hFont) + return false; + + // Calculate the font's height + HDC hDC = CreateCompatibleDC(NULL); + SelectObject(hDC, m_hFont); + TEXTMETRIC tmFontInfo; + + GetTextMetrics(hDC,&tmFontInfo); + m_iFontHeight = tmFontInfo.tmHeight; + + DeleteObject(hDC); + + OnFontChanged(); + + return true; +} + +//************************************************************************ +// sets the textobject's font's facename +//************************************************************************ +void CLCDTextObject::SetFontFaceName(tstring strFontName) +{ + // if NULL, uses the default gui font + if (strFontName.empty()) + return; + + LOGFONT lf; + ZeroMemory(&lf, sizeof(lf)); + GetObject(m_hFont, sizeof(LOGFONT), &lf); + + _tcsncpy(lf.lfFaceName, strFontName.c_str(), LF_FACESIZE); + + SetFont(lf); +} + +//************************************************************************ +// sets the textobject's font's point size +//************************************************************************ +void CLCDTextObject::SetFontPointSize(int nPointSize) +{ + LOGFONT lf; + ZeroMemory(&lf, sizeof(lf)); + GetObject(m_hFont, sizeof(LOGFONT), &lf); + + lf.lfHeight = -MulDiv(nPointSize, 96, 72); + + SetFont(lf); +} + +//************************************************************************ +// sets the textobject's font to italic +//************************************************************************ +void CLCDTextObject::SetFontItalic(bool flag) { + LOGFONT lf; + ZeroMemory(&lf, sizeof(lf)); + GetObject(m_hFont, sizeof(LOGFONT), &lf); + + lf.lfItalic = flag; + + SetFont(lf); +} + +//************************************************************************ +// sets the textobject's font's weight +//************************************************************************ +void CLCDTextObject::SetFontWeight(int nWeight) +{ + LOGFONT lf; + ZeroMemory(&lf, sizeof(lf)); + GetObject(m_hFont, sizeof(LOGFONT), &lf); + + lf.lfWeight = nWeight; + + SetFont(lf); +} + +//************************************************************************ +// sets the textobject's alignment +//************************************************************************ +void CLCDTextObject::SetAlignment(int iAlignment) +{ + m_iTextFormat &= ~m_iTextAlignment; + m_iTextFormat |= iAlignment; + m_iTextAlignment = iAlignment; +} + +//************************************************************************ +// sets the textobject's wordwrap mode +//************************************************************************ +void CLCDTextObject::SetWordWrap(bool bWrap) +{ + m_bWordWrap = bWrap; + if (bWrap) + m_iTextFormat |= DT_WORDBREAK; + else + m_iTextFormat &= ~DT_WORDBREAK; +} + +//************************************************************************ +// called when the textobject's font has changed +//************************************************************************ +void CLCDTextObject::OnFontChanged() +{ + +} diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDTextObject.h b/plugins/MirandaG15/LCDFramework/src/CLCDTextObject.h new file mode 100644 index 0000000000..ddc32c5eac --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDTextObject.h @@ -0,0 +1,53 @@ +#ifndef _CLCDTextObject_H_ +#define _CLCDTextObject_H_ + +#include "CLCDObject.h" + +class CLCDTextObject : public CLCDObject +{ +public: + // constructor + CLCDTextObject(); + // destructor + ~CLCDTextObject(); + + // initializes the textobject + bool Initialize(); + // deinitializes the textobject + bool Shutdown(); + + // sets the textobject's font + bool SetFont(LOGFONT& lf); + // sets the textobject's font's facename + void SetFontFaceName(tstring strFontName); + // sets the textobject's font's pointsize + void SetFontPointSize(int nPointSize); + // sets the textobject's font's weight + void SetFontWeight(int nWeight); + // sets the textobject's font's italic flag + void SetFontItalic(bool flag); + + // sets the textobject's alignment + void SetAlignment(int iAlignment); + // sets the textobject's wordwrap mode + void SetWordWrap(bool bWrap); + + // draws the textobject + bool Draw(CLCDGfx *pGfx); + // updates the textobject + bool Update(); + +protected: + virtual void OnFontChanged(); + +protected: + bool m_bWordWrap; + + HFONT m_hFont; + int m_iFontHeight; + DRAWTEXTPARAMS m_dtp; + UINT m_iTextFormat; + UINT m_iTextAlignment; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/ConStream.cpp b/plugins/MirandaG15/LCDFramework/src/ConStream.cpp new file mode 100644 index 0000000000..98b3f5c921 Binary files /dev/null and b/plugins/MirandaG15/LCDFramework/src/ConStream.cpp differ diff --git a/plugins/MirandaG15/LCDFramework/src/ConStream.h b/plugins/MirandaG15/LCDFramework/src/ConStream.h new file mode 100644 index 0000000000..78664316e8 Binary files /dev/null and b/plugins/MirandaG15/LCDFramework/src/ConStream.h differ diff --git a/plugins/MirandaG15/LCDFramework/src/LCDFramework.h b/plugins/MirandaG15/LCDFramework/src/LCDFramework.h new file mode 100644 index 0000000000..cdc9c44a05 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/LCDFramework.h @@ -0,0 +1,20 @@ +#ifndef _LCDFRAMEWORK_H +#define _LCDFRAMEWORK_H + +// HID Includes +#include +extern "C" +{ +#include "../hid/hidsdi.h" +} + +#ifdef _UNICODE +#define tstring wstring +#else +#define tstring string +#endif + +#include "debug.h" +#include "misc.h" + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/LCDObject.cpp b/plugins/MirandaG15/LCDFramework/src/LCDObject.cpp new file mode 100644 index 0000000000..2fe0319ca3 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/LCDObject.cpp @@ -0,0 +1,137 @@ +#include "stdafx.h" +#include "CLCDGfx.h" +#include "CLCDObject.h" + +//************************************************************************ +// Constructor +//************************************************************************ +CLCDObject::CLCDObject() +{ + m_Size.cx = 0; + m_Size.cy = 0; + m_Origin.x = 0; + m_Origin.y = 0; + m_bShow = true; +} + +//************************************************************************ +// Destructor +//************************************************************************ +CLCDObject::~CLCDObject() +{ +} + +//************************************************************************ +// Initialize the object +//************************************************************************ +bool CLCDObject::Initialize() +{ + return false; +} + +//************************************************************************ +// Shutdown the object +//************************************************************************ +bool CLCDObject::Shutdown() +{ + return false; +} + +//************************************************************************ +// Set the origin of the object +//************************************************************************ +void CLCDObject::SetOrigin(int iX,int iY) +{ + m_Origin.x = iX; + m_Origin.y = iY; +} + +void CLCDObject::SetOrigin(POINT p) +{ + m_Origin = p; +} + +//************************************************************************ +// Get the origin of the object +//************************************************************************ +POINT CLCDObject::GetOrigin() +{ + return m_Origin; +} + +//************************************************************************ +// Set the size of the object +//************************************************************************ +void CLCDObject::SetSize(int iWidth,int iHeight) +{ + SIZE OldSize = m_Size; + m_Size.cx = iWidth; + m_Size.cy = iHeight; + OnSizeChanged(OldSize); +} + +void CLCDObject::SetSize(SIZE s) +{ + SIZE OldSize = m_Size; + m_Size = s; + OnSizeChanged(OldSize); +} + +//************************************************************************ +// Get the size of the object +//************************************************************************ +SIZE CLCDObject::GetSize() +{ + return m_Size; +} + +int CLCDObject::GetWidth() +{ + return m_Size.cx; +} + +int CLCDObject::GetHeight() +{ + return m_Size.cy; +} + +//************************************************************************ +// Set the visibility +//************************************************************************ +void CLCDObject::Show(bool bShow) +{ + m_bShow = bShow; +} + +//************************************************************************ +// Check the visibility +//************************************************************************ +bool CLCDObject::IsVisible() +{ + return m_bShow; +} + +//************************************************************************ +// Update the object +//************************************************************************ +bool CLCDObject::Update() +{ + return true; +} + + +//************************************************************************ +// Draw the object +//************************************************************************ +bool CLCDObject::Draw(CLCDGfx *pGfx) +{ + return true; +} + +//************************************************************************ +// Called when the size of the object changed +//************************************************************************ +void CLCDObject::OnSizeChanged(SIZE OldSize) +{ + +} \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/debug.cpp b/plugins/MirandaG15/LCDFramework/src/debug.cpp new file mode 100644 index 0000000000..abca919bfe --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/debug.cpp @@ -0,0 +1,58 @@ +#include "stdafx.h" + +//file debug.cpp +#ifdef _DEBUG + +#ifdef USECONSTREAM + ConStream g_ConStream; + + void InitDebug() + { + g_ConStream.Open(); + } + + void UnInitDebug() + { + g_ConStream.Close(); + } +#else + void InitDebug() + { + } + + void UnInitDebug() + { + } +#endif + +void _trace(TCHAR *fmt, ...) +{ + TCHAR out[1024]; + va_list body; + va_start(body, fmt); +#ifdef _UNICODE + vswprintf(out, fmt, body); +#else + vsprintf(out,fmt,body); +#endif + + va_end(body); +#ifdef USECONSTREAM + g_ConStream << out; +#else + OutputDebugString(out); +#endif + +} +#else + +void InitDebug() +{ +} + +void UnInitDebug() +{ +} + +#endif + diff --git a/plugins/MirandaG15/LCDFramework/src/debug.h b/plugins/MirandaG15/LCDFramework/src/debug.h new file mode 100644 index 0000000000..39e34ebaae --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/debug.h @@ -0,0 +1,21 @@ +#ifndef _DEBUG_H_ +#define _DEBUG_H_ + +#define USECONSTREAM 1 + +extern void InitDebug(); +extern void UnInitDebug(); + + +#ifdef _DEBUG +#ifdef USECONSTREAM + #include "ConStream.h" +#endif +#define TRACE _trace +extern void _trace(TCHAR *fmt, ...); +#else +inline void _trace(LPCTSTR fmt, ...) { } +#define TRACE 1 ? (void)0 : _trace +#endif + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/misc.cpp b/plugins/MirandaG15/LCDFramework/src/misc.cpp new file mode 100644 index 0000000000..3e861fb529 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/misc.cpp @@ -0,0 +1,217 @@ +/* -------------------------------------------------------------------- */ +#include "StdAfx.h" + +tstring tstringprintf(tstring strFormat,...) { + va_list vlist; + + va_start(vlist, strFormat); + + int mlen = (int)strFormat.length()+128; + TCHAR *text = (TCHAR*)malloc(mlen*sizeof(TCHAR)); + _vsntprintf(text,mlen,strFormat.c_str(),vlist); + va_end(vlist); + + strFormat = text; + free(text); + + return strFormat; +} + +// Returns true if the unicode buffer only contains 7-bit characters. +BOOL IsUnicodeAscii(const wchar_t* pBuffer, int nSize) +{ + BOOL bResult = TRUE; + int nIndex; + + for (nIndex = 0; nIndex < nSize; nIndex++) { + if (pBuffer[nIndex] > 0x7F) { + bResult = FALSE; + break; + } + } + return bResult; +} + + +wstring +toWideString( const char* pStr , int len ) +{ + if ( pStr == NULL ) + return L"" ; + + //ASSERT_PTR( pStr ) ; + ASSERT( len >= 0 || len == -1 , _T("Invalid string length: ") << len ) ; + + // figure out how many wide characters we are going to get + int nChars = MultiByteToWideChar( CP_ACP , 0 , pStr , len , NULL , 0 ) ; + if ( len == -1 ) + -- nChars ; + if ( nChars == 0 ) + return L"" ; + + // convert the narrow string to a wide string + // nb: slightly naughty to write directly into the string like this + wstring buf ; + buf.resize( nChars ) ; + MultiByteToWideChar( CP_ACP , 0 , pStr , len , + const_cast(buf.c_str()) , nChars ) ; + + return buf ; +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +string +toNarrowString( const wchar_t* pStr , int len ) +{ + //ASSERT_PTR( pStr ) ; + ASSERT( len >= 0 || len == -1 , _T("Invalid string length: ") << len ) ; + + // figure out how many narrow characters we are going to get + int nChars = WideCharToMultiByte( CP_ACP , 0 , + pStr , len , NULL , 0 , NULL , NULL ) ; + if ( len == -1 ) + -- nChars ; + if ( nChars == 0 ) + return "" ; + + // convert the wide string to a narrow string + // nb: slightly naughty to write directly into the string like this + string buf ; + buf.resize( nChars ) ; + char *test = (char*)malloc((nChars+1)*sizeof(char)); + WideCharToMultiByte( CP_ACP , 0 , pStr , len , + const_cast(buf.c_str()), nChars , NULL , NULL ) ; + + return buf ; +} + +/// get lower string +tstring toLower(const tstring &i_str) +{ + tstring str(i_str); + for (size_t i = 0; i < str.size(); ++ i) + { + if (_istlead(str[i])) + ++ i; + else + str[i] = tolower(str[i]); + } + return str; +} + +/* + * decodes UTF-8 to unicode + * taken from jabber protocol implementation and slightly modified + * free() the return value + */ + +#if defined(_UNICODE) + + +tstring Utf8_Decode(const char *str) +{ + tstring strRes = _T(""); + + int i, len; + char *p; + WCHAR *wszTemp = NULL; + + if (str == NULL) + return strRes; + + len = strlen(str); + + if ((wszTemp = (WCHAR *) malloc(sizeof(TCHAR) * (len + 2))) == NULL) + return strRes; + + p = (char *) str; + i = 0; + while (*p) { + if ((*p & 0x80) == 0) + wszTemp[i++] = *(p++); + else if ((*p & 0xe0) == 0xe0) { + wszTemp[i] = (*(p++) & 0x1f) << 12; + wszTemp[i] |= (*(p++) & 0x3f) << 6; + wszTemp[i++] |= (*(p++) & 0x3f); + } + else { + wszTemp[i] = (*(p++) & 0x3f) << 6; + wszTemp[i++] |= (*(p++) & 0x3f); + } + } + wszTemp[i] = (TCHAR)'\0'; + + strRes = wszTemp; + free(wszTemp); + return strRes; +} + +/* + * convert unicode to UTF-8 + * code taken from jabber protocol implementation and slightly modified. + * free() the return value + */ + +string Utf8_Encode(const WCHAR *str) +{ + string strRes = ""; + + unsigned char *szOut = NULL; + int len, i; + const WCHAR *wszTemp, *w; + + if (str == NULL) + return strRes; + + wszTemp = str; + + // Convert unicode to utf8 + len = 0; + for (w=wszTemp; *w; w++) { + if (*w < 0x0080) len++; + else if (*w < 0x0800) len += 2; + else len += 3; + } + + if ((szOut = (unsigned char *) malloc(len + 2)) == NULL) + return strRes; + + i = 0; + for (w=wszTemp; *w; w++) { + if (*w < 0x0080) + szOut[i++] = (unsigned char) *w; + else if (*w < 0x0800) { + szOut[i++] = 0xc0 | ((*w) >> 6); + szOut[i++] = 0x80 | ((*w) & 0x3f); + } + else { + szOut[i++] = 0xe0 | ((*w) >> 12); + szOut[i++] = 0x80 | (((*w) >> 6) & 0x3f); + szOut[i++] = 0x80 | ((*w) & 0x3f); + } + } + szOut[i] = '\0'; + strRes = (char *) szOut; + free(szOut); + return strRes; +} + +#endif + + +// Zufallszahlen +int GetRandomInt(int iMin, int iMax) +{ + double r = ((double)rand() / (RAND_MAX +1)); + + int iRes = r*(iMax + 1- iMin) + iMin; + if(iRes > iMax) + Sleep(1); + return iRes; +} + +double GetRandomDouble() +{ + return ((double)rand() / (RAND_MAX +1)); +} \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/misc.h b/plugins/MirandaG15/LCDFramework/src/misc.h new file mode 100644 index 0000000000..43e35327c5 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/misc.h @@ -0,0 +1,97 @@ +extern BOOL IsUnicodeAscii(const wchar_t* pBuffer, int nSize); +extern tstring toLower(const tstring &i_str); + +extern std::wstring toWideString( const char* pStr , int len=-1 ) ; +inline std::wstring toWideString( const std::string& str ) +{ + return toWideString(str.c_str(),str.length()) ; +} +inline std::wstring toWideString( const wchar_t* pStr , int len=-1 ) +{ + return (len < 0) ? pStr : std::wstring(pStr,len) ; +} +inline std::wstring toWideString( const std::wstring& str ) +{ + return str ; +} +extern std::string toNarrowString( const wchar_t* pStr , int len=-1 ) ; +inline std::string toNarrowString( const std::wstring& str ) +{ + return toNarrowString(str.c_str(),str.length()) ; +} +inline std::string toNarrowString( const char* pStr , int len=-1 ) +{ + return (len < 0) ? pStr : std::string(pStr,len) ; +} +inline std::string toNarrowString( const std::string& str ) +{ + return str ; +} + +#ifdef _UNICODE + #define tstring wstring + inline TCHAR toTchar( char ch ) + { + return (wchar_t)ch ; + } + inline TCHAR toTchar( wchar_t ch ) + { + return ch ; + } + inline std::tstring toTstring( const std::string& s ) + { + return toWideString(s) ; + } + inline std::tstring toTstring( const char* p , int len=-1 ) + { + return toWideString(p,len) ; + } + inline std::tstring toTstring( const std::wstring& s ) + { + return s ; + } + inline std::tstring toTstring( const wchar_t* p , int len=-1 ) + { + return p == NULL?L"":((len < 0) ? p : std::wstring(p,len)); + } + + extern tstring Utf8_Decode(const char *str); + +// extern WCHAR *Utf8_Decode(const char *str); + extern string Utf8_Encode(const WCHAR *str); +#else + #define tstring string + inline TCHAR toTchar( char ch ) + { + return ch ; + } + inline TCHAR toTchar( wchar_t ch ) + { + return (ch >= 0 && ch <= 0xFF) ? (char)ch : '?' ; + } + inline std::tstring toTstring( const std::string& s ) + { + return s ; + } + inline std::tstring toTstring( const char* p , int len=-1 ) + { + if(p == NULL) + return ""; + return (len < 0) ? p : std::string(p,len) ; + } + inline std::tstring toTstring( const std::wstring& s ) + { + return toNarrowString(s) ; + } + inline std::tstring toTstring( const wchar_t* p , int len=-1 ) + { + return toNarrowString(p,len) ; + } +#endif // _UNICODE + + // Zufallszahlen + +extern int GetRandomInt(int iMin, int iMax); +extern double GetRandomDouble(); + +extern tstring tstringprintf(tstring strFormat,...); \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/stdafx.h b/plugins/MirandaG15/LCDFramework/src/stdafx.h new file mode 100644 index 0000000000..8830f34250 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/stdafx.h @@ -0,0 +1,33 @@ +#ifndef _STDAFX_H_ +#define _STDAFX_H_ + +#include + +#define ASSERT assert + +#define _WIN32_WINNT 0x0500 // Needed for waitable timers +#include +#include +#include +#include +#include +#include +using namespace std; + +#ifdef _UNICODE + #define tstring wstring +#else + #define tstring string +#endif + +#include "debug.h" +#include "misc.h" + +// HID Includes +#include +extern "C" +{ +#include "hidsdi.h" +} + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/todo.txt b/plugins/MirandaG15/LCDFramework/todo.txt new file mode 100644 index 0000000000..868788c685 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/todo.txt @@ -0,0 +1,8 @@ +wordwrapping rewrite mit gettextextentextpoint + +Icon + +Kommentare für CLCDInput und CLCDOutputManager + +kommentarsystem ändern +Outputmanager ggf umbenennen? diff --git a/plugins/MirandaG15/MirandaG15.aps b/plugins/MirandaG15/MirandaG15.aps new file mode 100644 index 0000000000..9ef951b920 Binary files /dev/null and b/plugins/MirandaG15/MirandaG15.aps differ diff --git a/plugins/MirandaG15/MirandaG15.rc b/plugins/MirandaG15/MirandaG15.rc new file mode 100644 index 0000000000..bd0ddcc822 --- /dev/null +++ b/plugins/MirandaG15/MirandaG15.rc @@ -0,0 +1,348 @@ +#define APSTUDIO_READONLY_SYMBOLS 0 +#define IDB_BACK 1 +#define IDB_CHAT 2 +#define IDB_CLIST 3 +#define IDB_DOWN 4 +#define IDB_EDIT 5 +#define IDB_HISTORY 6 +#define IDB_MINUS 7 +#define IDB_OPEN 8 +#define IDB_PLUS 9 +#define IDB_PREV 10 +#define IDB_REPLY 11 +#define IDB_SEND 12 +#define IDB_UP 13 +#define IDI_NOTICK 14 +#define IDI_TICK 15 +#define IDB_NEXT 16 +#define IDB_STATUS_OFFLINE 17 +#define IDB_STATUS_ONLINE 18 +#define IDB_STATUS_AWAY 19 +#define IDB_STATUS_NA 20 +#define IDB_STATUS_OCCUPIED 21 +#define IDB_STATUS_DND 22 +#define IDB_STATUS_INVISIBLE 23 +#define IDB_STATUS_FFC 24 +#define IDB_EVENT_INFO 25 +#define IDB_EVENT_CON 26 +#define IDB_EVENT_USER 27 +#define IDB_EVENT_MSG 28 +#define IDB_EVENT_INFO_LARGE 29 +#define IDB_EVENT_CON_LARGE 30 +#define IDB_EVENT_USER_LARGE 31 +#define IDB_EVENT_MSG_LARGE 32 +#define IDD_FONTS 102 +#define IDC_STATIC11 3000 +#define IDC_STATIC12 3002 +#define IDC_GRP3 3024 +#define IDC_SHOW_LABELS 3001 +#define IDC_STATIC13 3003 +#define IDC_SAMPLE1 3004 +#define IDC_CHOOSEFONT1 3005 +#define IDC_STATIC15 3006 +#define IDC_SAMPLE2 3007 +#define IDC_CHOOSEFONT2 3008 +#define IDC_STATIC17 3009 +#define IDC_SAMPLE3 3010 +#define IDC_CHOOSEFONT3 3011 +#define IDC_STATIC14 3012 +#define IDC_SAMPLE4 3013 +#define IDC_CHOOSEFONT4 3014 +#define IDC_STATIC16 3015 +#define IDC_SAMPLE5 3016 +#define IDC_CHOOSEFONT5 3017 +#define IDC_CONTROL_BACKLIGHTS 3018 +#define IDC_STC2 3019 +#define IDC_HOOK_VOLUMEWHEEL 3020 +#define IDC_TIMESTAMP_SECONDS 3021 +#define IDC_TRANSITIONS 3022 +#define IDC_CREDITS 3023 +#define IDC_STC6 3025 +#define IDC_STC7 3026 +#define IDC_STC8 3027 +#define IDC_STC9 3028 +#define IDC_STC10 3029 +#define IDC_DEVICE 3151 +#define IDC_DEVICE_STATIC 3150 +#define IDC_STC14 103 +#define IDC_SCREENSAVER_LOCK 3998 +#define IDC_SKIP_DRIVER_ERROR 3040 +#define IDD_NOTIFICATIONS 103 +#define IDC_STATIC18 4000 +#define IDC_STATIC19 4007 +#define IDC_NOTIFY_TITLEHIDE 4008 +#define IDC_NOTIFY_TITLENAME 4009 +#define IDC_NOTIFY_TITLEINFO 4010 +#define IDC_STATIC20 4001 +#define IDC_STATIC22 4004 +#define IDC_NOTIFY_LOGSIZE 4002 +#define IDC_NOTIFY_DURATION 4005 +#define IDC_STATIC21 4003 +#define IDC_STATIC23 4006 +#define IDC_STATIC24 4011 +#define IDC_NOTIFY_MESSAGES 4014 +#define IDC_NOTIFY_SIGNOFF 4016 +#define IDC_NOTIFY_STATUS 4017 +#define IDC_NOTIFY_URL 4023 +#define IDC_NOTIFY_CONTACTS 4018 +#define IDC_NOTIFY_FILE 4019 +#define IDC_NOTIFY_PROTO_SIGNOFF 4020 +#define IDC_NOTIFY_PROTO_SIGNON 4021 +#define IDC_NOTIFY_PROTO_STATUS 4022 +#define IDC_STATIC25 4012 +#define IDC_NOTIFY_SIGNON 4015 +#define IDC_PROTOCOLS 4013 +#define IDC_NOTIFY_SKIP_MESSAGES 4024 +#define IDC_STC3 4030 +#define IDC_NOTIFY_SKIP_STATUS 4025 +#define IDC_GRP1 4026 +#define IDC_NOTIFY_SKIP_SIGNON 4027 +#define IDC_NOTIFY_SKIP_SIGNOFF 4028 +#define IDC_NOTIFY_TIMESTAMPS 4029 +#define IDC_NOTIFY_IRC_MESSAGES 4031 +#define IDC_NOTIFY_IRC_USERS 4032 +#define IDC_NOTIFY_IRC_EMOTES 4033 +#define IDC_NOTIFY_IRC_STATUS 4034 +#define IDC_STC4 4035 +#define IDC_NOTIFY_IRC_NOTICES 4036 +#define IDC_NOTIFY_IRC_CHANNEL 4037 +#define IDC_NOTIFY_NICKCUTOFF 4038 +#define IDC_NOTIFY_NICKCUTOFF_OFFSET 4039 +#define IDC_STC11 4040 +#define IDC_NOTIFY_SHOWPROTO 4045 +#define IDC_NOTIFY_NO_SKIP_REPLY 4041 +#define IDC_STC12 4042 +#define IDC_STC13 104 +#define IDC_NOTIFY_CHANNELCUTOFF 105 +#define IDC_NOTIFY_CHANNELCUTOFF_OFFSET 106 +#define IDD_CLIST 1001 +#define IDC_STATIC9 2000 +#define IDC_CLIST_SHOWPROTO 2001 +#define IDC_CLIST_HIDEOFFLINE 2002 +#define IDC_CLIST_USEIGNORE 2003 +#define IDC_CLIST_USEGROUPS 2004 +#define IDC_STATIC10 2005 +#define IDC_CLIST_DRAWLINES 2006 +#define IDC_CLIST_COUNTERS 2007 +#define IDC_CLIST_POSITION 2008 +#define IDC_STC1 2009 +#define IDC_CLIST_GA_NONE 2010 +#define IDC_CLIST_GA_COLLAPSE 2011 +#define IDC_STC5 2014 +#define IDC_CLIST_PROTOFILTER 2013 +#define IDC_GRP2 2015 +#define IDC_CLIST_GA_EXPAND 2012 +#define IDC_CLIST_COLUMNS 2016 +#define IDC_CLIST_SELECTION 2999 +#define IDD_CHAT 100 +#define IDC_STATIC1 1000 +#define IDC_SESSION_SHOWTYPING 1001 +#define IDC_SESSION_SENDTYPING 1002 +#define IDC_STATIC2 1003 +#define IDC_STATIC3 1004 +#define IDC_MAXIMIZED_TITLE 1005 +#define IDC_MAXIMIZED_LABELS 1006 +#define IDC_STATIC4 1007 +#define IDC_SESSION_LOADDB 1008 +#define IDC_SESSION_MARKREAD 1009 +#define IDC_SESSION_SCROLL_MAXIMIZED 1010 +#define IDC_STATIC6 1011 +#define IDC_SESSION_LOGSIZE 1012 +#define IDC_STATIC5 1013 +#define IDC_STATIC8 1014 +#define IDC_SESSION_SCROLLNONE 1015 +#define IDC_SESSION_SCROLLFIRST 1016 +#define IDC_SESSION_SCROLLLAST 1017 +#define IDC_STATIC7 1018 +#define IDC_SESSION_SYMBOLS 1019 +#define IDC_SESSION_SENDRETURN 1020 +#define IDC_SESSION_REPLY_MAXIMIZED 1021 +#define IDC_SESSION_TIMESTAMPS 1022 +#define IDC_SESSION_CLOSE 1051 +#define IDC_SESSION_CLOSETIMER 1052 +#define IDC_STC16 1053 +#define IDC_GRP4 1050 +#include "resource.h" +IDB_BACK BITMAP DISCARDABLE "data/back.bmp" +IDB_CHAT BITMAP DISCARDABLE "data/chat.bmp" +IDB_CLIST BITMAP DISCARDABLE "data/clist.bmp" +IDB_DOWN BITMAP DISCARDABLE "data/down.bmp" +IDB_EDIT BITMAP DISCARDABLE "data/edit.bmp" +IDB_HISTORY BITMAP DISCARDABLE "data/hist.bmp" +IDB_MINUS BITMAP DISCARDABLE "data/minus.bmp" +IDB_OPEN BITMAP DISCARDABLE "data/open.bmp" +IDB_PLUS BITMAP DISCARDABLE "data/plus.bmp" +IDB_PREV BITMAP DISCARDABLE "data/prev.bmp" +IDB_REPLY BITMAP DISCARDABLE "data/reply.bmp" +IDB_SEND BITMAP DISCARDABLE "data/send.bmp" +IDB_UP BITMAP DISCARDABLE "data/up.bmp" +IDI_NOTICK ICON DISCARDABLE "data/notick.ico" +IDI_TICK ICON DISCARDABLE "data/tick.ico" +IDB_NEXT BITMAP DISCARDABLE "data/next.bmp" +IDB_STATUS_OFFLINE BITMAP DISCARDABLE "data/status/off.bmp" +IDB_STATUS_ONLINE BITMAP DISCARDABLE "data/status/on.bmp" +IDB_STATUS_AWAY BITMAP DISCARDABLE "data/status/away.bmp" +IDB_STATUS_NA BITMAP DISCARDABLE "data/status/na.bmp" +IDB_STATUS_OCCUPIED BITMAP DISCARDABLE "data/status/occ.bmp" +IDB_STATUS_DND BITMAP DISCARDABLE "data/status/dnd.bmp" +IDB_STATUS_INVISIBLE BITMAP DISCARDABLE "data/status/invis.bmp" +IDB_STATUS_FFC BITMAP DISCARDABLE "data/status/ffc.bmp" +IDB_EVENT_INFO BITMAP DISCARDABLE "data/events/info.bmp" +IDB_EVENT_CON BITMAP DISCARDABLE "data/events/conn.bmp" +IDB_EVENT_USER BITMAP DISCARDABLE "data/events/user.bmp" +IDB_EVENT_MSG BITMAP DISCARDABLE "data/events/msg.bmp" +IDB_EVENT_INFO_LARGE BITMAP DISCARDABLE "data/events/info_large.bmp" +IDB_EVENT_CON_LARGE BITMAP DISCARDABLE "data/events/conn_large.bmp" +IDB_EVENT_USER_LARGE BITMAP DISCARDABLE "data/events/user_large.bmp" +IDB_EVENT_MSG_LARGE BITMAP DISCARDABLE "data/events/msg_large.bmp" +IDD_FONTS DIALOGEX 0,0,302,244 +CAPTION "Fonts" +FONT 8,"MS Shell Dlg",400,0,1 +STYLE 0x80C00048 +BEGIN + CONTROL "General settings",IDC_STATIC11,"Button",0x50000007,0,0,300,111 + CONTROL "Show softkey labels",IDC_SHOW_LABELS,"Button",0x50010003,6,22,118,13 + CONTROL "Fonts",IDC_STATIC12,"Button",0x50000007,0,112,300,85 + CONTROL "Event log:",IDC_STATIC13,"Static",0x50020000,10,121,72,9 + CONTROL "Sample",IDC_SAMPLE1,"Static",0x50820201,10,131,72,13 + CONTROL "...",IDC_CHOOSEFONT1,"Button",0x50010000,88,131,18,13 + CONTROL "Message log:",IDC_STATIC15,"Static",0x50020000,10,147,72,9 + CONTROL "Sample",IDC_SAMPLE2,"Static",0x50820201,10,156,72,13 + CONTROL "...",IDC_CHOOSEFONT2,"Button",0x50010000,88,156,18,13 + CONTROL "Contactlist:",IDC_STATIC17,"Static",0x50020000,10,171,72,9 + CONTROL "Sample",IDC_SAMPLE3,"Static",0x50820201,10,180,72,13 + CONTROL "...",IDC_CHOOSEFONT3,"Button",0x50010000,88,180,18,13 + CONTROL "Titles:",IDC_STATIC14,"Static",0x50020000,130,121,72,9 + CONTROL "Sample",IDC_SAMPLE4,"Static",0x50820201,130,131,72,13 + CONTROL "...",IDC_CHOOSEFONT4,"Button",0x50010000,208,131,18,13 + CONTROL "Notifications:",IDC_STATIC16,"Static",0x50020000,130,147,72,9 + CONTROL "Sample",IDC_SAMPLE5,"Static",0x50820201,130,156,72,13 + CONTROL "...",IDC_CHOOSEFONT5,"Button",0x50010000,208,156,18,13 + CONTROL "Turn off backlights",IDC_CONTROL_BACKLIGHTS,"Button",0x50010003,14,60,126,9 + CONTROL "If the applet is active:",IDC_STC2,"Static",0x50000000,6,79,124,9 + CONTROL "Use the VolumeWheel to scroll up and down (might affect system performance)",IDC_HOOK_VOLUMEWHEEL,"Button",0x50010003,14,88,266,9 + CONTROL "Show seconds in timestamps",IDC_TIMESTAMP_SECONDS,"Button",0x50010003,6,33,124,9 + CONTROL "Use transition effects when changing screens",IDC_TRANSITIONS,"Button",0x50010003,14,97,164,9 + CONTROL "Credits",IDC_CREDITS,"Button",0x50010000,110,230,90,11 + CONTROL "About",IDC_GRP3,"Button",0x50000007,0,199,300,44 + CONTROL "Mirandag15 + TrillianG15",IDC_STC6,"Static",0x50000201,80,204,136,8 + CONTROL "For updates and news check the thread on http://www.g15forums.com",IDC_STC7,"Static",0x50000001,2,212,292,9 + CONTROL "Or visit http://www.mkleinhans.de",IDC_STC8,"Static",0x50000001,2,221,290,8 + CONTROL "mail@mkleinhans.de",IDC_STC9,"Static",0x50000000,232,232,66,9 + CONTROL "© 2006 by Martin Kleinhans",IDC_STC10,"Static",0x50000000,2,232,90,9 + CONTROL "",IDC_DEVICE,"ComboBox",0x50010003,42,9,80,11 + CONTROL "Device:",IDC_DEVICE_STATIC,"Static",0x50000000,8,11,32,9 + CONTROL "If the screensaver is active:",IDC_STC14,"Static",0x50000000,6,51,124,9 + CONTROL "Lock the Screen",IDC_SCREENSAVER_LOCK,"Button",0x50010003,14,70,126,9 + CONTROL "Skip driver missing notification",IDC_SKIP_DRIVER_ERROR,"Button",0x50010003,6,42,112,9 +END +IDD_NOTIFICATIONS DIALOGEX 0,0,304,240 +CAPTION "Notifications" +FONT 8,"MS Shell Dlg",400,0,1 +STYLE 0x80C80048 +BEGIN + CONTROL "General settings",IDC_STATIC18,"Button",0x50000007,0,0,160,80 + CONTROL "Notification screen title",IDC_STATIC19,"Button",0x50000007,0,81,160,43 + CONTROL "Hide it",IDC_NOTIFY_TITLEHIDE,"Button",0x50010009,12,88,114,13 + CONTROL "Show the plugin name",IDC_NOTIFY_TITLENAME,"Button",0x50010009,12,99,114,11 + CONTROL "Show a short event summary",IDC_NOTIFY_TITLEINFO,"Button",0x50010009,12,110,114,11 + CONTROL "Size of the log",IDC_STATIC20,"Static",0x50020000,6,22,84,9 + CONTROL "Notification duration",IDC_STATIC22,"Static",0x50020000,6,33,86,11 + CONTROL "",IDC_NOTIFY_LOGSIZE,"Edit",0x50012080,102,20,22,11,0x00000200 + CONTROL "",IDC_NOTIFY_DURATION,"Edit",0x50012080,102,33,22,11,0x00000200 + CONTROL "events",IDC_STATIC21,"Static",0x50020000,126,22,24,13 + CONTROL "seconds",IDC_STATIC23,"Static",0x50020000,126,35,30,11 + CONTROL "Notification types",IDC_STATIC24,"Button",0x50000007,0,125,300,113 + CONTROL "Incoming messages",IDC_NOTIFY_MESSAGES,"Button",0x50010003,94,138,94,13 + CONTROL "Contact signs off",IDC_NOTIFY_SIGNOFF,"Button",0x50010003,194,166,100,13 + CONTROL "Contact changes status",IDC_NOTIFY_STATUS,"Button",0x50010003,194,177,100,13 + CONTROL "Incoming URL",IDC_NOTIFY_URL,"Button",0x50010003,194,132,100,13 + CONTROL "Contactlist events",IDC_NOTIFY_CONTACTS,"Button",0x50010003,194,188,100,13 + CONTROL "Incoming file transfers",IDC_NOTIFY_FILE,"Button",0x50010003,194,144,100,13 + CONTROL "Protocol disconnected",IDC_NOTIFY_PROTO_SIGNOFF,"Button",0x50010003,194,199,102,13 + CONTROL "Protocol connected",IDC_NOTIFY_PROTO_SIGNON,"Button",0x50010003,194,210,102,13 + CONTROL "Protocol status changes",IDC_NOTIFY_PROTO_STATUS,"Button",0x50010003,194,221,102,11 + CONTROL "Show only events from the following protocols:",IDC_STATIC25,"Static",0x50020000,6,134,86,28 + CONTROL "Contact signs on",IDC_NOTIFY_SIGNON,"Button",0x50010003,194,155,98,13 + CONTROL "",IDC_PROTOCOLS,"SysTreeView32",0x50810001,6,162,84,70 + CONTROL "Incoming messages",IDC_NOTIFY_SKIP_MESSAGES,"Button",0x50010003,174,38,122,9 + CONTROL "When a chatsession is active, skip the following notifications for that contact:",IDC_STC3,"Static",0x50000000,168,9,128,28 + CONTROL "Contact changes status",IDC_NOTIFY_SKIP_STATUS,"Button",0x50010003,174,48,122,9 + CONTROL "Chatsession specific",IDC_GRP1,"Button",0x50000007,164,0,136,124 + CONTROL "Contact signs on",IDC_NOTIFY_SKIP_SIGNON,"Button",0x50010003,174,59,102,9 + CONTROL "Contact signs off",IDC_NOTIFY_SKIP_SIGNOFF,"Button",0x50010003,174,70,102,9 + CONTROL "Show timestamps",IDC_NOTIFY_TIMESTAMPS,"Button",0x50010003,6,9,102,9 + CONTROL "Messages",IDC_NOTIFY_IRC_MESSAGES,"Button",0x50010003,110,162,74,9 + CONTROL "User events",IDC_NOTIFY_IRC_USERS,"Button",0x50010003,110,184,76,9 + CONTROL "Emotes",IDC_NOTIFY_IRC_EMOTES,"Button",0x50010003,110,195,76,9 + CONTROL "Status changes",IDC_NOTIFY_IRC_STATUS,"Button",0x50010003,110,206,76,9 + CONTROL "Special IRC events:",IDC_STC4,"Static",0x50000000,110,151,64,9 + CONTROL "Notices",IDC_NOTIFY_IRC_NOTICES,"Button",0x50010003,110,173,74,9 + CONTROL "Channel events",IDC_NOTIFY_IRC_CHANNEL,"Button",0x50010003,110,217,76,9 + CONTROL "Cutoff nicknames after",IDC_NOTIFY_NICKCUTOFF,"Button",0x50010003,4,46,90,9 + CONTROL "",IDC_NOTIFY_NICKCUTOFF_OFFSET,"Edit",0x50012080,102,46,22,11,0x00000200 + CONTROL "chars",IDC_STC11,"Static",0x50020000,126,48,30,9 + CONTROL "Show protocol labels",IDC_NOTIFY_SHOWPROTO,"Button",0x50010003,4,68,92,9 + CONTROL "Don't skip when repyling",IDC_NOTIFY_NO_SKIP_REPLY,"Button",0x50010003,174,99,122,11 + CONTROL "Exceptions:",IDC_STC12,"Static",0x50000000,170,88,88,9 + CONTROL "chars",IDC_STC13,"Static",0x50020000,126,59,30,9 + CONTROL "Cutoff channelnames after",IDC_NOTIFY_CHANNELCUTOFF,"Button",0x50010003,4,57,90,9 + CONTROL "",IDC_NOTIFY_CHANNELCUTOFF_OFFSET,"Edit",0x50012080,102,57,22,11,0x00000200 +END +IDD_CLIST DIALOGEX 0,0,304,179 +CAPTION "Contactlist" +FONT 8,"MS Shell Dlg",400,0,1 +STYLE 0x80C80048 +BEGIN + CONTROL "General settings",IDC_STATIC9,"Button",0x50000007,0,0,174,135 + CONTROL "Show the contacts protocols",IDC_CLIST_SHOWPROTO,"Button",0x50010003,6,11,154,13 + CONTROL "Hide offline users",IDC_CLIST_HIDEOFFLINE,"Button",0x50010003,6,22,156,13 + CONTROL "Use ignore settings",IDC_CLIST_USEIGNORE,"Button",0x50010003,6,33,160,13 + CONTROL "Use groups/subgroups",IDC_CLIST_USEGROUPS,"Button",0x50010003,6,44,158,13 + CONTROL "Grouped mode",IDC_STATIC10,"Button",0x50000007,0,136,300,39 + CONTROL "Draw tree lines",IDC_CLIST_DRAWLINES,"Button",0x50010003,4,145,162,13 + CONTROL "Show counters behind group names",IDC_CLIST_COUNTERS,"Button",0x50010003,4,158,168,13 + CONTROL "Reset selection",IDC_CLIST_POSITION,"Button",0x50010003,14,90,146,11 + CONTROL "When opening the contactlist screen:",IDC_STC1,"Static",0x50000000,6,81,156,9 + CONTROL "Don't change group states",IDC_CLIST_GA_NONE,"Button",0x50010009,14,101,146,9 + CONTROL "Collapse all groups",IDC_CLIST_GA_COLLAPSE,"Button",0x50010009,14,112,152,9 + CONTROL "Show only contacts from the following protocols:",IDC_STC5,"Static",0x50020000,192,9,94,24 + CONTROL "",IDC_CLIST_PROTOFILTER,"SysTreeView32",0x50810001,192,35,94,91 + CONTROL "Protocol filter",IDC_GRP2,"Button",0x50000007,176,0,122,135 + CONTROL "Expand all groups",IDC_CLIST_GA_EXPAND,"Button",0x50010009,14,123,136,9 + CONTROL "Use two columns",IDC_CLIST_COLUMNS,"Button",0x50010003,6,55,160,13 + CONTROL "Fade out selection rectangle",IDC_CLIST_SELECTION,"Button",0x50010003,6,66,160,13 +END +IDD_CHAT DIALOGEX 0,0,302,193 +CAPTION "Chat" +FONT 8,"MS Shell Dlg",400,0,1 +STYLE 0x80C80048 +BEGIN + CONTROL "Typing notifications",IDC_STATIC1,"Button",0x50000007,160,105,140,33 + CONTROL "Show typing notifications",IDC_SESSION_SHOWTYPING,"Button",0x50010003,168,114,126,11 + CONTROL "Send typing notifications",IDC_SESSION_SENDTYPING,"Button",0x50010003,168,125,128,11 + CONTROL "Maximizing",IDC_STATIC2,"Button",0x50000007,0,105,156,33 + CONTROL "When maximized:",IDC_STATIC3,"Static",0x50020000,4,116,66,9 + CONTROL "Hide title",IDC_MAXIMIZED_TITLE,"Button",0x50010003,62,114,70,13 + CONTROL "Hide labels",IDC_MAXIMIZED_LABELS,"Button",0x50010003,62,125,68,11 + CONTROL "General settings",IDC_STATIC4,"Button",0x50000007,0,1,300,67 + CONTROL "Show only new messages",IDC_SESSION_LOADDB,"Button",0x50010003,6,9,144,13 + CONTROL "Mark incoming messages as read",IDC_SESSION_MARKREAD,"Button",0x50010003,6,20,148,13 + CONTROL "Maximized scrolling",IDC_SESSION_SCROLL_MAXIMIZED,"Button",0x50010003,6,42,148,11 + CONTROL "Size of the log:",IDC_STATIC6,"Static",0x50020000,6,55,84,9 + CONTROL "",IDC_SESSION_LOGSIZE,"Edit",0x50012080,96,53,30,11,0x00000200 + CONTROL "events",IDC_STATIC5,"Static",0x50020000,132,55,24,9 + CONTROL "On incoming messages:",IDC_STATIC8,"Static",0x50020000,156,11,132,11 + CONTROL "Do nothing",IDC_SESSION_SCROLLNONE,"Button",0x50010009,168,20,90,13 + CONTROL "Scroll to the first line",IDC_SESSION_SCROLLFIRST,"Button",0x50010009,168,31,108,13 + CONTROL "Scroll to the last line",IDC_SESSION_SCROLLLAST,"Button",0x50010009,168,42,90,13 + CONTROL "Replying",IDC_STATIC7,"Button",0x50000007,0,142,300,48 + CONTROL "Show linebreak indicators",IDC_SESSION_SYMBOLS,"Button",0x50010003,6,151,264,13 + CONTROL "Send messages with return, insert linebreaks with ctrl+return",IDC_SESSION_SENDRETURN,"Button",0x50010003,6,162,284,13 + CONTROL "Maximized replying",IDC_SESSION_REPLY_MAXIMIZED,"Button",0x50010003,6,173,274,13 + CONTROL "Show timestamps",IDC_SESSION_TIMESTAMPS,"Button",0x50010003,6,31,148,11 + CONTROL "Close chat after",IDC_SESSION_CLOSE,"Button",0x50010003,8,84,98,8 + CONTROL "",IDC_SESSION_CLOSETIMER,"Edit",0x50010000,112,83,30,11,0x00000200 + CONTROL "seconds",IDC_STC16,"Static",0x50000000,146,84,30,8 + CONTROL "When in background",IDC_GRP4,"Button",0x50000007,0,72,300,30 +END diff --git a/plugins/MirandaG15/MirandaG15.sln b/plugins/MirandaG15/MirandaG15.sln new file mode 100644 index 0000000000..475e1d3305 --- /dev/null +++ b/plugins/MirandaG15/MirandaG15.sln @@ -0,0 +1,39 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MirandaG15", "MirandaG15.vcxproj", "{8ACA3C8B-BDFA-47B2-8578-069555BA05B3}" + ProjectSection(ProjectDependencies) = postProject + {3BBA4976-826E-44E5-B65F-8A2E1D912BE7} = {3BBA4976-826E-44E5-B65F-8A2E1D912BE7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LCDFramework", "LCDFramework\LCDFramework.vcxproj", "{3BBA4976-826E-44E5-B65F-8A2E1D912BE7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8ACA3C8B-BDFA-47B2-8578-069555BA05B3}.Debug|Win32.ActiveCfg = Debug|Win32 + {8ACA3C8B-BDFA-47B2-8578-069555BA05B3}.Debug|Win32.Build.0 = Debug|Win32 + {8ACA3C8B-BDFA-47B2-8578-069555BA05B3}.Debug|x64.ActiveCfg = Debug|x64 + {8ACA3C8B-BDFA-47B2-8578-069555BA05B3}.Debug|x64.Build.0 = Debug|x64 + {8ACA3C8B-BDFA-47B2-8578-069555BA05B3}.Release|Win32.ActiveCfg = Release|Win32 + {8ACA3C8B-BDFA-47B2-8578-069555BA05B3}.Release|Win32.Build.0 = Release|Win32 + {8ACA3C8B-BDFA-47B2-8578-069555BA05B3}.Release|x64.ActiveCfg = Release|x64 + {8ACA3C8B-BDFA-47B2-8578-069555BA05B3}.Release|x64.Build.0 = Release|x64 + {3BBA4976-826E-44E5-B65F-8A2E1D912BE7}.Debug|Win32.ActiveCfg = Debug|Win32 + {3BBA4976-826E-44E5-B65F-8A2E1D912BE7}.Debug|Win32.Build.0 = Debug|Win32 + {3BBA4976-826E-44E5-B65F-8A2E1D912BE7}.Debug|x64.ActiveCfg = Debug|x64 + {3BBA4976-826E-44E5-B65F-8A2E1D912BE7}.Debug|x64.Build.0 = Debug|x64 + {3BBA4976-826E-44E5-B65F-8A2E1D912BE7}.Release|Win32.ActiveCfg = Release|Win32 + {3BBA4976-826E-44E5-B65F-8A2E1D912BE7}.Release|Win32.Build.0 = Release|Win32 + {3BBA4976-826E-44E5-B65F-8A2E1D912BE7}.Release|x64.ActiveCfg = Release|x64 + {3BBA4976-826E-44E5-B65F-8A2E1D912BE7}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/plugins/MirandaG15/MirandaG15.vcxproj b/plugins/MirandaG15/MirandaG15.vcxproj new file mode 100644 index 0000000000..cb18675058 --- /dev/null +++ b/plugins/MirandaG15/MirandaG15.vcxproj @@ -0,0 +1,420 @@ + + + + + Debug ANSI + Win32 + + + Debug ANSI + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release ANSI + Win32 + + + Release ANSI + x64 + + + Release + Win32 + + + Release + x64 + + + + {8ACA3C8B-BDFA-47B2-8578-069555BA05B3} + MirandaG15 + Win32Proj + + + + DynamicLibrary + MultiByte + true + + + DynamicLibrary + MultiByte + true + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + + + DynamicLibrary + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + true + true + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + false + false + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + true + true + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + $(SolutionDir)Build\$(Configuration)\ + false + false + + + + Disabled + LCDFramework\src;..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MIRANDAG15_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + comctl32.lib %(AdditionalOptions) + true + Windows + false + + + MachineX86 + $(ProfileDir)..\..\bin10\lib + + + + + Disabled + LCDFramework\src;..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MIRANDAG15_EXPORTS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + comctl32.lib %(AdditionalOptions) + true + Windows + false + + + $(ProfileDir)..\..\bin10\lib + + + + + LCDFramework\src;..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MIRANDAG15_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + comctl32.lib %(AdditionalOptions) + true + Windows + true + true + false + + + MachineX86 + $(ProfileDir)..\..\bin10\lib + + + + + LCDFramework\src;..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MIRANDAG15_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + comctl32.lib %(AdditionalOptions) + true + Windows + true + true + false + + + $(ProfileDir)..\..\bin10\lib + + + + + Disabled + LCDFramework\src;..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MIRANDAG15_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + comctl32.lib %(AdditionalOptions) + true + Windows + false + + + MachineX86 + $(ProfileDir)..\..\bin10\lib + + + + + Disabled + LCDFramework\src;..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MIRANDAG15_EXPORTS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + comctl32.lib %(AdditionalOptions) + true + Windows + false + + + $(ProfileDir)..\..\bin10\lib + + + + + LCDFramework\src;..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MIRANDAG15_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + comctl32.lib %(AdditionalOptions) + true + Windows + true + true + false + + + MachineX86 + $(ProfileDir)..\..\bin10\lib + + + + + LCDFramework\src;..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MIRANDAG15_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + comctl32.lib %(AdditionalOptions) + true + Windows + true + true + false + + + $(ProfileDir)..\..\bin10\lib + + + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {3bba4976-826e-44e5-b65f-8a2e1d912be7} + + + + + + \ No newline at end of file diff --git a/plugins/MirandaG15/MirandaG15.vcxproj.filters b/plugins/MirandaG15/MirandaG15.vcxproj.filters new file mode 100644 index 0000000000..04f612158a --- /dev/null +++ b/plugins/MirandaG15/MirandaG15.vcxproj.filters @@ -0,0 +1,229 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {da23f7ae-a558-4f9c-a10b-acaf09ad33b9} + + + {646e30dc-4ba4-489e-8aa3-b99f397e0963} + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {68ea4916-17a8-4272-b715-f6810cc42684} + + + {15a59424-ddac-499b-b802-aca213f69f7b} + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files\Screens + + + Source Files\Screens + + + Source Files\Screens + + + Source Files\Screens + + + Source Files\Screens + + + Source Files\Screens + + + Source Files\Screens + + + Source Files\Objects + + + Source Files\Objects + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files\Screens + + + Header Files\Screens + + + Header Files\Screens + + + Header Files\Screens + + + Header Files\Screens + + + Header Files\Screens + + + Header Files\Screens + + + Header Files\Objects + + + Header Files\Objects + + + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + + + + + + Resource Files + + + \ No newline at end of file diff --git a/plugins/MirandaG15/changelog.txt b/plugins/MirandaG15/changelog.txt new file mode 100644 index 0000000000..dfbcb36f16 --- /dev/null +++ b/plugins/MirandaG15/changelog.txt @@ -0,0 +1,129 @@ +v 0.1.1.14 - 23.04.2008 +------------------------- +- fixed: some messages were not shown on the lcd +- changed: updated IRC plugin + +v 0.1.1.12 - 05.10.2007 +------------------------- +- fixed: wrong version displayed in last release +- fixed: small bug in displaying notifications + +v 0.1.1.12 - 05.10.2007 +------------------------- +- fixed: a bug in metacontacts handling could cause mirandag15 to crash +- fixed: no more notifications when copying history entries + +v 0.1.1.11 - 26.09.2007 +------------------------- +- added: press chat on a metacontact to chat directly, hold and release the button to view the subcontacts +- added: chatscreen can close automatically when the applet is inactive +- changed: performance improvements +- fixed: improved support for metacontacts plugin +- fixed: improved device selection +- fixed: support for miranda 0.7 +- fixed: added new IRC.dll + +v 0.1.1.10 - 10.06.2007 +------------------------- +- fixed: bug in channelname shortening + +v 0.1.1.9 - 10.06.2007 +------------------------- +- fixed: the applet could crash when LCDMon.exe got terminated (fixes the crash on shutdown problem) +- fixed: improved connection handling (applet can now reconnect when LCDMon is restarted) & hotplugging support +- fixed: 7zip compatible archive ;-) +- added: irc channelnames can now be optionally shortened +- added: applet can be locked when screensaver gets activated + +v 0.1.1.8 - 23.05.2007 +------------------------- +- fixed: crash on exit that could occur with newer version of miranda +- changed: updated to miranda 0.6.8 + +v 0.1.1.7 - 01.01.2007 +------------------------- +- added: the logitech lcd device to be used can now be selected on the configuration screen +- added: option to keep contactlist selection rectangle from disappearing +- changed: logitech drivers version 1.03 are now required +- changed: miranda 0.6.x is now required +- changed: updated the patched irc protocoll plugin +- fixed: wrong nickname was displayed for authorizationrequest events +- fixed: private messages on IRC are now working again +- fixed: a bug that that disabled the plugin when saving the configuration without an lcd plugged in + +v 0.1.1.6 - 02.08.2006 +------------------------- +- fixed: a bug in the IRC message handling could cause miranda to freeze + +v 0.1.1.5 - 25.07.2006 +------------------------- +- fixed: the eventlog screen could get activated, when notifications where received on the chatscreen +- fixed: the "Show typing notifications" option wasn't used (thanks to spiky1984) +- fixed: no typing notifications were sent since 0.1.0.0 + +v 0.1.1.4 - 10.07.2006 +------------------------- +- fixed: bugs in the IRC event handling, that could cause miranda to crash (thanks to lastwebpage) +- fixed: some IRC part/quit events were not handled correctly +- fixed: many improvements in the IRC handling code + +v 0.1.1.3 - 09.07.2006 +------------------------- +- added: support for language packs +- added: german language pack (available at miranda-im.de, thanks to Dober) +- added: option to enable/disable showing the protocol on status and message notifications +- fixed: metacontact signon notifications are no longer displayed when connecting + +v 0.1.1.2 - 03.07.2006 +------------------------- +- added: support for multiple instances of the IRC protocol (thanks to lastwebpage for reporting it) + +v 0.1.1.1 - 02.07.2006 +------------------------- +- fixed: a bug in the input control, that could cause miranda to freeze (thanks to QBUS for reporting it) + +v 0.1.1.0 - 02.07.2006 +------------------------- +- added: IRC support +- added: support for the metacontacts plugin +- added: when applying configuration changes, the old screen layout morphs into the new one +- added: a credit screen (somehow more effective than the readme I hope) +- added: optional transition effects when changing screens +- added: support for unicode contact-/groupnames (make sure you use a unicode font to use this) +- added: new filters to hide protocols from the contactlist +- added: optional timestamps in the eventlog, the chatlog and on the notificationscreen +- added: when a chatsession is active, notifications can be skipped for that contact (optional) +- added: option to use the volumewheel to scroll up and down +- added: option to turn off the g15 backlight while the screensaver is active +- added: new options to change the contactlists initial selection and groups states +- added: some small changes to the configuration dialog +- added: button to jump to the chatscreen from new notifications +- added: contactlist can be displayed in two columns +- added: replaced status strings on the contactlist with status icons, and added one to the chatscreen +- added: events are now represented by small icons +- added: option to shorten user nicknames inside of notifications +- fixed: a bug with contact renaming that could result in the wrong name being displayed on the LCD +- fixed: optimized the way contactlist & eventlog scroll +- fixed: added case-insensitive alphabetical sorting as an additional condition for contacts +- fixed: applet stays focused while replying even if automatic timed applet switching is enabled +- fixed: wrong chatscreen layout when softkey labels where disabled +- fixed: line breaks weren't displayed correctly in the eventlog +- fixed: added scrollbar to messages on the notificationscreen +- fixed: textlog & eventlog where immediately scrolling to the bottom on new events, + even if the user was just scrolling manually +- fixed: added timeout delay to message sending, so the dialog can't get stuck +- fixed: chatsession didn't update the status label when the contact signed off/on +- fixed: some improvements to the hotplugging support +- fixed: unread messages were counted wrong when a contact with unread messages was deleted +- fixed: scrollbars could show the wrong position after starting miranda +- fixed: some label issues (wrong cutoff positions, problems with multiline labels) +- fixed: italic and bold fonts weren't handled correct (issues with wordwrapping, label cutoffs..) + +v 0.1.0.2 - 30.04.2006 +------------------------- +- fixed: the messagelog could stop receiving messages when a notification was displayed + +v 0.1.0.1 - 29.04.2006 +------------------------- +- fixed: bug that could cause a crash when the keyboard was not connected when starting miranda +- fixed: some events were appearing in the chatlog multiple times \ No newline at end of file diff --git a/plugins/MirandaG15/data/back.bmp b/plugins/MirandaG15/data/back.bmp new file mode 100644 index 0000000000..7ab9da42a7 Binary files /dev/null and b/plugins/MirandaG15/data/back.bmp differ diff --git a/plugins/MirandaG15/data/chat.bmp b/plugins/MirandaG15/data/chat.bmp new file mode 100644 index 0000000000..93b2ebff37 Binary files /dev/null and b/plugins/MirandaG15/data/chat.bmp differ diff --git a/plugins/MirandaG15/data/clist.bmp b/plugins/MirandaG15/data/clist.bmp new file mode 100644 index 0000000000..68cbbec9ea Binary files /dev/null and b/plugins/MirandaG15/data/clist.bmp differ diff --git a/plugins/MirandaG15/data/down.bmp b/plugins/MirandaG15/data/down.bmp new file mode 100644 index 0000000000..e2b5898f99 Binary files /dev/null and b/plugins/MirandaG15/data/down.bmp differ diff --git a/plugins/MirandaG15/data/edit.bmp b/plugins/MirandaG15/data/edit.bmp new file mode 100644 index 0000000000..cb941124a0 Binary files /dev/null and b/plugins/MirandaG15/data/edit.bmp differ diff --git a/plugins/MirandaG15/data/events/conn.bmp b/plugins/MirandaG15/data/events/conn.bmp new file mode 100644 index 0000000000..f0bcc9186e Binary files /dev/null and b/plugins/MirandaG15/data/events/conn.bmp differ diff --git a/plugins/MirandaG15/data/events/conn_large.bmp b/plugins/MirandaG15/data/events/conn_large.bmp new file mode 100644 index 0000000000..2f0a79a1d0 Binary files /dev/null and b/plugins/MirandaG15/data/events/conn_large.bmp differ diff --git a/plugins/MirandaG15/data/events/info.bmp b/plugins/MirandaG15/data/events/info.bmp new file mode 100644 index 0000000000..4dc3871518 Binary files /dev/null and b/plugins/MirandaG15/data/events/info.bmp differ diff --git a/plugins/MirandaG15/data/events/info_large.bmp b/plugins/MirandaG15/data/events/info_large.bmp new file mode 100644 index 0000000000..522752cb8e Binary files /dev/null and b/plugins/MirandaG15/data/events/info_large.bmp differ diff --git a/plugins/MirandaG15/data/events/msg.bmp b/plugins/MirandaG15/data/events/msg.bmp new file mode 100644 index 0000000000..ff59ca2b04 Binary files /dev/null and b/plugins/MirandaG15/data/events/msg.bmp differ diff --git a/plugins/MirandaG15/data/events/msg_large.bmp b/plugins/MirandaG15/data/events/msg_large.bmp new file mode 100644 index 0000000000..bce1ebadd4 Binary files /dev/null and b/plugins/MirandaG15/data/events/msg_large.bmp differ diff --git a/plugins/MirandaG15/data/events/user.bmp b/plugins/MirandaG15/data/events/user.bmp new file mode 100644 index 0000000000..c8425a5a86 Binary files /dev/null and b/plugins/MirandaG15/data/events/user.bmp differ diff --git a/plugins/MirandaG15/data/events/user_large.bmp b/plugins/MirandaG15/data/events/user_large.bmp new file mode 100644 index 0000000000..a7ecd79064 Binary files /dev/null and b/plugins/MirandaG15/data/events/user_large.bmp differ diff --git a/plugins/MirandaG15/data/hist.bmp b/plugins/MirandaG15/data/hist.bmp new file mode 100644 index 0000000000..9e9f6fe16b Binary files /dev/null and b/plugins/MirandaG15/data/hist.bmp differ diff --git a/plugins/MirandaG15/data/minus.bmp b/plugins/MirandaG15/data/minus.bmp new file mode 100644 index 0000000000..8b05aa6229 Binary files /dev/null and b/plugins/MirandaG15/data/minus.bmp differ diff --git a/plugins/MirandaG15/data/next.bmp b/plugins/MirandaG15/data/next.bmp new file mode 100644 index 0000000000..8b21294110 Binary files /dev/null and b/plugins/MirandaG15/data/next.bmp differ diff --git a/plugins/MirandaG15/data/notick.ico b/plugins/MirandaG15/data/notick.ico new file mode 100644 index 0000000000..20cc236bad Binary files /dev/null and b/plugins/MirandaG15/data/notick.ico differ diff --git a/plugins/MirandaG15/data/open.bmp b/plugins/MirandaG15/data/open.bmp new file mode 100644 index 0000000000..f9e519ffb5 Binary files /dev/null and b/plugins/MirandaG15/data/open.bmp differ diff --git a/plugins/MirandaG15/data/plus.bmp b/plugins/MirandaG15/data/plus.bmp new file mode 100644 index 0000000000..d90508d71f Binary files /dev/null and b/plugins/MirandaG15/data/plus.bmp differ diff --git a/plugins/MirandaG15/data/prev.bmp b/plugins/MirandaG15/data/prev.bmp new file mode 100644 index 0000000000..643bba1e1c Binary files /dev/null and b/plugins/MirandaG15/data/prev.bmp differ diff --git a/plugins/MirandaG15/data/reply.bmp b/plugins/MirandaG15/data/reply.bmp new file mode 100644 index 0000000000..baa2d483d6 Binary files /dev/null and b/plugins/MirandaG15/data/reply.bmp differ diff --git a/plugins/MirandaG15/data/send.bmp b/plugins/MirandaG15/data/send.bmp new file mode 100644 index 0000000000..e9d46e4660 Binary files /dev/null and b/plugins/MirandaG15/data/send.bmp differ diff --git a/plugins/MirandaG15/data/status/away.bmp b/plugins/MirandaG15/data/status/away.bmp new file mode 100644 index 0000000000..f5c7f9d33e Binary files /dev/null and b/plugins/MirandaG15/data/status/away.bmp differ diff --git a/plugins/MirandaG15/data/status/dnd.bmp b/plugins/MirandaG15/data/status/dnd.bmp new file mode 100644 index 0000000000..d7c33722b3 Binary files /dev/null and b/plugins/MirandaG15/data/status/dnd.bmp differ diff --git a/plugins/MirandaG15/data/status/ffc.bmp b/plugins/MirandaG15/data/status/ffc.bmp new file mode 100644 index 0000000000..162bb13cf0 Binary files /dev/null and b/plugins/MirandaG15/data/status/ffc.bmp differ diff --git a/plugins/MirandaG15/data/status/invis.bmp b/plugins/MirandaG15/data/status/invis.bmp new file mode 100644 index 0000000000..ebb1c782e5 Binary files /dev/null and b/plugins/MirandaG15/data/status/invis.bmp differ diff --git a/plugins/MirandaG15/data/status/na.bmp b/plugins/MirandaG15/data/status/na.bmp new file mode 100644 index 0000000000..6a46edfaf5 Binary files /dev/null and b/plugins/MirandaG15/data/status/na.bmp differ diff --git a/plugins/MirandaG15/data/status/occ.bmp b/plugins/MirandaG15/data/status/occ.bmp new file mode 100644 index 0000000000..bcfbe1ea63 Binary files /dev/null and b/plugins/MirandaG15/data/status/occ.bmp differ diff --git a/plugins/MirandaG15/data/status/off.bmp b/plugins/MirandaG15/data/status/off.bmp new file mode 100644 index 0000000000..31efd66b56 Binary files /dev/null and b/plugins/MirandaG15/data/status/off.bmp differ diff --git a/plugins/MirandaG15/data/status/on.bmp b/plugins/MirandaG15/data/status/on.bmp new file mode 100644 index 0000000000..8ef4b9fba5 Binary files /dev/null and b/plugins/MirandaG15/data/status/on.bmp differ diff --git a/plugins/MirandaG15/data/status/status.bmp b/plugins/MirandaG15/data/status/status.bmp new file mode 100644 index 0000000000..76227f9520 Binary files /dev/null and b/plugins/MirandaG15/data/status/status.bmp differ diff --git a/plugins/MirandaG15/data/tick.ico b/plugins/MirandaG15/data/tick.ico new file mode 100644 index 0000000000..e72a277915 Binary files /dev/null and b/plugins/MirandaG15/data/tick.ico differ diff --git a/plugins/MirandaG15/data/up.bmp b/plugins/MirandaG15/data/up.bmp new file mode 100644 index 0000000000..2530c5568c Binary files /dev/null and b/plugins/MirandaG15/data/up.bmp differ diff --git a/plugins/MirandaG15/langpack_german.txt b/plugins/MirandaG15/langpack_german.txt new file mode 100644 index 0000000000..e50301b8b1 --- /dev/null +++ b/plugins/MirandaG15/langpack_german.txt @@ -0,0 +1,262 @@ +; MirandaG15 0.1.1.2 +; Dateiname: mirandag15.dll +; Autor: Tharit +; http://addons.miranda-im.org/details.php?action=viewfile&id=2610 +; Übersetzung: Tharit 09.07.06 +; Aktualisierung: Dober 09.07.06 + +; /CAppletManager.cpp +[Timeout: No response from contact/server] +Timeout: Keine Antwort von Kontakt/Server +[New message from %s] +Neue Nachricht von %s +[Incoming URL from %s] +Neue URL von %s +[Incoming contacts from %s] +Neue Kontakte von %s +[You were added by %s] +%s hat dich hinzugefügt! +[Authrequest from %s] +Autorisationsanfrage von %s +[Incoming file from %s] +Neuer Dateitransfer von %s +[%s has joined the channel] +%s hat den Channel betreten +[%s has left] +%s hat den Channel verlassen +[%s has left: %s] +%s hat den Channel verlassen: %s +[%s has disconnected] +%s hat die Verbindung beendet +[%s has disconnected: %s] +%s hat die Verbindung beendet: %s +[%s has kicked %s: %s] +%s hat %s gekickt: %s +[%s is now known as %s] +%s heißt jetzt %s +[Notice from %s: %s] +Hinweis von %s: %s +[Topic is now '%s' (set by %s)] +Neues Thema: '%s' (geändert von %s) +[%s enables '%s' for %s] +%s aktiviert '%s' für %s +[%s disables '%s' for %s] +%s deaktiviert '%s' für %s +[Joined %s] +%s beigetreten +[%s signed on (%s)] +%s hat sich angemeldet (%s) +[Left %s] +%s verlassen +[%s signed off] +%s hat sich abgemeldet +[%s is now %s] +%s ist jetzt %s +[Contactlist event] +Kontaktlisten-Ereignis +[You are now %s] +Du bist jetzt %s +[Protocol status change] +Verbindungsstatus geändert +[%s was deleted from contactlist!] +%s wurde von der Kontaktliste entfernt + +; /CChatScreen.cpp +[typing..] +tippt.. +[IRC-Chatroom support is disabled!\nYou need to install the patched IRC.dll (see the readme) to use IRC-Chatrooms on the LCD] +IRC-Chatraum Unterstützung ist deaktiviert!\nDu benötigst die gepatchte IRC.dll (siehe Readme) um sie zu aktivieren! +[Sending message...] +Nachricht wird gesendet... +[Could not send the message!] +Nachricht konnte nicht gesendet werden! + +; /MirandaG15.rc:IDD_FONTS +[Appearance] +Darstellung +[Fonts] +Schriftarten +[General settings] +Generelle Einstellungen +[Show softkey labels] +Softkeybeschreibungen anzeigen +[Event log:] +Ereignisverlauf: +[Sample] +Beispiel +[Message log:] +Nachrichten +[Contactlist:] +Kontaktliste +[Titles:] +Titel +[Notifications:] +Benachrichtigungen +[Turn off backlights while screensaver is active] +Hintergrundbeleuchtung ausschalten wenn Bildschirmschoner aktiviert wird +[If the applet is active:] +Wenn das Applet aktiv ist: +[Use the VolumeWheel to scroll up and down] +Lautstärkerad zum Blättern benutzen +[Show seconds in timestamps] +Sekunden in Uhrzeiten anzeigen +[Use transition effects when changing screens] +Übergangseffekte für Bildschirmwechsel +[Credits] +Credits +[About] +Über +[For updates and news check the thread on http://www.g15forums.com] +Für Neuigkeiten und Aktualisierungen, siehe den Thread auf http://www.g15forums.com +[Or visit http://www.mkleinhans.de] +Oder besuche http://www.mkleinhans.de + +; /MirandaG15.rc:IDD_NOTIFICATIONS +[Notifications] +Benachrichtigungen +[Notification screen title] +Benachrichtigungstitel +[Hide it] +Ausblenden +[Show the plugin name] +Pluginname anzeigen +[Show a short event summary] +Ereignisbeschreibung anzeigen +[Size of the log] +Einträge im Verlauf +[Notification duration] +Benachrichtigungsdauer +[Edit] +Bearbeiten +[events] +Ereignisse +[seconds] +Sekunden +[Notification types] +Benachrichtigungstypen +[Incoming messages] +Eingehende Nachrichten +[Contact signs off] +Kontakt meldet sich ab +[Contact changes status] +Kontakt wechselt Status +[Incoming URL] +Eingehende URL +[Contactlist events] +Kontaktlisten Ereignisse +[Incoming file transfers] +Eingehende Filetransfers +[Protocol disconnected] +Verbindung getrennt +[Protocol connected] +Verbindung hergestellt +[Protocol status changes] +Verbindungsstatus geändert +[Show only events from the following protocols:] +Nur Ereignisse der folgenden Protokolle zeigen: +[Contact signs on] +Kontakt meldet sich an +[When a chatsession is active, skip the following notifications for that contact:] +Wenn ein Chatfenster aktiv ist, ignoriere folgende Ereignisse dieses Kontakts: +[Chatsession specific] +Einstellungen für das Chatfenster +[Show timestamps] +Uhrzeit anzeigen +[Messages] +Nachrichten +[User events] +Benutzer Ereignisse +[Emotes] +Emotes +[Status changes] +Statusänderungen +[Special IRC events:] +IRC-spezifische Ereignisse +[Notices] +Hinweise +[Channel events] +Channel Ereignisse +[Cutoff nicknames after] +Nicks abschneiden nach +[chars] +Zeichen +[Show protocol labels] +Protkoll anzeigen + +; /MirandaG15.rc:IDD_CLIST +[Contactlist] +Kontaktliste +[Show the contacts protocols] +Protokoll anzeigen +[Hide offline users] +Abgemeldete Benutzer ausblenden +[Use ignore settings] +"Ignorieren"-Einstellungen benutzen +[Use groups/subgroups] +Gruppen/Untergruppen benutzen +[Grouped mode] +Gruppenmodus +[Draw tree lines] +Baumlinien anzeigen +[Show counters behind group names] +Zähler hinter Gruppe anzeigen +[Reset selection] +Auswahl zurücksetzen +[When opening the contactlist screen:] +Wenn die Kontaktliste aktiviert wird: +[Don't change group states] +Gruppenzustände nicht ändern +[Collapse all groups] +Alle Gruppen schließen +[Show only contacts from the following protocols:] +Nur Kontakte der folgenden Protokolle anzeigen +[Protocol filter] +Protkollfilter +[Expand all groups] +Alle Gruppen öffnen +[Use two columns] +Zwei Spalten verwenden + +; /MirandaG15.rc:IDD_CHAT +[Chat] +Chat +[Typing notifications] +Tipp-Benachrichtigungen +[Show typing notifications] +Tipp-Benachrichtigungen anzeigen +[Send typing notifications] +Tipp-Benachrichtigungen senden +[Maximizing] +Maximieren +[When maximized] +Wenn maximiert: +[Hide title] +Titel ausblenden +[Hide labels] +Softkeybeschreibungen ausblenden +[Message log] +Nachrichtenverlauf +[Load only unread messages] +Nur ungelesene Nachrichten laden +[Mark incoming messages as read] +Eingehende Nachrichten als gelesen markieren +[Maximized scrolling] +Maximiertes Blättern +[Size of the log:] +Größe des Verlaufs: +[On incoming messages:] +Bei eingehenden Nachrichten: +[Do nothing] +Position nicht ändern +[Scroll to the first line] +Zur ersten Zeile blättern +[Scroll to the last line] +Zur letzten Zeile blättern +[Replying] +Antworten +[Show linebreak indicators] +Zeilenumbrüche anzeigen +[Send messages with return, insert linebreaks with ctrl+return] +Nachrichten mit Enter senden (Zeilenumbruch mit STRG+Enter) +[Maximized replying] +Maximiertes Antworten \ No newline at end of file diff --git a/plugins/MirandaG15/readme.txt b/plugins/MirandaG15/readme.txt new file mode 100644 index 0000000000..4606da0921 --- /dev/null +++ b/plugins/MirandaG15/readme.txt @@ -0,0 +1,54 @@ +MirandaG15 +-------------------- +MirandaG15 is a plugin for Miranda-IM (www.miranda-im.org). +It's an applet for Logitech's G15 Keyboard. + +~~~~~~~~~~~~~~~~~~~~~~ +Features: +~~~~~~~~~~~~~~~~~~~~~~ +- Event notifications +- Event log +- Contactlist +- Chatsessions on the LCD ( you can even reply without leaving the program/game you're in) + +~~~~~~~~~~~~~~~~~~~~~~ +Installation: +~~~~~~~~~~~~~~~~~~~~~~ +1) Stop miranda if it is currently running +2) Copy the included mirandag15.dll to the plugins\ directory of your Miranda-IM installation. + If you want to use IRC with this applet, you have to copy the included irc.dll, too. +3) The plugin should be working on the next startup. + You can configure it in mirandas options under "MirandaG15". + +~~~~~~~~~~~~~~~~~~~~~~ +Troubleshooting: +~~~~~~~~~~~~~~~~~~~~~~ +Starting with v0.1.1.7 you will need the logitech drivers v1.03 or newer and miranda 0.6.x! + +If you use tabsrmm make sure you have "enable third party event API" enabled for some features of this plugin +to work correctly. + +If the plugin is not detected by miranda make sure you have the latest VC++ runtime from Microsoft installed. +You can get it here: +http://www.microsoft.com/downloads/details.aspx?FamilyId=32BC1BEE-A3F9-4C13-9C99-220B62A191EE +(you will need the x86 version, as there is no x64 version of miranda) + +~~~~~~~~~~~~~~~~~~~~~~ +Special thanks to: +~~~~~~~~~~~~~~~~~~~~~~ +ShereKhan + Helped with the initial concept, testing since the very first day, softkey icons/labels +Tauu, Cloonix + Testing, suggestions, moral support ;) + +Everyone else who reported bugs or gave suggestions on how to improve this plugin! + +~~~~~~~~~~~~~~~~~~~~~~ +Contact: +~~~~~~~~~~~~~~~~~~~~~~ +MirandaG15 2007 by Martin Kleinhans + +Email: mail@mkleinhans.de +Homepage: - + +If you experience any bugs or have any suggestions please report them to me per email or at www.g15forums.com. \ No newline at end of file diff --git a/plugins/MirandaG15/resource.h b/plugins/MirandaG15/resource.h new file mode 100644 index 0000000000..97390427be --- /dev/null +++ b/plugins/MirandaG15/resource.h @@ -0,0 +1,163 @@ +#define IDD_FONTS 102 +#define IDC_STATIC11 3000 +#define IDC_STATIC12 3002 +#define IDC_GRP3 3024 +#define IDC_SHOW_LABELS 3001 +#define IDC_STATIC13 3003 +#define IDC_SAMPLE1 3004 +#define IDC_CHOOSEFONT1 3005 +#define IDC_STATIC15 3006 +#define IDC_SAMPLE2 3007 +#define IDC_CHOOSEFONT2 3008 +#define IDC_STATIC17 3009 +#define IDC_SAMPLE3 3010 +#define IDC_CHOOSEFONT3 3011 +#define IDC_STATIC14 3012 +#define IDC_SAMPLE4 3013 +#define IDC_CHOOSEFONT4 3014 +#define IDC_STATIC16 3015 +#define IDC_SAMPLE5 3016 +#define IDC_CHOOSEFONT5 3017 +#define IDC_CONTROL_BACKLIGHTS 3018 +#define IDC_STC2 3019 +#define IDC_HOOK_VOLUMEWHEEL 3020 +#define IDC_TIMESTAMP_SECONDS 3021 +#define IDC_TRANSITIONS 3022 +#define IDC_CREDITS 3023 +#define IDC_STC6 3025 +#define IDC_STC7 3026 +#define IDC_STC8 3027 +#define IDC_STC9 3028 +#define IDC_STC10 3029 +#define IDC_DEVICE 3151 +#define IDC_DEVICE_STATIC 3150 +#define IDC_STC14 103 +#define IDC_SCREENSAVER_LOCK 3998 +#define IDC_SKIP_DRIVER_ERROR 3040 +#define IDD_NOTIFICATIONS 103 +#define IDC_STATIC18 4000 +#define IDC_STATIC19 4007 +#define IDC_NOTIFY_TITLEHIDE 4008 +#define IDC_NOTIFY_TITLENAME 4009 +#define IDC_NOTIFY_TITLEINFO 4010 +#define IDC_STATIC20 4001 +#define IDC_STATIC22 4004 +#define IDC_NOTIFY_LOGSIZE 4002 +#define IDC_NOTIFY_DURATION 4005 +#define IDC_STATIC21 4003 +#define IDC_STATIC23 4006 +#define IDC_STATIC24 4011 +#define IDC_NOTIFY_MESSAGES 4014 +#define IDC_NOTIFY_SIGNOFF 4016 +#define IDC_NOTIFY_STATUS 4017 +#define IDC_NOTIFY_URL 4023 +#define IDC_NOTIFY_CONTACTS 4018 +#define IDC_NOTIFY_FILE 4019 +#define IDC_NOTIFY_PROTO_SIGNOFF 4020 +#define IDC_NOTIFY_PROTO_SIGNON 4021 +#define IDC_NOTIFY_PROTO_STATUS 4022 +#define IDC_STATIC25 4012 +#define IDC_NOTIFY_SIGNON 4015 +#define IDC_PROTOCOLS 4013 +#define IDC_NOTIFY_SKIP_MESSAGES 4024 +#define IDC_STC3 4030 +#define IDC_NOTIFY_SKIP_STATUS 4025 +#define IDC_GRP1 4026 +#define IDC_NOTIFY_SKIP_SIGNON 4027 +#define IDC_NOTIFY_SKIP_SIGNOFF 4028 +#define IDC_NOTIFY_TIMESTAMPS 4029 +#define IDC_NOTIFY_IRC_MESSAGES 4031 +#define IDC_NOTIFY_IRC_USERS 4032 +#define IDC_NOTIFY_IRC_EMOTES 4033 +#define IDC_NOTIFY_IRC_STATUS 4034 +#define IDC_STC4 4035 +#define IDC_NOTIFY_IRC_NOTICES 4036 +#define IDC_NOTIFY_IRC_CHANNEL 4037 +#define IDC_NOTIFY_NICKCUTOFF 4038 +#define IDC_NOTIFY_NICKCUTOFF_OFFSET 4039 +#define IDC_STC11 4040 +#define IDC_NOTIFY_SHOWPROTO 4045 +#define IDC_NOTIFY_NO_SKIP_REPLY 4041 +#define IDC_STC12 4042 +#define IDC_STC13 104 +#define IDC_NOTIFY_CHANNELCUTOFF 105 +#define IDC_NOTIFY_CHANNELCUTOFF_OFFSET 106 +#define IDD_CLIST 1001 +#define IDC_STATIC9 2000 +#define IDC_CLIST_SHOWPROTO 2001 +#define IDC_CLIST_HIDEOFFLINE 2002 +#define IDC_CLIST_USEIGNORE 2003 +#define IDC_CLIST_USEGROUPS 2004 +#define IDC_STATIC10 2005 +#define IDC_CLIST_DRAWLINES 2006 +#define IDC_CLIST_COUNTERS 2007 +#define IDC_CLIST_POSITION 2008 +#define IDC_STC1 2009 +#define IDC_CLIST_GA_NONE 2010 +#define IDC_CLIST_GA_COLLAPSE 2011 +#define IDC_STC5 2014 +#define IDC_CLIST_PROTOFILTER 2013 +#define IDC_GRP2 2015 +#define IDC_CLIST_GA_EXPAND 2012 +#define IDC_CLIST_COLUMNS 2016 +#define IDC_CLIST_SELECTION 2999 +#define IDD_CHAT 100 +#define IDC_STATIC1 1000 +#define IDC_SESSION_SHOWTYPING 1001 +#define IDC_SESSION_SENDTYPING 1002 +#define IDC_STATIC2 1003 +#define IDC_STATIC3 1004 +#define IDC_MAXIMIZED_TITLE 1005 +#define IDC_MAXIMIZED_LABELS 1006 +#define IDC_STATIC4 1007 +#define IDC_SESSION_LOADDB 1008 +#define IDC_SESSION_MARKREAD 1009 +#define IDC_SESSION_SCROLL_MAXIMIZED 1010 +#define IDC_STATIC6 1011 +#define IDC_SESSION_LOGSIZE 1012 +#define IDC_STATIC5 1013 +#define IDC_STATIC8 1014 +#define IDC_SESSION_SCROLLNONE 1015 +#define IDC_SESSION_SCROLLFIRST 1016 +#define IDC_SESSION_SCROLLLAST 1017 +#define IDC_STATIC7 1018 +#define IDC_SESSION_SYMBOLS 1019 +#define IDC_SESSION_SENDRETURN 1020 +#define IDC_SESSION_REPLY_MAXIMIZED 1021 +#define IDC_SESSION_TIMESTAMPS 1022 +#define IDC_SESSION_CLOSE 1051 +#define IDC_SESSION_CLOSETIMER 1052 +#define IDC_STC16 1053 +#define IDC_GRP4 1050 +#define IDB_BACK 1 +#define IDB_CHAT 2 +#define IDB_CLIST 3 +#define IDB_DOWN 4 +#define IDB_EDIT 5 +#define IDB_HISTORY 6 +#define IDB_MINUS 7 +#define IDB_OPEN 8 +#define IDB_PLUS 9 +#define IDB_PREV 10 +#define IDB_REPLY 11 +#define IDB_SEND 12 +#define IDB_UP 13 +#define IDI_NOTICK 14 +#define IDI_TICK 15 +#define IDB_NEXT 16 +#define IDB_STATUS_OFFLINE 17 +#define IDB_STATUS_ONLINE 18 +#define IDB_STATUS_AWAY 19 +#define IDB_STATUS_NA 20 +#define IDB_STATUS_OCCUPIED 21 +#define IDB_STATUS_DND 22 +#define IDB_STATUS_INVISIBLE 23 +#define IDB_STATUS_FFC 24 +#define IDB_EVENT_INFO 25 +#define IDB_EVENT_CON 26 +#define IDB_EVENT_USER 27 +#define IDB_EVENT_MSG 28 +#define IDB_EVENT_INFO_LARGE 29 +#define IDB_EVENT_CON_LARGE 30 +#define IDB_EVENT_USER_LARGE 31 +#define IDB_EVENT_MSG_LARGE 32 diff --git a/plugins/MirandaG15/src/CAppletManager.cpp b/plugins/MirandaG15/src/CAppletManager.cpp new file mode 100644 index 0000000000..8eb965f0a3 --- /dev/null +++ b/plugins/MirandaG15/src/CAppletManager.cpp @@ -0,0 +1,1960 @@ +#include "stdafx.h" +#include "CConfig.h" +#include "CAppletManager.h" +#include "m_system.h" + +// specifies how long contact status notifications are ignored after signon +#define PROTOCOL_NOTIFY_DELAY 1500 + +//######################################################################## +// functions +//######################################################################## + +//************************************************************************ +// returns the AppletManager's instance +//************************************************************************ +CAppletManager *CAppletManager::GetInstance() +{ + return (CAppletManager*)CLCDOutputManager::GetInstance(); +} + +//************************************************************************ +// Constructor +//************************************************************************ +CAppletManager::CAppletManager() +{ + m_uiTimer = NULL; + m_pLastScreen = NULL; + + +} + +//************************************************************************ +// Destructor +//************************************************************************ +CAppletManager::~CAppletManager() +{ + +} + +//************************************************************************ +// Initializes the AppletManager +//************************************************************************ +bool CAppletManager::Initialize(tstring strAppletName) +{ + if(!CLCDOutputManager::Initialize(strAppletName)) + return false; + + GetLCDConnection()->Connect(CConfig::GetIntSetting(DEVICE)); + + // set the volumewheel hook + SetVolumeWheelHook(); + + // initialize the screens + m_NotificationScreen.Initialize(); + m_EventScreen.Initialize(); + m_ContactlistScreen.Initialize(); + m_ChatScreen.Initialize(); + m_CreditsScreen.Initialize(); + m_ScreensaverScreen.Initialize(); + + // add the screens to the list + AddScreen(&m_NotificationScreen); + AddScreen(&m_EventScreen); + AddScreen(&m_ContactlistScreen); + AddScreen(&m_ChatScreen); + AddScreen(&m_CreditsScreen); + AddScreen(&m_ScreensaverScreen); + + // activate the event screen + ActivateScreen(&m_EventScreen); + + // hook the neccessary events + m_hMIHookMessageWindowEvent = HookEvent(ME_MSG_WINDOWEVENT,CAppletManager::HookMessageWindowEvent); + m_hMIHookEventAdded = HookEvent(ME_DB_EVENT_ADDED, CAppletManager::HookEventAdded); + m_hMIHookStatusChanged = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, CAppletManager::HookStatusChanged); + m_hMIHookProtoAck = HookEvent(ME_PROTO_ACK, CAppletManager::HookProtoAck); + m_hMIHookContactDeleted = HookEvent(ME_DB_CONTACT_DELETED, CAppletManager::HookContactDeleted); + m_hMIHookContactAdded = HookEvent(ME_DB_CONTACT_ADDED, CAppletManager::HookContactAdded); + m_hMIHookSettingChanged = HookEvent(ME_DB_CONTACT_SETTINGCHANGED,CAppletManager::HookSettingChanged); + m_hMIHookContactIsTyping = HookEvent(ME_PROTO_CONTACTISTYPING,CAppletManager::HookContactIsTyping); + + // enumerate protocols + int iCount; + int iProtoCount = 0; + PROTOACCOUNT **ppAccounts; + CProtocolData *pProtoData = NULL; + CIRCConnection *pIRCConnection = NULL; + + CallService(MS_PROTO_ENUMACCOUNTS,(WPARAM)&iCount,(LPARAM)&ppAccounts); + for(int i=0;itype != PROTOTYPE_PROTOCOL) + continue;**/ + if (ppAccounts[i]->bIsEnabled == 0) + continue; + + iProtoCount++; + pProtoData = new CProtocolData(); + pProtoData->iStatus = ID_STATUS_OFFLINE; + pProtoData->strProtocol = toTstring(ppAccounts[i]->szModuleName); + pProtoData->lTimeStamp = 0; + + // try to create an irc connection for that protocol (will fail if it is no irc protocol) + pIRCConnection = CreateIRCConnection(pProtoData->strProtocol); + + m_vProtocolData.push_back(pProtoData); + } + + // load status bitmaps + m_ahStatusBitmaps[0] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_OFFLINE), + IMAGE_BITMAP,5, 5, LR_MONOCHROME); + m_ahStatusBitmaps[1] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_ONLINE), + IMAGE_BITMAP,5, 5, LR_MONOCHROME); + m_ahStatusBitmaps[2] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_AWAY), + IMAGE_BITMAP,5, 5, LR_MONOCHROME); + m_ahStatusBitmaps[3] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_NA), + IMAGE_BITMAP,5, 5, LR_MONOCHROME); + m_ahStatusBitmaps[4] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_OCCUPIED), + IMAGE_BITMAP,5, 5, LR_MONOCHROME); + m_ahStatusBitmaps[5] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_DND), + IMAGE_BITMAP,5, 5, LR_MONOCHROME); + m_ahStatusBitmaps[6] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_INVISIBLE), + IMAGE_BITMAP,5, 5, LR_MONOCHROME); + m_ahStatusBitmaps[7] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_STATUS_FFC), + IMAGE_BITMAP,5, 5, LR_MONOCHROME); + // Load event bitmaps + m_ahEventBitmaps[0] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_MSG), + IMAGE_BITMAP,6, 6, LR_MONOCHROME); + m_ahEventBitmaps[1] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_CON), + IMAGE_BITMAP,6, 6, LR_MONOCHROME); + m_ahEventBitmaps[2] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_USER), + IMAGE_BITMAP,6, 6, LR_MONOCHROME); + m_ahEventBitmaps[3] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_INFO), + IMAGE_BITMAP,6, 6, LR_MONOCHROME); + + m_ahLargeEventBitmaps[0] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_MSG_LARGE), + IMAGE_BITMAP,8, 8, LR_MONOCHROME); + m_ahLargeEventBitmaps[1] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_CON_LARGE), + IMAGE_BITMAP,8, 8, LR_MONOCHROME); + m_ahLargeEventBitmaps[2] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_USER_LARGE), + IMAGE_BITMAP,8, 8, LR_MONOCHROME); + m_ahLargeEventBitmaps[3] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_EVENT_INFO_LARGE), + IMAGE_BITMAP,8, 8, LR_MONOCHROME); + + + // start the update timer + m_uiTimer = SetTimer(0,0,1000/10,CAppletManager::UpdateTimer); + + + + return true; +} + +//************************************************************************ +// Deinitializes the AppletManager +//************************************************************************ +bool CAppletManager::Shutdown() +{ + if(!IsInitialized()) + return false; + + // stop the update timer + KillTimer(0,m_uiTimer); + + // delete status bitmaps + for(int i=0;i<8;i++) + DeleteObject(m_ahStatusBitmaps[i]); + + // delete event bitmaps + for(int i=0;i<8;i++) + { + DeleteObject(m_ahLargeEventBitmaps[i]); + DeleteObject(m_ahEventBitmaps[i]); + } + + // unhook the events + UnhookEvent(m_hMIHookMessageWindowEvent); + UnhookEvent(m_hMIHookEventAdded); + UnhookEvent(m_hMIHookStatusChanged); + UnhookEvent(m_hMIHookProtoAck); + UnhookEvent(m_hMIHookContactDeleted); + UnhookEvent(m_hMIHookContactAdded); + UnhookEvent(m_hMIHookSettingChanged); + + // unhook all irc protocols, and delete the classes + vector::iterator iter = m_vIRCConnections.begin(); + while(iter != m_vIRCConnections.end()) + { + UnhookEvent((*iter)->hEventHook); + delete *iter; + iter++; + } + m_vIRCConnections.clear(); + + // Deinitialize the screens + m_NotificationScreen.Shutdown(); + m_EventScreen.Shutdown(); + m_ContactlistScreen.Shutdown(); + m_ChatScreen.Shutdown(); + m_CreditsScreen.Shutdown(); + m_ScreensaverScreen.Shutdown(); + + // deinitialize the configuration manager + CConfig::Shutdown(); + + // delete the protocol information + CProtocolData *pProtoData; + for(int i=0;istrProtocol == strProtocol) + return m_vProtocolData[i]; + } + return NULL; +} + +//************************************************************************ +// Updates the AppletManager +//************************************************************************ +bool CAppletManager::Update() +{ + if(!CLCDOutputManager::Update()) + return false; + + // Update Messagejobs + UpdateMessageJobs(); + + // Screensaver detection + BOOL bActive = false; + SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &bActive, 0); + if(bActive != m_bScreensaver) + { + if(CConfig::GetBoolSetting(SCREENSAVER_LOCK)) { + if(!m_bScreensaver) { + ActivateScreensaverScreen(); + } else { + ActivateEventScreen(); + } + } + if(CConfig::GetBoolSetting(CONTROL_BACKLIGHTS)) { + if(GetLCDConnection() && + GetLCDConnection()->GetConnectionType() == TYPE_LOGITECH) + { + CLCDConnectionLogitech *pLCDConnection = (CLCDConnectionLogitech*)GetLCDConnection(); + + // Screensaver starts + if(!m_bScreensaver) + { + m_G15LightStatus = pLCDConnection->GetLightStatus(); + pLCDConnection->SetLCDBacklight(LCD_OFF); + pLCDConnection->SetKBDBacklight(KBD_OFF); + pLCDConnection->SetMKeyLight(0,0,0,0); + } + // Screensaver ends + else + { + SG15LightStatus currentStatus = pLCDConnection->GetLightStatus(); + + if(currentStatus.eLCDBrightness == LCD_OFF) + pLCDConnection->SetLCDBacklight(m_G15LightStatus.eLCDBrightness); + if(currentStatus.eKBDBrightness == KBD_OFF) + pLCDConnection->SetKBDBacklight(m_G15LightStatus.eKBDBrightness); + if(!currentStatus.bMRKey && !currentStatus.bMKey[0] && !currentStatus.bMKey[1] + && !currentStatus.bMKey[2]) + pLCDConnection->SetMKeyLight(m_G15LightStatus.bMKey[0],m_G15LightStatus.bMKey[1],m_G15LightStatus.bMKey[2],m_G15LightStatus.bMRKey); + } + } + } + m_bScreensaver = bActive; + } + + return true; +} + +//************************************************************************ +// Called when the active screen has expired +//************************************************************************ +void CAppletManager::OnScreenExpired(CLCDScreen *pScreen) +{ + // If the notification screen has expired, activate the last active screen + if(pScreen == (CLCDScreen*)&m_NotificationScreen) + { + ActivateScreen(m_pLastScreen); + if(CConfig::GetBoolSetting(TRANSITIONS)) + m_pGfx->StartTransition(); + } +} + +//************************************************************************ +// the update timer's callback function +//************************************************************************ +VOID CALLBACK CAppletManager::UpdateTimer(HWND hwnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime) +{ + CAppletManager::GetInstance()->Update(); +} + +//************************************************************************ +// applies the volumewheel setting +//************************************************************************ +void CAppletManager::SetVolumeWheelHook() +{ + // Set the volumewheel hook + if(GetLCDConnection() && GetLCDConnection()->GetConnectionType() == TYPE_LOGITECH) + { + CLCDConnectionLogitech *pLCDConnection = (CLCDConnectionLogitech*)GetLCDConnection(); + if(pLCDConnection->GetConnectionState() == CONNECTED) + pLCDConnection->SetVolumeWheelHook(CConfig::GetBoolSetting(HOOK_VOLUMEWHEEL)); + } +} + +//************************************************************************ +// Called when the connection state has changed +//************************************************************************ +void CAppletManager::OnConnectionChanged(int iConnectionState) +{ + if(iConnectionState == CONNECTED) + { + SetVolumeWheelHook(); + } + CConfig::OnConnectionChanged(); +} + +//************************************************************************ +// called when the plugin's configuration has changed +//************************************************************************ +void CAppletManager::OnConfigChanged() +{ + GetLCDConnection()->Connect(CConfig::GetIntSetting(DEVICE)); + + m_pGfx->StartTransition(TRANSITION_MORPH); + + // Set the volumewheel hook + SetVolumeWheelHook(); + // send the event to all screens + m_NotificationScreen.OnConfigChanged(); + m_ChatScreen.OnConfigChanged(); + m_EventScreen.OnConfigChanged(); + m_ContactlistScreen.OnConfigChanged(); + m_CreditsScreen.OnConfigChanged(); +} +//************************************************************************ +// activate a screen +//************************************************************************ +void CAppletManager::ActivateScreen(CScreen *pScreen) { + if(GetActiveScreen() && GetActiveScreen() != &m_NotificationScreen) { + m_pLastScreen = (CScreen*)GetActiveScreen(); + } + + CLCDOutputManager::ActivateScreen(pScreen); +} + +//************************************************************************ +// activates the previous screen +//************************************************************************ +void CAppletManager::ActivatePreviousScreen() { + if(m_pLastScreen) { + ActivateScreen(m_pLastScreen); + } +} + +//************************************************************************ +// activates the credits screen +//************************************************************************ +void CAppletManager::ActivateScreensaverScreen() +{ + m_ScreensaverScreen.Reset(); + ActivateScreen(&m_ScreensaverScreen); +} + +//************************************************************************ +// activates the credits screen +//************************************************************************ +void CAppletManager::ActivateCreditsScreen() +{ + m_CreditsScreen.Reset(); + ActivateScreen(&m_CreditsScreen); +} + +//************************************************************************ +// activates the event screen +//************************************************************************ +void CAppletManager::ActivateEventScreen() +{ + m_ChatScreen.SetContact(NULL); + ActivateScreen(&m_EventScreen); + + if(CConfig::GetBoolSetting(TRANSITIONS)) + m_pGfx->StartTransition(); +} + +//************************************************************************ +// activates the contactlist screen +//************************************************************************ +void CAppletManager::ActivateCListScreen() +{ + m_ChatScreen.SetContact(NULL); + m_ContactlistScreen.ResetPosition(); + ActivateScreen(&m_ContactlistScreen); + + if(CConfig::GetBoolSetting(TRANSITIONS)) + m_pGfx->StartTransition(); +} + +//************************************************************************ +// activates the chat screen +//************************************************************************ +bool CAppletManager::ActivateChatScreen(HANDLE hContact) +{ + if(!m_ChatScreen.SetContact(hContact)) + return false; + + m_ContactlistScreen.OnSessionOpened(hContact); + ActivateScreen(&m_ChatScreen); + + if(CConfig::GetBoolSetting(TRANSITIONS)) + m_pGfx->StartTransition(); + return true; +} + +//************************************************************************ +// returns the contacts displayname +//************************************************************************ +tstring CAppletManager::GetContactDisplayname(HANDLE hContact,bool bShortened) +{ + if(!bShortened || !CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF)) + return (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR); + + tstring strNick = GetContactDisplayname(hContact,false); + if(strNick.length() > CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + return strNick.erase(CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + _T("..."); + + return strNick; +} + +//************************************************************************ +// returns the contacts group +//************************************************************************ +tstring CAppletManager::GetContactGroup(HANDLE hContact) +{ + DBVARIANT dbv; + int res = db_get_ts(hContact, "CList", "Group", &dbv); + + tstring strGroup = _T(""); + if(!res) + strGroup = dbv.ptszVal; + + db_free(&dbv); + return strGroup; +} + +//************************************************************************ +// returns the bitmap for the specified event +//************************************************************************ +HBITMAP CAppletManager::GetEventBitmap(EventType eType, bool bLarge) +{ + switch(eType) + { + case EVENT_MSG_RECEIVED: + case EVENT_MSG_SENT: + case EVENT_IRC_RECEIVED: + case EVENT_IRC_SENT: + if(bLarge) + return m_ahLargeEventBitmaps[0]; + else + return m_ahEventBitmaps[0]; + case EVENT_PROTO_STATUS: + case EVENT_PROTO_CONNECTED: + case EVENT_PROTO_DISCONNECTED: + if(bLarge) + return m_ahLargeEventBitmaps[1]; + else + return m_ahEventBitmaps[1]; + case EVENT_STATUS: + case EVENT_SIGNED_ON: + case EVENT_SIGNED_OFF: + if(bLarge) + return m_ahLargeEventBitmaps[2]; + else + return m_ahEventBitmaps[2]; + default: + if(bLarge) + return m_ahLargeEventBitmaps[3]; + else + return m_ahEventBitmaps[3]; + } +} + +//************************************************************************ +// returns the bitmap for the specified status +//************************************************************************ +HBITMAP CAppletManager::GetStatusBitmap(int iStatus) +{ + switch(iStatus) + { + case ID_STATUS_OFFLINE: + return m_ahStatusBitmaps[0]; + case ID_STATUS_ONLINE: + return m_ahStatusBitmaps[1]; + case ID_STATUS_NA: + return m_ahStatusBitmaps[3]; + case ID_STATUS_OCCUPIED: + return m_ahStatusBitmaps[4]; + case ID_STATUS_DND: + return m_ahStatusBitmaps[5]; + case ID_STATUS_INVISIBLE: + return m_ahStatusBitmaps[6]; + case ID_STATUS_FREECHAT: + return m_ahStatusBitmaps[7]; + case ID_STATUS_AWAY: + default: + return m_ahStatusBitmaps[2]; + } +} +//************************************************************************ +// returns a formatted timestamp string +//************************************************************************ +tstring CAppletManager::GetFormattedTimestamp(tm *tm_time) +{ + time_t now; + tm tm_now; + time(&now); + localtime_s(&tm_now,&now); + + TCHAR buffer[128]; + setlocale( LC_ALL, "" ); + + if(tm_time->tm_mday != tm_now.tm_mday || tm_time->tm_mon != tm_now.tm_mon) + { + if(CConfig::GetBoolSetting(TIMESTAMP_SECONDS)) + _tcsftime(buffer,128,_T("[%x %H:%M:%S]"),tm_time); + else + _tcsftime(buffer,128,_T("[%x %H:%M]"),tm_time); + } + else + { + if(CConfig::GetBoolSetting(TIMESTAMP_SECONDS)) + _tcsftime(buffer,128,_T("[%H:%M:%S]"),tm_time); + else + _tcsftime(buffer,128,_T("[%H:%M]"),tm_time); + } + + return toTstring(buffer); +} + +//************************************************************************ +// called to process the specified event +//************************************************************************ +void CAppletManager::HandleEvent(CEvent *pEvent) +{ + TRACE(_T("<< Event: %i\n"),(int)pEvent->eType); + + // check if the event's timestamp needs to be set + if(!pEvent->bTime) + { + time_t now; + time(&now); + localtime_s(&pEvent->Time,&now); + } + // check wether the event needs notification + + // check for protocol filters + if(pEvent->hContact != NULL && pEvent->eType != EVENT_CONTACT_ADDED) + { + char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)pEvent->hContact, 0); + if(szProto == NULL || !CConfig::GetProtocolNotificationFilter(toTstring(szProto))) + pEvent->bNotification = false; + } + pEvent->bLog = pEvent->bNotification; + + if(CAppletManager::IsSubContact(pEvent->hContact)) + { + pEvent->bLog = false; + pEvent->bNotification = false; + } + + // if the applet is in foreground, skip notifications for the chatsession contact + if(pEvent->hContact && GetLCDConnection()->IsForeground() && pEvent->hContact == m_ChatScreen.GetContact() && + (!m_ChatScreen.IsInputActive() || !CConfig::GetBoolSetting(NOTIFY_NO_SKIP_REPLY))) + { + if(pEvent->eType == EVENT_STATUS && CConfig::GetBoolSetting(NOTIFY_SKIP_STATUS)) + pEvent->bNotification = false; + if( pEvent->eType == EVENT_SIGNED_ON && CConfig::GetBoolSetting(NOTIFY_SKIP_SIGNON)) + pEvent->bNotification = false; + if(pEvent->eType == EVENT_SIGNED_OFF && CConfig::GetBoolSetting(NOTIFY_SKIP_SIGNOFF)) + pEvent->bNotification = false; + if((pEvent->eType == EVENT_IRC_RECEIVED || pEvent->eType == EVENT_MSG_RECEIVED) && CConfig::GetBoolSetting(NOTIFY_SKIP_MESSAGES)) + pEvent->bNotification = false; + } + + // send the event to all screens + m_NotificationScreen.OnEventReceived(pEvent); + m_ChatScreen.OnEventReceived(pEvent); + m_EventScreen.OnEventReceived(pEvent); + m_ContactlistScreen.OnEventReceived(pEvent); + + // activate notification screen if neccessary (and screensaverscreen is not active) + if(pEvent->bNotification) + { + if(GetActiveScreen() != (CLCDScreen*)&m_NotificationScreen && GetActiveScreen() != (CLCDScreen*)&m_ScreensaverScreen) + { + m_NotificationScreen.SetAlert(true); + m_NotificationScreen.SetExpiration(CConfig::GetIntSetting(NOTIFY_DURATION)*1000); + ActivateScreen(&m_NotificationScreen); + + if(GetLCDConnection()->IsForeground() && CConfig::GetBoolSetting(TRANSITIONS)) + m_pGfx->StartTransition(); + } + } +} + +bool CAppletManager::IsUtfSendAvailable(HANDLE hContact) { + char* szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if ( szProto == NULL ) + return FALSE; + + return ( CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_4, 0) & PF4_IMSENDUTF ) ? TRUE : FALSE; +} + +//************************************************************************ +// returns the contacts message service name +//************************************************************************ +char *CAppletManager::GetMessageServiceName(HANDLE hContact,bool bIsUnicode) +{ + if(g_bUnicode) { + char szServiceName[100]; + char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + + if(szProto == NULL) + return NULL; + + if (!bIsUnicode) + return PSS_MESSAGE; + + _snprintf(szServiceName, sizeof(szServiceName), "%s%sW", szProto, PSS_MESSAGE); + if (ServiceExists(szServiceName)) + return PSS_MESSAGE "W"; + } else { + return PSS_MESSAGE; + } +} + +//************************************************************************ +// updates all pending message jobs +//************************************************************************ +void CAppletManager::UpdateMessageJobs() +{ + list::iterator iter = m_MessageJobs.begin(); + while(iter != m_MessageJobs.end()) + { + // TODO: Fertigstellen + if((*iter)->dwTimestamp + 15*1000 < GetTickCount()) + { + CEvent Event; + + Event.eType = EVENT_MESSAGE_ACK; + Event.hValue = (*iter)->hEvent; + Event.hContact = (*iter)->hContact; + Event.iValue = ACKRESULT_FAILED; + Event.strValue = TranslateString(_T("Timeout: No response from contact/server")); + + HandleEvent(&Event); + + SMessageJob *pJob = *iter; + m_MessageJobs.erase(iter); + free(pJob->pcBuffer); + delete(pJob); + break; + } + iter++; + } +} + +//************************************************************************ +// adds a message job to the list +//************************************************************************ +void CAppletManager::AddMessageJob(SMessageJob *pJob) +{ + m_MessageJobs.push_back(pJob); +} + +//************************************************************************ +// finishes a message job +//************************************************************************ +void CAppletManager::FinishMessageJob(SMessageJob *pJob) +{ + list::iterator iter = m_MessageJobs.begin(); + while(iter != m_MessageJobs.end()) + { + if((*iter) == pJob) + { + char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)pJob->hContact, 0); + tstring strProto = toTstring(szProto); + CIRCConnection *pIRCCon = GetIRCConnection(strProto); + + // Only add the message to the history if the contact isn't an irc chatroom + if(!(pIRCCon && db_get_b(pJob->hContact, szProto, "ChatRoom", 0) != 0)) + { + // Add the message to the database + DBEVENTINFO dbei = { 0 }; + dbei.cbSize = sizeof(dbei); + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.flags = DBEF_SENT; + dbei.szModule = szProto; + dbei.timestamp = time(NULL); + // Check if protocoll is valid + if(dbei.szModule == NULL) + return; + + if(pJob->dwFlags & PREF_UTF) { + dbei.flags |= DBEF_UTF; + } + + dbei.cbBlob = pJob->iBufferSize; + dbei.pBlob = (PBYTE) pJob->pcBuffer; + + db_event_add(pJob->hContact, &dbei); + } + SMessageJob *pJob = *iter; + m_MessageJobs.erase(iter); + free(pJob->pcBuffer); + delete(pJob); + return; + } + } +} + +//************************************************************************ +// cancels a message job +//************************************************************************ +void CAppletManager::CancelMessageJob(SMessageJob *pJob) +{ + list::iterator iter = m_MessageJobs.begin(); + while(iter != m_MessageJobs.end()) + { + if((*iter) == pJob) + { + SMessageJob *pJob = *iter; + m_MessageJobs.erase(iter); + free(pJob->pcBuffer); + delete(pJob); + return; + } + } +} + +//************************************************************************ +// returns wether or not a contact is a subcontact +//************************************************************************ +bool CAppletManager::IsSubContact(HANDLE hContact) +{ + if(!db_get_b(0, "MetaContacts", "Enabled", 1)) + return false; + bool bIsSubcontact = db_get_b(hContact,"MetaContacts","IsSubcontact",0); + return bIsSubcontact; + // HANDLE hMetaContact = (HANDLE)CallService(MS_MC_GETMETACONTACT, (WPARAM)hContact, NULL); + // return hMetaContact != NULL; +} + +//************************************************************************ +// sends typing notifications to the specified contact +//************************************************************************ +void CAppletManager::SendTypingNotification(HANDLE hContact,bool bEnable) +{ + DWORD protoStatus; + DWORD protoCaps; + DWORD typeCaps; + + if (!hContact) + return; + + // Don't send to protocols who don't support typing + // Don't send to users who are unchecked in the typing notification options + // Don't send to protocols that are offline + // Don't send to users who are not visible and + // Don't send to users who are not on the visible list when you are in invisible mode. + if (!db_get_b(hContact, "SRMsg", "SupportTyping", db_get_b(NULL, "SRMsg", "DefaultTyping", 1))) + return; + + char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if (!szProto) + return; + + protoStatus = CallProtoService(szProto, PS_GETSTATUS, 0, 0); + protoCaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0); + typeCaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_4, 0); + + if (!(typeCaps & PF4_SUPPORTTYPING)) + return; + if (protoStatus < ID_STATUS_ONLINE) + return; + if (protoCaps & PF1_VISLIST && db_get_w(hContact, szProto, "ApparentMode", 0) == ID_STATUS_OFFLINE) + return; + if (protoCaps & PF1_INVISLIST && protoStatus == ID_STATUS_INVISIBLE && db_get_w(hContact, szProto, "ApparentMode", 0) != ID_STATUS_ONLINE) + return; + if (db_get_b(hContact, "CList", "NotOnList", 0) + && !db_get_b(NULL, "SRMsg", "UnknownTyping", 1)) + return; + // End user check + CallService(MS_PROTO_SELFISTYPING, (WPARAM) hContact, bEnable?PROTOTYPE_SELFTYPING_ON:PROTOTYPE_SELFTYPING_OFF); +} + +//************************************************************************ +// sends a message to the specified contact +//************************************************************************ +HANDLE CAppletManager::SendMessageToContact(HANDLE hContact,tstring strMessage) +{ + string strAscii = toNarrowString(strMessage); + int bufSize = lstrlenA(strAscii.c_str())+1; + SMessageJob *pJob = new SMessageJob(); + pJob->dwTimestamp = GetTickCount(); + pJob->hContact = hContact; + + char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + tstring strProto = toTstring(szProto); + + CIRCConnection *pIRCCon = CAppletManager::GetInstance()->GetIRCConnection(strProto); + + if(pIRCCon && db_get_b(hContact, szProto, "ChatRoom", 0) != 0) + { + GCDEST gcd = {0}; + GCEVENT gce = {0}; + + DBVARIANT dbv; + if (!db_get((HANDLE)hContact, szProto, "Nick", &dbv) && dbv.type == DBVT_ASCIIZ ) + gcd.pszID = dbv.pszVal; + else + return NULL; + + string strID = string(gcd.pszID) + " - " + toNarrowString(pIRCCon->strNetwork).c_str(); + gcd.pszID = (char*)strID.c_str(); + gcd.pszModule = szProto; + gcd.iType = GC_EVENT_SENDMESSAGE; + + gce.cbSize = sizeof(GCEVENT); + gce.pDest = &gcd; + gce.pszStatus = ""; + // gce.bAddToLog = true; + gce.pszUserInfo = NULL; + + gce.pszText = (char *)strAscii.c_str(); + + gce.dwItemData = NULL; + gce.time = time(NULL); + gce.bIsMe = true; + + CallService(MS_GC_EVENT, NULL, (LPARAM) &gce); + + pJob->hEvent = NULL; + } + else + { + DWORD pref = 0; + bool bIsUnicode = false; + if(CAppletManager::IsUtfSendAvailable(pJob->hContact)) { + pref = PREF_UTF; + char* szMsgUtf = NULL; + #if defined( _UNICODE ) + szMsgUtf = mir_utf8encodeW( strMessage.c_str()); + #else + int codepage = CallService( MS_LANGPACK_GETCODEPAGE, 0, 0 ); + szMsgUtf = mir_utf8encodecp(strMessage.c_str(), codepage); + #endif + + pJob->iBufferSize = strlen(szMsgUtf)+1; + pJob->pcBuffer = (char *)malloc(pJob->iBufferSize); + pJob->dwFlags = PREF_UTF; + + memcpy(pJob->pcBuffer,szMsgUtf,pJob->iBufferSize); + mir_free(szMsgUtf); + } else { + +#ifdef _UNICODE + bIsUnicode = !IsUnicodeAscii(strMessage.c_str(),lstrlen(strMessage.c_str())); +#endif + if(bIsUnicode) { + pref = PREF_UNICODE; + pJob->iBufferSize = bufSize * (sizeof(TCHAR) + 1); + } else { + pJob->iBufferSize = bufSize; + } + pJob->pcBuffer = (char *)malloc(pJob->iBufferSize); + memcpy(pJob->pcBuffer,strAscii.c_str(),bufSize); + + if(bIsUnicode) { + memcpy(&pJob->pcBuffer[bufSize],strMessage.c_str(),bufSize*sizeof(TCHAR)); + } + } + char *szService = CAppletManager::GetMessageServiceName(pJob->hContact,bIsUnicode); + + if(szService == NULL) + { + free(pJob->pcBuffer); + pJob->pcBuffer == NULL; + return NULL; + } + pJob->hEvent = (HANDLE) CallContactService(pJob->hContact, szService , pref, (LPARAM)pJob->pcBuffer ); + CAppletManager::GetInstance()->AddMessageJob(pJob); + } + + + return pJob->hEvent; +} + +//************************************************************************ +// check if a contacts message window is opened +//************************************************************************ +bool CAppletManager::IsMessageWindowOpen(HANDLE hContact) +{ + MessageWindowInputData mwid; + mwid.cbSize = sizeof(MessageWindowInputData); + mwid.hContact = hContact; + mwid.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH; + + MessageWindowData mwd; + mwd.cbSize = sizeof(MessageWindowData); + CallService(MS_MSG_GETWINDOWDATA,(WPARAM)&mwid,(LPARAM)&mwd); + if(mwd.uState & MSG_WINDOW_STATE_EXISTS) + return true; + return false; +} + +//************************************************************************ +// marks the given message as read +//************************************************************************ +void CAppletManager::MarkMessageAsRead(HANDLE hContact,HANDLE hEvent) +{ + db_event_markRead(hContact, hEvent); + CallService(MS_CLIST_REMOVEEVENT, (WPARAM)hContact, (LPARAM)hEvent); +} + +//************************************************************************ +// translates the given database event +//************************************************************************ +bool CAppletManager::TranslateDBEvent(CEvent *pEvent,WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE)wParam; + HANDLE hdbevent = (HANDLE)lParam; + + + // Create struct for dbevent + DBEVENTINFO dbevent; + ZeroMemory(&dbevent, sizeof(dbevent)); + //dbevent.flags |= PREF_UNICODE; + dbevent.cbSize = sizeof(dbevent); + dbevent.cbBlob = db_event_getBlobSize(hdbevent); + if(dbevent.cbBlob == -1) // hdbevent is invalid + { + return false; + } + dbevent.pBlob = (PBYTE)malloc(dbevent.cbBlob); + if(db_event_get(hdbevent, &dbevent) != 0) + { + free(dbevent.pBlob); + return false; + } + + pEvent->dwFlags = dbevent.flags; + pEvent->hContact = hContact; + pEvent->hValue = hdbevent; + + time_t timestamp = (time_t)dbevent.timestamp; + localtime_s(&pEvent->Time,×tamp); + pEvent->bTime = true; + /* + if(dbevent.eventType == EVENTTYPE_MESSAGE && dbevent.flags & DBEF_READ) { + free(dbevent.pBlob); + return false; + } + */ + // Skip events from the user except for messages + if(dbevent.eventType != EVENTTYPE_MESSAGE && (dbevent.flags & DBEF_SENT)) + { + free(dbevent.pBlob); + return false; + } + + int msglen = 0; + + tstring strName = CAppletManager::GetContactDisplayname(hContact,true); + + switch(dbevent.eventType) + { + case EVENTTYPE_MESSAGE: + msglen = strlen((char *) dbevent.pBlob) + 1; +#ifdef _UNICODE + if (dbevent.flags & DBEF_UTF) { + pEvent->strValue = Utf8_Decode((char*)dbevent.pBlob); + } else if ((int) dbevent.cbBlob == msglen*3){ + pEvent->strValue = (TCHAR *) & dbevent.pBlob[msglen]; + } else { + pEvent->strValue = toTstring((char*)dbevent.pBlob); + } +#else + pEvent->strValue = toTstring((char*)dbevent.pBlob); +#endif + pEvent->eType = (dbevent.flags & DBEF_SENT) ? EVENT_MSG_SENT:EVENT_MSG_RECEIVED; + if(pEvent->eType == EVENT_MSG_RECEIVED) + { + pEvent->dwFlags = MSG_UNREAD; + if(CConfig::GetBoolSetting(NOTIFY_MESSAGES)) + pEvent->bNotification = true; + } + + pEvent->strDescription = strName + _T(": ") +pEvent->strValue; + pEvent->strSummary = TranslateString(_T("New message from %s"),strName.c_str()); + break; + case EVENTTYPE_URL: + if(CConfig::GetBoolSetting(NOTIFY_URL)) + pEvent->bNotification = true; + + pEvent->eType = EVENT_URL; + pEvent->strDescription = TranslateString(_T("Incoming URL from %s"),strName.c_str()); + break; + case EVENTTYPE_CONTACTS: + if(CConfig::GetBoolSetting(NOTIFY_CONTACTS)) + pEvent->bNotification = true; + + pEvent->strDescription = TranslateString(_T("Incoming contacts from %s"),strName.c_str()); + pEvent->eType = EVENT_CONTACTS; + break; + case EVENTTYPE_ADDED: + if(CConfig::GetBoolSetting(NOTIFY_CONTACTS)) + pEvent->bNotification = true; + + pEvent->strDescription = TranslateString(_T("You were added by %s"),strName.c_str()); + pEvent->eType = EVENT_ADDED; + break; + case EVENTTYPE_AUTHREQUEST: + if(CConfig::GetBoolSetting(NOTIFY_CONTACTS)) + pEvent->bNotification = true; + + pEvent->strDescription = TranslateString(_T("Incoming Authrequest!")); + pEvent->eType = EVENT_AUTHREQUEST; + break; + case EVENTTYPE_FILE: + if(CConfig::GetBoolSetting(NOTIFY_FILE)) + pEvent->bNotification = true; + + pEvent->strDescription = TranslateString(_T("Incoming file from %s"),strName.c_str()); + pEvent->eType = EVENT_FILE; + break; + default: + return false; + break; + } + + if(CConfig::GetBoolSetting(NOTIFY_SHOWPROTO)) + { + char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)pEvent->hContact, 0); + pEvent->strDescription = _T("(")+toTstring(szProto)+_T(") ") + pEvent->strDescription; + } + + // Clean up + free(dbevent.pBlob); + return true; +} + +//************************************************************************ +// removes IRC formatting tags from the string +//************************************************************************ +tstring CAppletManager::StripIRCFormatting(tstring strText) +{ + tstring::size_type End=0,Start=0; + tstring strEntity = _T(""); + tstring strReplace = _T(""); + tstring::size_type len = strText.length(); + + int i = 0; + while(i < strText.length()) + { + Start = strText.find(_T("%"),i); + if(Start != string::npos && Start < strText.length() - 1) + { + strEntity = strText[Start+1]; + if(strEntity == _T("%")) + { + strText.replace(Start,2,_T("%")); + i = Start +1; + } + /* + else if(strEntity == _T("b") || strEntity == _T("B") || + strEntity == _T("i") || strEntity == _T("I") || + strEntity ==_T("u") || strEntity == _T("U") || + strEntity == _T("C") ||strEntity == _T("F")) + { + strText.erase(Start,2); + i = Start; + } + */ + else if(strEntity == _T("c") || strEntity == _T("f")) + { + strText.erase(Start,4); + i = Start; + } + else + { + strText.erase(Start,2); + i = Start; + } + } + else + break; + } + + return strText; +} + +//************************************************************************ +// returns the IRC connection class for the specified protocol +//************************************************************************ +CIRCConnection *CAppletManager::GetIRCConnection(tstring strProtocol) +{ + vector::iterator iter = m_vIRCConnections.begin(); + while(iter != m_vIRCConnections.end()) + { + if((*iter)->strProtocol == strProtocol) + return *iter; + iter++; + } + return NULL; +} + +//************************************************************************ +// creates the IRC connection class for the specified protocol +//************************************************************************ +CIRCConnection *CAppletManager::CreateIRCConnection(tstring strProtocol) +{ + char buffer[128]; + sprintf(buffer,"%s/HookableEvents",toNarrowString(strProtocol).c_str()); + + // try to hook the events + HANDLE hEventHook = HookEvent(buffer,CAppletManager::HookChatInbound); + // if the hook could not be established, the protocol is not an IRC instance + if(!hEventHook) + return NULL; + + TRACE(_T("Patched IRC-Connection found: %s\n"),strProtocol.c_str()); + CIRCConnection *pIRCCon = new CIRCConnection(); + pIRCCon->strProtocol = strProtocol; + pIRCCon->hEventHook = hEventHook; + pIRCCon->strNetwork = _T(""); + + m_vIRCConnections.push_back(pIRCCon); + + return pIRCCon; +} + +//************************************************************************ +// returns the history class for the specified IRC channel +//************************************************************************ +CIRCHistory *CAppletManager::GetIRCHistory(HANDLE hContact) +{ + list::iterator iter = m_LIRCHistorys.begin(); + while(iter != m_LIRCHistorys.end()) + { + if((*iter)->hContact == hContact) + return *iter; + iter++; + } + return NULL; +} + +CIRCHistory *CAppletManager::GetIRCHistoryByName(tstring strProtocol,tstring strChannel) +{ + list::iterator iter = m_LIRCHistorys.begin(); + while(iter != m_LIRCHistorys.end()) + { + if((*iter)->strChannel == strChannel && (*iter)->strProtocol == strProtocol) + return *iter; + iter++; + } + return NULL; +} + +//************************************************************************ +// deletes the history class for the specified IRC channel +//************************************************************************ +void CAppletManager::DeleteIRCHistory(HANDLE hContact) +{ + list::iterator iter = m_LIRCHistorys.begin(); + while(iter != m_LIRCHistorys.end()) + { + if((*iter)->hContact == hContact) + { + CIRCHistory *pHistory = *iter; + pHistory->LMessages.clear(); + pHistory->LUsers.clear(); + + m_LIRCHistorys.erase(iter); + + delete pHistory; + + return; + } + iter++; + } +} + +//************************************************************************ +// creates a history class for the specified IRC channel +//************************************************************************ +CIRCHistory *CAppletManager::CreateIRCHistory(HANDLE hContact,tstring strChannel) +{ + char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if(!szProto) + return NULL; + + CIRCHistory *pHistory = GetIRCHistoryByName(toTstring(szProto),strChannel); + if(pHistory) + { + pHistory->hContact = hContact; + return pHistory; + } + + pHistory = new CIRCHistory(); + pHistory->hContact = hContact; + pHistory->strChannel = strChannel; + pHistory->strProtocol = toTstring(szProto); + + m_LIRCHistorys.push_back(pHistory); + + return pHistory; +} + +CIRCHistory *CAppletManager::CreateIRCHistoryByName(tstring strProtocol,tstring strChannel) +{ + CIRCHistory *pHistory = GetIRCHistoryByName(strProtocol,strChannel); + if(pHistory) + return pHistory; + + pHistory = new CIRCHistory(); + pHistory->hContact = NULL; + pHistory->strChannel = strChannel; + pHistory->strProtocol = strProtocol; + + m_LIRCHistorys.push_back(pHistory); + + return pHistory; +} + +//######################################################################## +// hook functions +//######################################################################## + +//************************************************************************ +// inbound chat event hook function +//************************************************************************ +int CAppletManager::HookChatInbound(WPARAM wParam,LPARAM lParam) +{ + GCEVENT *gce = (GCEVENT*)lParam; + GCDEST *gcd = (GCDEST*)gce->pDest; + + if(gce == NULL || gcd == NULL) + TRACE(_T("<< [%s] skipping invalid IRC event\n")); + + TRACE(_T("<< [%s:%s] IRC event %04X\n"),toTstring(gcd->pszModule).c_str(),toTstring(gcd->pszID).c_str(),gcd->iType); + + // get the matching irc connection entry + CIRCConnection *pIRCCon = CAppletManager::GetInstance()->GetIRCConnection(toTstring(gcd->pszModule)); + if(!pIRCCon) + { + TRACE(_T("<< [%s] IRC connection not found, skipping event\n"),toTstring(gcd->pszModule).c_str()); + return 0; + } + + // fetch the network name + if(gcd->iType == GC_EVENT_CHANGESESSIONAME) + { + if(!_tcsicmp(gcd->ptszID,_T("Network log"))) + { + pIRCCon->strNetwork = toTstring(gce->ptszText); + TRACE(_T("\t Found network identifier: %s\n"),pIRCCon->strNetwork.c_str()); + return 0; + } + } + + CEvent Event; + if(gce->bIsMe) + Event.eType = EVENT_IRC_SENT; + else + Event.eType = EVENT_IRC_RECEIVED; + Event.iValue = gcd->iType; + Event.hValue = (HANDLE)lParam; + + CIRCHistory *pHistory = NULL; + if(gcd->ptszID) + { + tstring strChannel = toTstring(gcd->ptszID); + tstring::size_type pos = strChannel.find('-'); + if(pos != tstring::npos) + strChannel = strChannel.substr(0,pos-1); + else + { + if(_tcsicmp(gcd->ptszID,_T("Network log"))) + TRACE(_T("\t WARNING: ignoring unknown event!\n")); + return 0; + } + pHistory = CAppletManager::GetInstance()->GetIRCHistoryByName(pIRCCon->strProtocol,strChannel); + if(!pHistory) + { + if(gcd->iType == GC_EVENT_JOIN) + { + pHistory = CAppletManager::GetInstance()->CreateIRCHistoryByName(pIRCCon->strProtocol,strChannel); + if(pHistory) + pHistory->LUsers.push_back(toTstring(gce->ptszNick)); + } + return 0; + } + Event.hContact = pHistory->hContact; + } + else if(gcd->iType != GC_EVENT_INFORMATION) + { + TRACE(_T("\t WARNING: ignoring unknown event!\n")); + return 0; + } + else + Event.hContact = NULL; + + // Ignore events from hidden chatrooms, except for join events + if(gcd->ptszID != NULL && db_get_b(Event.hContact,"CList","Hidden",0)) + { + if(gcd->iType == GC_EVENT_JOIN && pHistory) + pHistory->LUsers.push_back(toTstring(gce->ptszNick)); + + TRACE(_T("\t Chatroom is hidden, skipping event!\n")); + return 0; + } + + tstring strText = StripIRCFormatting(toTstring(gce->ptszText)); + tstring strNick = toTstring(gce->ptszNick); + tstring strStatus = toTstring(gce->ptszStatus); + + if(CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF) && strNick.length() > CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + strNick = strNick.erase(CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + _T("..."); + + TRACE(_T("\t Handling event...\t")); + + switch(gcd->iType) + { + case GC_EVENT_INFORMATION: + if(CConfig::GetBoolSetting(NOTIFY_IRC_CHANNEL)) + Event.bNotification = true; + + if(strText.find(_T("CTCP")) == 0) + Event.strValue = _T("--> ") + strText; + else + Event.strValue = strText; + + break; + case GC_EVENT_ACTION: + if(CConfig::GetBoolSetting(NOTIFY_IRC_EMOTES)) + Event.bNotification = true; + Event.strValue = strNick + _T(" ") + strText; + break; + case GC_EVENT_MESSAGE: + if(CConfig::GetBoolSetting(NOTIFY_IRC_MESSAGES)) + Event.bNotification = true; + Event.strValue = strNick + _T(": ") + strText; + break; + case GC_EVENT_JOIN: + // Add the user to the list + pHistory->LUsers.push_back(toTstring(gce->ptszNick)); + + if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS)) + Event.bNotification = true; + // Skip join event for user + if(gce->bIsMe) + return 0; + Event.strValue = TranslateString(_T("%s has joined the channel"),strNick.c_str()); + + break; + case GC_EVENT_PART: + { + if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS)) + Event.bNotification = true; + tstring strFullNick = toTstring(gce->ptszNick); + Event.strValue = TranslateString(strText.empty()?_T("%s has left"):_T("%s has left: %s"),strNick.c_str(),strText.c_str()); + if(pHistory) + { + // Remove the user from the list + list::iterator iter = pHistory->LUsers.begin(); + while(iter != pHistory->LUsers.end()) + { + if((*iter) == strFullNick) + { + pHistory->LUsers.erase(iter); + break; + } + iter++; + } + } + break; + } + case GC_EVENT_QUIT: + if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS)) + Event.bNotification = true; + Event.strValue = TranslateString(strText.empty()?_T("%s has disconnected"):_T("%s has disconnected: %s"),strNick.c_str(),strText.c_str()); + break; + case GC_EVENT_KICK: + if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS)) + Event.bNotification = true; + Event.strValue = TranslateString(_T("%s has kicked %s: %s"),strStatus.c_str(),strNick.c_str(),strText.c_str()); + break; + case GC_EVENT_NICK: + { + if(CConfig::GetBoolSetting(NOTIFY_IRC_USERS)) + Event.bNotification = true; + tstring strFullNick = toTstring(gce->ptszNick); + + if(CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF) && strText.length() > CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + strText = strText.erase(CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + _T("..."); + + Event.strValue = TranslateString(_T("%s is now known as %s"),strNick.c_str(),strText.c_str()); + if(pHistory) + { + // change the nick in the userlist + list::iterator iter = pHistory->LUsers.begin(); + while(iter != pHistory->LUsers.end()) + { + if((*iter) == strFullNick) + (*iter) = strText; + iter++; + } + } + break; + } + case GC_EVENT_NOTICE: + if(CConfig::GetBoolSetting(NOTIFY_IRC_NOTICES)) + Event.bNotification = true; + Event.strValue = TranslateString(_T("Notice from %s: %s"),strNick.c_str(),strText.c_str()); + break; + case GC_EVENT_TOPIC: + if(CConfig::GetBoolSetting(NOTIFY_IRC_CHANNEL)) + Event.bNotification = true; + Event.strValue = TranslateString(_T("Topic is now '%s' (set by %s)"),strText.c_str(),strNick.c_str()); + break; + case GC_EVENT_ADDSTATUS: + { + if(CConfig::GetBoolSetting(NOTIFY_IRC_STATUS)) + Event.bNotification = true; + tstring strNick2 = toTstring(gce->ptszStatus); + if(CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF) && strNick2.length() > CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + strNick2 = strNick2.erase(CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + _T("..."); + + Event.strValue = TranslateString(_T("%s enables '%s' for %s"),strText.c_str(),strNick2.c_str(),strNick.c_str()); + break; + } + case GC_EVENT_REMOVESTATUS: + { + if(CConfig::GetBoolSetting(NOTIFY_IRC_STATUS)) + Event.bNotification = true; + tstring strNick2 = toTstring(gce->ptszStatus); + if(CConfig::GetBoolSetting(NOTIFY_NICKCUTOFF) && strNick2.length() > CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + strNick2 = strNick2.erase(CConfig::GetIntSetting(NOTIFY_NICKCUTOFF_OFFSET)) + _T("..."); + + Event.strValue = TranslateString(_T("%s disables '%s' for %s"),strText.c_str(),strNick2.c_str(),strNick.c_str()); + break; + } + default: + TRACE(_T("OK!\n")); + return 0; + } + if(gce->bIsMe || gcd->ptszID == NULL) + Event.bNotification = false; + + // set the event's timestamp + Event.bTime = true; + time_t now; + time(&now); + localtime_s(&Event.Time,&now); + + SIRCMessage IRCMsg; + IRCMsg.bIsMe = gce->bIsMe; + IRCMsg.strMessage = Event.strValue; + IRCMsg.Time = Event.Time; + + if(pHistory) + { + pHistory->LMessages.push_back(IRCMsg); + + // Limit the size to the session logsize + if(pHistory->LMessages.size() > CConfig::GetIntSetting(SESSION_LOGSIZE)) + pHistory->LMessages.pop_front(); + } + else if(gce->ptszNick && gcd->iType == GC_EVENT_QUIT) + { + tstring strNick = toTstring(gce->ptszNick); + + if(!CAppletManager::GetInstance()->m_LIRCHistorys.empty()) + { + list::iterator iter = CAppletManager::GetInstance()->m_LIRCHistorys.begin(); + list::iterator nickiter; + while(iter != CAppletManager::GetInstance()->m_LIRCHistorys.end()) + { + nickiter = (*iter)->LUsers.begin(); + while(nickiter != (*iter)->LUsers.end()) + { + if((*nickiter) == strNick) + { + (*iter)->LMessages.push_back(IRCMsg); + // Limit the size to the session logsize + if((*iter)->LMessages.size() > CConfig::GetIntSetting(SESSION_LOGSIZE)) + (*iter)->LMessages.pop_front(); + + (*iter)->LUsers.erase(nickiter); + + Event.hContact = (*iter)->hContact; + tstring strName = CAppletManager::GetContactDisplayname((*iter)->hContact,true); + Event.strDescription = strName + _T(" - ")+Event.strValue; + Event.strSummary = _T("(") + toTstring(gcd->pszModule) + _T(") ")+strName; + CAppletManager::GetInstance()->HandleEvent(&Event); + break; + } + nickiter++; + } + iter++; + } + } + TRACE(_T("OK!\n")); + return 0; + } + else if(gcd->ptszID != NULL) + { + TRACE(_T("OK!\n")); + return 0; + } + + if(pHistory) + { + tstring strChannel = pHistory->strChannel; + if(CConfig::GetBoolSetting(NOTIFY_CHANNELCUTOFF) && strNick.length() > CConfig::GetIntSetting(NOTIFY_CHANNELCUTOFF_OFFSET)) { + strChannel = strChannel.erase(CConfig::GetIntSetting(NOTIFY_CHANNELCUTOFF_OFFSET)) + _T("..."); + } + Event.strDescription = strChannel + _T(" - ")+Event.strValue; + Event.strSummary = _T("(") + toTstring(gcd->pszModule) + _T(") ")+pHistory->strChannel; + } + else + Event.strDescription = Event.strValue; + + TRACE(_T("OK!\n")); + + CAppletManager::GetInstance()->HandleEvent(&Event); + + return 0; +} + +//************************************************************************ +// message window event hook function +//************************************************************************ +int CAppletManager::HookMessageWindowEvent(WPARAM wParam, LPARAM lParam) +{ + MessageWindowEventData *mwed = (MessageWindowEventData*)lParam; + CEvent Event; + + Event.eType = EVENT_MESSAGEWINDOW; + Event.hContact = mwed->hContact; + Event.iValue = mwed->uType; + + CAppletManager::GetInstance()->HandleEvent(&Event); + + return 0; +} + + +//************************************************************************ +// contact typing notification hook function +//************************************************************************ +int CAppletManager::HookContactIsTyping(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE)wParam; + int iState = (int)lParam; + + CEvent Event; + + Event.eType = EVENT_TYPING_NOTIFICATION; + Event.hContact = hContact; + Event.iValue = iState; + + CAppletManager::GetInstance()->HandleEvent(&Event); + return 0; +} + +//************************************************************************ +// new event hook function +//************************************************************************ +int CAppletManager::HookEventAdded(WPARAM wParam, LPARAM lParam) +{ + CEvent Event; + + if(CAppletManager::TranslateDBEvent(&Event,wParam,lParam)) + CAppletManager::GetInstance()->HandleEvent(&Event); + + return 0; +} + +//************************************************************************ +// contact status change hook function +//************************************************************************ +int CAppletManager::HookStatusChanged(WPARAM wParam, LPARAM lParam) +{ + DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam; + + if ((wParam == 0) || (strcmp(cws->szSetting,"Status") != NULL)) + return 0; + + + // Prepare message and append to queue + CEvent Event; + Event.hContact = (HANDLE)wParam; + int iStatus = cws->value.wVal; + Event.iValue = iStatus; + + int iOldStatus = CAppletManager::GetInstance()->m_ContactlistScreen.GetContactStatus(Event.hContact); + + char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)Event.hContact, 0); + tstring strProto = toTstring(szProto); + + CProtocolData *pProtocolData = CAppletManager::GetInstance()->GetProtocolData(toTstring(szProto)); + if(pProtocolData == NULL) + return false; + + // Fetch the contacts name + tstring strName = CAppletManager::GetContactDisplayname(Event.hContact,true); + + // Get status String + Event.strValue = toTstring((char *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iStatus, 0)); + + // check if this is an irc protocol + CIRCConnection *pIRCCon = CAppletManager::GetInstance()->GetIRCConnection(strProto); + + // Contact signed on + if(iOldStatus == ID_STATUS_OFFLINE && iStatus != ID_STATUS_OFFLINE) + { + if(CConfig::GetBoolSetting(NOTIFY_SIGNOFF)) + Event.bNotification = true; + + Event.eType = EVENT_SIGNED_ON; + if(pIRCCon && db_get_b(Event.hContact, szProto, "ChatRoom", 0) != 0) + { + Event.strDescription = TranslateString(_T("Joined %s"),strName.c_str()); + + DBVARIANT dbv; + if (db_get_ts(Event.hContact, szProto, "Nick", &dbv)) + return 0; + CAppletManager::GetInstance()->CreateIRCHistory(Event.hContact,dbv.ptszVal); + db_free(&dbv); + } + else + Event.strDescription = TranslateString(_T("%s signed on (%s)"),strName.c_str(),Event.strValue.c_str()); + } + // Contact signed off + else if(iStatus == ID_STATUS_OFFLINE && iOldStatus != ID_STATUS_OFFLINE) + { + if(CConfig::GetBoolSetting(NOTIFY_SIGNON)) + Event.bNotification = true; + + Event.eType = EVENT_SIGNED_OFF; + if(pIRCCon && db_get_b(Event.hContact, szProto, "ChatRoom", 0) != 0) + { + Event.strDescription = TranslateString(_T("Left %s"),strName.c_str()); + // delete IRC-Channel history + CAppletManager::GetInstance()->DeleteIRCHistory(Event.hContact); + } + else + Event.strDescription = TranslateString(_T("%s signed off"),strName.c_str()); + } + // Contact changed status + else if(iStatus != iOldStatus) + { + if(CConfig::GetBoolSetting(NOTIFY_STATUS)) + Event.bNotification = true; + + Event.eType = EVENT_STATUS; + Event.strDescription = TranslateString(_T("%s is now %s"),strName.c_str(),Event.strValue.c_str()); + } + // ignore remaining events + else + return 0; + + if(CConfig::GetBoolSetting(NOTIFY_SHOWPROTO)) + Event.strDescription = _T("(")+strProto+_T(") ") + Event.strDescription; + + + + Event.strSummary = TranslateString(_T("Contactlist event")); + + // Block notifications after connecting/disconnecting + if(pProtocolData->iStatus == ID_STATUS_OFFLINE || + pProtocolData->lTimeStamp + PROTOCOL_NOTIFY_DELAY > GetTickCount()) + Event.bNotification = false; + + //CAppletManager::GetInstance()->ActivateNotificationScreen(&Event); + CAppletManager::GetInstance()->HandleEvent(&Event); + + return 0; +} + +//************************************************************************ +// protocoll ack hook function +//************************************************************************ +int CAppletManager::HookProtoAck(WPARAM wParam, LPARAM lParam) +{ + ACKDATA *pAck = (ACKDATA *) lParam; + + if(lParam == 0) + return 0; + + // Prepare message and append to queue + CEvent Event; + + // Message job handling + if(pAck->type == ACKTYPE_MESSAGE) + { + list::iterator iter = CAppletManager::GetInstance()->m_MessageJobs.begin(); + while(iter != CAppletManager::GetInstance()->m_MessageJobs.end()) + { + if((*iter)->hEvent == pAck->hProcess && (*iter)->hContact == pAck->hContact) + { + Event.eType = EVENT_MESSAGE_ACK; + Event.hValue = pAck->hProcess; + Event.hContact = pAck->hContact; + Event.iValue = pAck->result; + if(pAck->lParam != 0) + Event.strValue = toTstring((char*)pAck->lParam); + else + Event.strValue = _T(""); + + if(Event.iValue == ACKRESULT_SUCCESS) + CAppletManager::GetInstance()->FinishMessageJob((*iter)); + else + CAppletManager::GetInstance()->CancelMessageJob((*iter)); + + CAppletManager::GetInstance()->HandleEvent(&Event); + + return 0; + } + iter++; + } + } + // protocol status changes + else if(pAck->type == ACKTYPE_STATUS && pAck->result == ACKRESULT_SUCCESS) + { + int iOldStatus = (int)pAck->hProcess; + int iNewStatus = pAck->lParam; + + tstring strProto = toTstring(pAck->szModule); + + // ignore metacontacts status changes + if(toLower(strProto) == _T("metacontacts")) + return 0; + + CProtocolData *pProtoData = CAppletManager::GetInstance()->GetProtocolData(strProto); + if(pProtoData == NULL) + return 0; + + if(iNewStatus == ID_STATUS_CONNECTING) + return 0; + + if(iNewStatus == ID_STATUS_OFFLINE) + { + if(CConfig::GetBoolSetting(NOTIFY_PROTO_SIGNOFF)) + Event.bNotification = true; + Event.eType = EVENT_PROTO_DISCONNECTED; + } + else if(iNewStatus != ID_STATUS_OFFLINE && iOldStatus == ID_STATUS_CONNECTING) + { + if(CConfig::GetBoolSetting(NOTIFY_PROTO_SIGNON)) + Event.bNotification = true; + Event.eType = EVENT_PROTO_CONNECTED; + } + else + { + if(CConfig::GetBoolSetting(NOTIFY_PROTO_STATUS)) + Event.bNotification = true; + Event.eType = EVENT_PROTO_STATUS; + } + + // Skip connecting status + if(iNewStatus == ID_STATUS_CONNECTING) + return 0; + + pProtoData->iStatus = iNewStatus; + + Event.iValue = iNewStatus; + Event.strValue = strProto; + + // set the event description / summary + tstring strStatus = toTstring((char *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iNewStatus, 0)); + Event.strDescription = _T("(") + Event.strValue + _T(") ")+ TranslateString(_T("You are now %s"),strStatus.c_str()); + Event.strSummary = TranslateString(_T("Protocol status change")); + + if(Event.eType != EVENT_PROTO_STATUS) + pProtoData->lTimeStamp = GetTickCount(); + + CAppletManager::GetInstance()->HandleEvent(&Event); + //CAppletManager::GetInstance()->ActivateNotificationScreen(&Event); + } + + return 0; +} + +//************************************************************************ +// contact added hook function +//************************************************************************ +int CAppletManager::HookContactAdded(WPARAM wParam, LPARAM lParam) +{ + CEvent Event; + Event.eType = EVENT_CONTACT_ADDED; + Event.hContact = (HANDLE)wParam; + + CAppletManager::GetInstance()->HandleEvent(&Event); + return 0; +} + +//************************************************************************ +// contact deleted hook function +//************************************************************************ +int CAppletManager::HookContactDeleted(WPARAM wParam, LPARAM lParam) +{ + CEvent Event; + Event.eType = EVENT_CONTACT_DELETED; + Event.hContact = (HANDLE)wParam; + Event.bNotification = CConfig::GetBoolSetting(NOTIFY_CONTACTS); + Event.bLog = Event.bNotification; + + tstring strName = CAppletManager::GetContactDisplayname(Event.hContact,true); + + Event.strDescription = TranslateString(_T("%s was deleted from contactlist!"),strName.c_str()); + + CAppletManager::GetInstance()->HandleEvent(&Event); + return 0; +} + +//************************************************************************ +// setting changed hook function +//************************************************************************ +int CAppletManager::HookSettingChanged(WPARAM wParam,LPARAM lParam) +{ + DBCONTACTWRITESETTING *dbcws = (DBCONTACTWRITESETTING*)lParam; + + CEvent Event; + Event.hContact = (HANDLE)wParam; + + if(!lstrcmpA(dbcws->szModule,"MetaContacts")) + { + //if(!lstrcmpA(dbcws->szSetting,"Enabled")) { + // CAppletManager::GetInstance()->OnConfigChanged(); + // return 0; + //} else + if(!lstrcmpA(dbcws->szSetting,"IsSubcontact")) { + Event.eType = EVENT_CONTACT_GROUP; + DBVARIANT dbv; + int res = db_get_ts((HANDLE)wParam, "CList", "Group", &dbv); + if(!res) + Event.strValue = dbv.ptszVal; + db_free(&dbv); + } else { + return 0; + } + } + else if(!lstrcmpA(dbcws->szSetting,"Nick") || !lstrcmpA(dbcws->szSetting,"MyHandle")) + { + DBVARIANT dbv={0}; + // if the protocol nick has changed, check if a custom handle is set + if(!lstrcmpA(dbcws->szSetting,"Nick")) + { + if (!db_get_ts(Event.hContact, "CList", "MyHandle", &dbv)) + { + // handle found, ignore this event + if(dbv.pszVal && strlen(dbv.pszVal)>0) + return 0; + } + db_free(&dbv); + } + + Event.eType = EVENT_CONTACT_NICK; + if(dbcws->value.type != DBVT_DELETED && dbcws->value.pszVal && strlen(dbcws->value.pszVal)>0) + { +#ifdef _UNICODE + if(dbcws->value.type == DBVT_UTF8) + Event.strValue = Utf8_Decode(dbcws->value.pszVal); + else +#endif + Event.strValue = toTstring(dbcws->value.pszVal); + } + else + { + char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)Event.hContact, 0); + if (db_get_ts(Event.hContact, szProto, "Nick", &dbv)) + return 0; + Event.strValue = dbv.ptszVal; + db_free(&dbv); + } + } + else if(!lstrcmpA(dbcws->szModule,"CList")) + { + if(!lstrcmpA(dbcws->szSetting,"Hidden")) + { + Event.eType = EVENT_CONTACT_HIDDEN; + Event.iValue = db_get_b((HANDLE)wParam,"CList","Hidden",0); + } + else if(!lstrcmpA(dbcws->szSetting,"Group")) + { + Event.eType = EVENT_CONTACT_GROUP; + DBVARIANT dbv; + int res = db_get_ts((HANDLE)wParam, "CList", "Group", &dbv); + if(!res) + Event.strValue = dbv.ptszVal; + db_free(&dbv); + } + else + return 0; + } + else + return 0; + CAppletManager::GetInstance()->HandleEvent(&Event); + return 0; +} \ No newline at end of file diff --git a/plugins/MirandaG15/src/CAppletManager.h b/plugins/MirandaG15/src/CAppletManager.h new file mode 100644 index 0000000000..dee9b96a9e --- /dev/null +++ b/plugins/MirandaG15/src/CAppletManager.h @@ -0,0 +1,193 @@ +#ifndef _COUTPUTMANAGER_H_ +#define _COUTPUTMANAGER_H_ + +#include "CLCDOutputManager.h" + +#include "CProtocolData.h" +#include "CIRCHistory.h" +#include "CIRCConnection.h" + +#include "CNotificationScreen.h" +#include "CEventScreen.h" +#include "CContactlistScreen.h" +#include "CChatScreen.h" +#include "CCreditsScreen.h" +#include "CScreensaverScreen.h" + +#include "CLCDConnectionLogitech.h" + +struct SMessageJob +{ + HANDLE hEvent; + HANDLE hContact; + DWORD dwFlags; + char *pcBuffer; + int iBufferSize; + DWORD dwTimestamp; +}; + +class CAppletManager : public CLCDOutputManager +{ +public: + // returns the AppletManager's instance + static CAppletManager *GetInstance(); + + // Constructor + CAppletManager(); + // Destructor + ~CAppletManager(); + + // Initializes the AppletManager + bool Initialize(tstring strAppletName); + // Deinitializes the AppletManager + bool Shutdown(); + // Updates the AppletManager + bool Update(); + + // the update timer's callback function + static VOID CALLBACK UpdateTimer(HWND hwnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime); + + // called when the plugin's configuration has changed + void OnConfigChanged(); + + // called to process the specified event + void HandleEvent(CEvent *pEvent); + + // screen activation functions + void ActivatePreviousScreen(); + void ActivateScreensaverScreen(); + void ActivateCreditsScreen(); + void ActivateEventScreen(); + void ActivateCListScreen(); + bool ActivateChatScreen(HANDLE hContact); + + // hook functions + static int HookMessageWindowEvent(WPARAM wParam, LPARAM lParam); + static int HookContactIsTyping(WPARAM wParam, LPARAM lParam); + static int HookEventAdded(WPARAM wParam, LPARAM lParam); + static int HookStatusChanged(WPARAM wParam, LPARAM lParam); + static int HookProtoAck(WPARAM wParam, LPARAM lParam); + static int HookContactAdded(WPARAM wParam, LPARAM lParam); + static int HookContactDeleted(WPARAM wParam, LPARAM lParam); + static int HookSettingChanged(WPARAM wParam,LPARAM lParam); + static int HookChatInbound(WPARAM wParam,LPARAM lParam); + + // check if a contacts message window is opened + static bool IsMessageWindowOpen(HANDLE hContact); + // marks the given event as read + static void MarkMessageAsRead(HANDLE hContact,HANDLE hEvent); + // translates the given database event + static bool TranslateDBEvent(CEvent *pEvent,WPARAM wParam, LPARAM lParam); + // sends a message to the specified contact + static HANDLE SendMessageToContact(HANDLE hContact,tstring strMessage); + // sends typing notifications to the specified contact + static void SendTypingNotification(HANDLE hContact,bool bEnable); + + // returns the contacts message service name + static char *GetMessageServiceName(HANDLE hContact,bool bIsUnicode); + static bool IsUtfSendAvailable(HANDLE hContact); + // returns a formatted timestamp string + static tstring GetFormattedTimestamp(tm *time); + + // returns wether or not a contact is a subcontact + static bool IsSubContact(HANDLE hContact); + // returns the contacts group + static tstring GetContactGroup(HANDLE hContact); + // returns the contacts displayname + static tstring GetContactDisplayname(HANDLE hContact,bool bShortened=false); + + // returns the history class for the specified IRC channel + CIRCHistory *GetIRCHistory(HANDLE hContact); + CIRCHistory *GetIRCHistoryByName(tstring strProtocol,tstring strChannel); + + // returns the IRC connection class for the specified protocol + CIRCConnection *GetIRCConnection(tstring strProtocol); + // creates the IRC connection class for the specified protocol + CIRCConnection *CreateIRCConnection(tstring strProtocol); + + // returns the bitmap for the specified status + HBITMAP GetStatusBitmap(int iStatus); + // returns the bitmap for the specified event + HBITMAP GetEventBitmap(EventType eType, bool bLarge = false); + + // checks if the patched IRC protocol is in place + bool IsIRCHookEnabled(); + + static tstring TranslateString(TCHAR *szString,...); + +private: + list m_LIRCHistorys; + // deletes the history class for the specified IRC channel + void DeleteIRCHistory(HANDLE hContact); + // creates a history class for the specified IRC channel + CIRCHistory *CreateIRCHistory(HANDLE hContact,tstring strChannel); + CIRCHistory *CreateIRCHistoryByName(tstring strProtocol,tstring strChannel); + + // activate a screen + void ActivateScreen(CScreen *pScreen); + + // applies the volumewheel setting + void SetVolumeWheelHook(); + + // Called when the connection state has changed + void OnConnectionChanged(int iConnectionState); + // Called when the active screen has expired + void OnScreenExpired(CLCDScreen *pScreen); + + // updates all pending message jobs + void UpdateMessageJobs(); + // adds a message job to the list + void AddMessageJob(SMessageJob *pJob); + // finishes a message job + void FinishMessageJob(SMessageJob *pJob); + // cancels a message job + void CancelMessageJob(SMessageJob *pJob); + + // removes a message job from the list + + // strip IRC formatting + static tstring StripIRCFormatting(tstring strText); + + // Light status + SG15LightStatus m_G15LightStatus; + + list m_MessageJobs; + + // update timer handle + UINT m_uiTimer; + + // screens + CNotificationScreen m_NotificationScreen; + CEventScreen m_EventScreen; + CContactlistScreen m_ContactlistScreen; + CChatScreen m_ChatScreen; + CCreditsScreen m_CreditsScreen; + CScreensaverScreen m_ScreensaverScreen; + + // protocol data + vector m_vProtocolData; + CProtocolData* GetProtocolData(tstring strProtocol); + + // hook handles + HANDLE m_hMIHookMessageWindowEvent; + HANDLE m_hMIHookContactIsTyping; + HANDLE m_hMIHookEventAdded; + HANDLE m_hMIHookStatusChanged; + HANDLE m_hMIHookProtoAck; + HANDLE m_hMIHookSettingChanged; + HANDLE m_hMIHookContactDeleted; + HANDLE m_hMIHookContactAdded; + + vector m_vIRCConnections; + + // last active screen + CScreen *m_pLastScreen; + + bool m_bScreensaver; + + HBITMAP m_ahStatusBitmaps[8]; + HBITMAP m_ahEventBitmaps[4]; + HBITMAP m_ahLargeEventBitmaps[4]; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/CChatScreen.cpp b/plugins/MirandaG15/src/CChatScreen.cpp new file mode 100644 index 0000000000..dc87294e26 --- /dev/null +++ b/plugins/MirandaG15/src/CChatScreen.cpp @@ -0,0 +1,800 @@ +#include "stdafx.h" +#include "CChatScreen.h" +#include "CConfig.h" +#include "CAppletManager.h" + +//************************************************************************ +// Constructor +//************************************************************************ +CChatScreen::CChatScreen() +{ + m_bTyping = false; + m_hContact = NULL; + m_bHideTitle = false; + m_bHideLabels = false; + + m_dwMaximizedTimer = 0; + m_bMaximizedTimer = false; + m_bCloseTimer = false; + m_dwCloseTimer = 0; + + m_eReplyState = REPLY_STATE_NONE; + m_iStatus = ID_STATUS_OFFLINE; +} + +//************************************************************************ +// Destructor +//************************************************************************ +CChatScreen::~CChatScreen() +{ +} + +//************************************************************************ +// Initializes the screen +//************************************************************************ +bool CChatScreen::Initialize() +{ + if(!CScreen::Initialize()) + return false; + + m_InfoText.Initialize(); + m_UserName.Initialize(); + m_UserStatus.Initialize(); + m_UserProto.Initialize(); + m_Input.Initialize(); + m_TextLog.Initialize(); + m_Scrollbar.Initialize(); + + UpdateObjects(); + // other attributes + m_InfoText.SetAlignment(DT_CENTER); + m_InfoText.SetWordWrap(TRUE); + m_InfoText.SetText(_T("")); + m_InfoText.Show(0); + + m_UserName.SetAlignment(DT_CENTER); + m_UserName.SetWordWrap(TRUE); + m_UserName.SetText(_T("Proto")); + + + m_UserStatus.SetAlignment(DT_LEFT); + m_UserStatus.SetWordWrap(TRUE); + m_UserStatus.SetText(_T("Status")); + + + m_UserProto.SetAlignment(DT_RIGHT); + m_UserProto.SetWordWrap(TRUE); + m_UserProto.SetText(_T("User")); + + m_Input.Show(0); + + + + m_TextLog.Show(1); + + + + m_TextLog.SetScrollbar(&m_Scrollbar); + + AddObject(&m_Scrollbar); + AddObject(&m_TextLog); + AddObject(&m_Input); + AddObject(&m_InfoText); + AddObject(&m_UserName); + AddObject(&m_UserStatus); + AddObject(&m_UserProto); + + + SetButtonBitmap(0,IDB_UP); + SetButtonBitmap(1,IDB_DOWN); + SetButtonBitmap(2,IDB_HISTORY); + SetButtonBitmap(3,IDB_REPLY); + + return true; +} + +//************************************************************************ +// Shutdown the screen +//************************************************************************ +bool CChatScreen::Shutdown() +{ + if(!CScreen::Shutdown()) + return false; + + return true; +} + +//************************************************************************ +// update's the screens objects ( sizes, fonts etc) +//************************************************************************ +void CChatScreen::UpdateObjects() +{ + m_bHideTitle = false; + m_bHideLabels = !CConfig::GetBoolSetting(SHOW_LABELS); + + if(IsMaximized()) + { + if(!m_bHideTitle && !CConfig::GetBoolSetting(MAXIMIZED_TITLE)) + m_bHideTitle = true; + + if(!m_bHideLabels && !CConfig::GetBoolSetting(MAXIMIZED_LABELS)) + m_bHideLabels = true; + } + + // Fonts + m_TextLog.SetFont(CConfig::GetFont(FONT_SESSION)); + m_Input.SetFont(CConfig::GetFont(FONT_SESSION)); + m_InfoText.SetFont(CConfig::GetFont(FONT_SESSION)); + + m_UserName.SetFont(CConfig::GetFont(FONT_TITLE)); + m_UserStatus.SetFont(CConfig::GetFont(FONT_TITLE)); + m_UserProto.SetFont(CConfig::GetFont(FONT_TITLE)); + + int w = GetWidth() - 8; + // Sizes + m_UserName.SetSize(w*0.4, CConfig::GetFontHeight(FONT_TITLE)); + m_UserStatus.SetSize(w*0.25, CConfig::GetFontHeight(FONT_TITLE)); + m_UserProto.SetSize(w*0.3, CConfig::GetFontHeight(FONT_TITLE)); + + int iHeight =GetHeight(); + iHeight -= m_bHideTitle?0:CConfig::GetFontHeight(FONT_TITLE)+2; + iHeight -= m_bHideLabels?0:5; + + m_Input.SetSize(GetWidth()-5, iHeight); + m_TextLog.SetSize(GetWidth()-5, iHeight); + + m_InfoText.SetSize(160, 28); + m_InfoText.SetOrigin(0,(iHeight-CConfig::GetFontHeight(FONT_SESSION))/2); + + // Origins + + m_UserName.SetOrigin(8+w*0.25, 0); + m_UserStatus.SetOrigin(8, 0); + m_UserProto.SetOrigin(GetWidth()-w*0.3, 0); + + m_TextLog.SetOrigin(0, m_bHideTitle?0:CConfig::GetFontHeight(FONT_TITLE)+2); + m_Input.SetOrigin(0,m_bHideTitle?0:CConfig::GetFontHeight(FONT_TITLE)+2); + + m_InfoText.SetOrigin(0, 10); + + m_UserName.Show(!m_bHideTitle); + m_UserStatus.Show(!m_bHideTitle); + m_UserProto.Show(!m_bHideTitle); + + m_Scrollbar.SetOrigin(GetWidth()-4,(m_bHideTitle?0:CConfig::GetFontHeight(FONT_TITLE)+2)); + m_Scrollbar.SetSize(4,iHeight); + + // other options + m_TextLog.SetLogSize(CConfig::GetIntSetting(SESSION_LOGSIZE)); + + m_Input.SetBreakKeys(CConfig::GetBoolSetting(SESSION_SENDRETURN)?KEYS_RETURN:KEYS_CTRL_RETURN); + m_Input.ShowSymbols(CConfig::GetBoolSetting(SESSION_SYMBOLS)); + + ShowButtons(!m_bHideLabels); +} + +//************************************************************************ +// update's the screens title labels +//************************************************************************ +void CChatScreen::UpdateLabels() +{ + tstring strNickname = CAppletManager::GetContactDisplayname(m_hContact); + char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(UINT)m_hContact,0); + char *szStatus = NULL; + m_iStatus = ID_STATUS_OFFLINE; + + tstring strProto = _T(""); + tstring strStatus = _T(""); + if(szProto != NULL) + { + strProto = _T("(") + toTstring(szProto) + _T(")"); + m_iStatus = db_get_w(m_hContact,szProto,"Status",ID_STATUS_OFFLINE); + } + + szStatus = (char *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, m_iStatus, 0); + if(szStatus != NULL) + strStatus = toTstring(szStatus); + + m_UserName.SetText(strNickname.c_str()); + m_UserStatus.SetText(strStatus.c_str()); + + if(m_bContactTyping && CConfig::GetBoolSetting(SESSION_SHOWTYPING)) + m_UserProto.SetText(CAppletManager::TranslateString(_T("typing.."))); + else + m_UserProto.SetText(strProto.c_str()); +} + +// returns wether the input mode is active +bool CChatScreen::IsInputActive() +{ + if(m_eReplyState != REPLY_STATE_NONE) + return true; + else + return false; +} + +//************************************************************************ +// returns the chat contact +//************************************************************************ +HANDLE CChatScreen::GetContact() +{ + return m_hContact; +} + +//************************************************************************ +// sets the screen's chat contact +//************************************************************************ +bool CChatScreen::SetContact(HANDLE hContact) +{ + if(hContact == NULL) + { + m_hContact = NULL; + return true; + } + + // Check if the contact is valid + char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + m_strProto = toTstring(szProto); + + CIRCConnection *pIRCCon = CAppletManager::GetInstance()->GetIRCConnection(m_strProto); + if(pIRCCon) + m_bIRCProtocol = true; + else + m_bIRCProtocol = false; + + + if(!szProto) + return false; + + if(m_eReplyState != REPLY_STATE_NONE) + DeactivateMessageMode(); + else if(IsMaximized()) + Minimize(); + + m_bContactTyping = false; + m_hContact = hContact; + m_TextLog.ClearLog(); + UpdateLabels(); + + LoadHistory(); + + return true; +} + +//************************************************************************ +// loads the contacts history +//************************************************************************ +void CChatScreen::LoadHistory() +{ + if(!m_hContact) + return; + + char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)m_hContact, 0); + + if(m_bIRCProtocol && db_get_b(m_hContact, szProto, "ChatRoom", 0) != 0) + { + if(!CAppletManager::GetInstance()->IsIRCHookEnabled()) + { + time_t now; + tm tm_now; + time(&now); + localtime_s(&tm_now,&now); + + AddIncomingMessage(CAppletManager::TranslateString(_T("IRC-Chatroom support is disabled!\nYou need to install the patched IRC.dll (see the readme) to use IRC-Chatrooms on the LCD")),&tm_now,true); + } + else + { + CIRCHistory *pHistory = CAppletManager::GetInstance()->GetIRCHistory(m_hContact); + if(pHistory) + { + list::iterator iter = pHistory->LMessages.begin(); + while(iter != pHistory->LMessages.end()) + { + if((*iter).bIsMe) + AddOutgoingMessage((*iter).strMessage,&((*iter).Time),true); + else + AddIncomingMessage((*iter).strMessage,&((*iter).Time),true); + iter++; + } + } + } + } + else + { + // Get last events from database + CEvent Event; + list LHandles; + HANDLE hEvent = db_event_last(m_hContact); + HANDLE hUnread = db_event_firstUnread(m_hContact); + + if(CConfig::GetBoolSetting(SESSION_LOADDB)) + { + while(hEvent != NULL && hUnread != NULL) + { + LHandles.push_front(hEvent); + if(CConfig::GetBoolSetting(SESSION_LOADDB) && *(LHandles.begin()) == hUnread) + break; + hEvent = db_event_prev(hEvent); + } + } + else + { + for (int i = CConfig::GetIntSetting(SESSION_LOGSIZE); i > 0 && hEvent!=NULL; i--) + { + LHandles.push_front(hEvent); + hEvent = db_event_prev(hEvent); + } + } + + bool bRead = true; + while(!(LHandles.empty())) + { + if(CAppletManager::TranslateDBEvent(&Event,(LPARAM)m_hContact,(WPARAM)*(LHandles.begin()))) + { + if(Event.hValue == hUnread) + bRead = false; + if(Event.eType == EVENT_MSG_RECEIVED) + { + AddIncomingMessage(Event.strValue,&Event.Time); + if(!bRead && CConfig::GetBoolSetting(SESSION_MARKREAD) && !CAppletManager::IsMessageWindowOpen(m_hContact)) + CAppletManager::MarkMessageAsRead(m_hContact,Event.hValue); + } + else + AddOutgoingMessage(Event.strValue,&Event.Time); + + } + LHandles.pop_front(); + } + } +} + +//************************************************************************ +// Updates the screen +//************************************************************************ +bool CChatScreen::Update() +{ + if(!CScreen::Update()) + return false; + + if(CConfig::GetBoolSetting(SESSION_CLOSE)) { + if(!CAppletManager::GetInstance()->GetLCDConnection()->IsForeground()) { + if(!m_bCloseTimer && CConfig::GetIntSetting(SESSION_CLOSETIMER) != 0) { + m_bCloseTimer = true; + m_dwCloseTimer = GetTickCount(); + } else if(CConfig::GetIntSetting(SESSION_CLOSETIMER) == 0 || GetTickCount() - m_dwCloseTimer >= CConfig::GetIntSetting(SESSION_CLOSETIMER)) { + m_bCloseTimer = false; + CAppletManager::GetInstance()->ActivateEventScreen(); + return true; + } + } + } + + if(m_bMaximizedTimer && m_dwMaximizedDuration != INFINITE) + { + if(m_dwMaximizedTimer + m_dwMaximizedDuration <= GetTickCount()) + Minimize(); + } + + if(m_eReplyState == REPLY_STATE_INPUT && !m_Input.IsInputActive()) + SendCurrentMessage(); + + // Handle Typing notifications + if(IsInputActive()) + { + if(m_Input.GetLastInputTime() + 10000 <= GetTickCount()) + { + if(m_bTyping) + { + m_bTyping = false; + CAppletManager::GetInstance()->SendTypingNotification(m_hContact,0); + } + } + else if(CConfig::GetBoolSetting(SESSION_SENDTYPING) && !m_bTyping) + { + m_bTyping = true; + CAppletManager::GetInstance()->SendTypingNotification(m_hContact,1); + } + } + else if(m_bTyping) + { + m_bTyping = false; + CAppletManager::GetInstance()->SendTypingNotification(m_hContact,0); + } + + return true; +} + +//************************************************************************ +// Draws the screen +//************************************************************************ +bool CChatScreen::Draw(CLCDGfx *pGfx) +{ + if(!CScreen::Draw(pGfx)) + return false; + + if(!m_bHideTitle) + { + int iTitleHeight = CConfig::GetFontHeight(FONT_TITLE)+1; + pGfx->DrawLine(0,iTitleHeight<6?6:iTitleHeight,GetWidth(),iTitleHeight<6?6:iTitleHeight); + int iOffset = (iTitleHeight-5)/2; + pGfx->DrawBitmap(1,iOffset,5,5,CAppletManager::GetInstance()->GetStatusBitmap(m_iStatus)); + } + + return true; +} + +//************************************************************************ +// Adds an outgoing message to the log +//************************************************************************ +void CChatScreen::AddOutgoingMessage(tstring strMessage,tm *time,bool bIRC) +{ + tstring strPrefix = bIRC?_T(""):_T(">> "); + if(CConfig::GetBoolSetting(SESSION_TIMESTAMPS)) + strPrefix += CAppletManager::GetFormattedTimestamp(time) + _T(" "); + + // adjust the scroll mode + m_TextLog.SetAutoscrollMode(SCROLL_LINE); + + // add the message + m_TextLog.AddText(strPrefix + strMessage,true); + +} + +//************************************************************************ +// Adds an incoming message to the log +//************************************************************************ +void CChatScreen::AddIncomingMessage(tstring strMessage,tm *time,bool bIRC) +{ + tstring strPrefix = bIRC?_T(""):_T("<< "); + if(CConfig::GetBoolSetting(SESSION_TIMESTAMPS)) + strPrefix += CAppletManager::GetFormattedTimestamp(time) + _T(" "); + + + // adjust the scroll mode + EScrollMode eMode; + switch(CConfig::GetIntSetting(SESSION_AUTOSCROLL)) + { + case SESSION_AUTOSCROLL_NONE: eMode = SCROLL_NONE; break; + case SESSION_AUTOSCROLL_FIRST: eMode = SCROLL_MESSAGE; break; + case SESSION_AUTOSCROLL_LAST: eMode = SCROLL_LINE; break; + } + m_TextLog.SetAutoscrollMode(eMode); + + // add the message + m_TextLog.AddText(strPrefix + strMessage); +} + +//************************************************************************ +// activates the input mode +//************************************************************************ +void CChatScreen::ActivateMessageMode() +{ + m_InfoText.Show(0); + m_TextLog.Show(0); + m_TextLog.SetScrollbar(NULL); + m_Input.SetScrollbar(&m_Scrollbar); + + if(m_eReplyState != REPLY_STATE_FAILED) + m_Input.Reset(); + + m_Input.Show(1); + m_Input.ActivateInput(); + + m_eReplyState = REPLY_STATE_INPUT; + + SetButtonBitmap(2,IDB_BACK); + SetButtonBitmap(3,IDB_SEND); + + if(CConfig::GetBoolSetting(SESSION_REPLY_MAXIMIZED)) + Maximize(); + else + Minimize(); +} + +//************************************************************************ +// sends the message +//************************************************************************ +void CChatScreen::SendCurrentMessage() +{ + if(m_Input.GetText().empty()) + { + DeactivateMessageMode(); + return; + } + ASSERT(m_eReplyState == REPLY_STATE_INPUT); + + m_eReplyState = REPLY_STATE_SENDING; + + m_Input.DeactivateInput(); + + m_InfoText.SetText(CAppletManager::TranslateString(_T("Sending message..."))); + m_InfoText.Show(1); + m_Input.Show(0); + + m_hMessage = CAppletManager::SendMessageToContact(m_hContact,m_Input.GetText()); + if(m_hMessage == NULL) + { + DeactivateMessageMode(); + return; + } + SetButtonBitmap(2,NULL); + SetButtonBitmap(3,NULL); +} + +//************************************************************************ +// invalidates the message mode +//************************************************************************ +void CChatScreen::InvalidateMessageMode(tstring strError) +{ + m_eReplyState = REPLY_STATE_FAILED; + + m_InfoText.SetText(strError); + + SetButtonBitmap(2,IDB_BACK); + SetButtonBitmap(3,IDB_SEND); + + if(IsMaximized()) + Minimize(); +} + +//************************************************************************ +// deactivates the input mode +//************************************************************************ +void CChatScreen::DeactivateMessageMode() +{ + m_Input.Reset(); + + m_Input.SetScrollbar(NULL); + m_TextLog.SetScrollbar(&m_Scrollbar); + + m_TextLog.Show(1); + m_InfoText.Show(0); + m_Input.Show(0); + + m_Input.DeactivateInput(); + + m_eReplyState = REPLY_STATE_NONE; + + SetButtonBitmap(2,IDB_HISTORY); + SetButtonBitmap(3,IDB_REPLY); + + if(IsMaximized()) + Minimize(); +} + +//************************************************************************ +// maximizes the content object +//************************************************************************ +void CChatScreen::Maximize(DWORD dwTimer) +{ + m_bMaximizedTimer = true; + m_dwMaximizedTimer = GetTickCount(); + m_dwMaximizedDuration = dwTimer; + UpdateObjects(); +} + +//************************************************************************ +// minimizes the content object +//************************************************************************ +void CChatScreen::Minimize() +{ + m_bMaximizedTimer = false; + m_dwMaximizedTimer = 0; + UpdateObjects(); +} + +//************************************************************************ +// returns wether the content is maximized +//************************************************************************ +bool CChatScreen::IsMaximized() +{ + return m_bMaximizedTimer; +} + +//************************************************************************ +// Called when the screen size has changed +//************************************************************************ +void CChatScreen::OnSizeChanged() +{ + CScreen::OnSizeChanged(); + UpdateObjects(); +} + +//************************************************************************ +// Called when the applet's configuration has changed +//************************************************************************ +void CChatScreen::OnConfigChanged() +{ + CScreen::OnConfigChanged(); + + UpdateObjects(); + + m_TextLog.ClearLog(); + LoadHistory(); +} + +//************************************************************************ +// Called when an event is received +//************************************************************************ +void CChatScreen::OnEventReceived(CEvent *pEvent) +{ + // only let events for this contact pass + if(pEvent->hContact != m_hContact && + // expect for IRC events without a contact -> global notifications + !((pEvent->eType == EVENT_IRC_SENT || pEvent->eType == EVENT_IRC_RECEIVED) && pEvent->hContact == NULL)) + return; + + switch(pEvent->eType) + { + case EVENT_MESSAGE_ACK: + if(pEvent->hValue != m_hMessage) + return; + + if(pEvent->iValue == ACKRESULT_SUCCESS) + DeactivateMessageMode(); + else + InvalidateMessageMode(pEvent->strValue.empty()?CAppletManager::TranslateString(_T("Could not send the message!")):pEvent->strValue); + break; + case EVENT_IRC_SENT: + // Add the message to the log + AddOutgoingMessage(pEvent->strValue,&pEvent->Time,true); + break; + case EVENT_IRC_RECEIVED: + // Add the message to the log + AddIncomingMessage(pEvent->strValue,&pEvent->Time,true); + break; + case EVENT_MSG_RECEIVED: + // mark it as read if required + if(CConfig::GetBoolSetting(SESSION_MARKREAD) && !CAppletManager::IsMessageWindowOpen(m_hContact)) + CAppletManager::MarkMessageAsRead(m_hContact,pEvent->hValue); + // Add the message to the log + AddIncomingMessage(pEvent->strValue,&pEvent->Time); + break; + case EVENT_MSG_SENT: + // Add the message to the log + AddOutgoingMessage(pEvent->strValue,&pEvent->Time); + break; + case EVENT_CONTACT_HIDDEN: + // contact is set to hidden + if(pEvent->iValue == 1) + { + // Close the chat screen if the contact is an irc chatroom + if(!(m_bIRCProtocol && db_get_b(pEvent->hContact, toNarrowString(m_strProto).c_str(), "ChatRoom", 0) != 0)) + break; + } + else + break; + case EVENT_CONTACT_DELETED: + CAppletManager::GetInstance()->ActivateEventScreen(); + break; + case EVENT_TYPING_NOTIFICATION: + m_bContactTyping = pEvent->iValue != 0; + UpdateLabels(); + break; + case EVENT_STATUS: + case EVENT_CONTACT_NICK: + case EVENT_SIGNED_OFF: + case EVENT_SIGNED_ON: + UpdateLabels(); + break; + } +} + +//************************************************************************ +// Called when an LCD-button is pressed +//************************************************************************ +void CChatScreen::OnLCDButtonDown(int iButton) +{ + switch(m_eReplyState) + { + case REPLY_STATE_NONE: + if(iButton == LGLCDBUTTON_CANCEL) { + CAppletManager::GetInstance()->ActivatePreviousScreen(); + } else if(iButton == LGLCDBUTTON_BUTTON2 || iButton == LGLCDBUTTON_MENU) + CAppletManager::GetInstance()->ActivateEventScreen(); + // enter reply mode + else if(iButton == LGLCDBUTTON_BUTTON3 || iButton == LGLCDBUTTON_OK) + ActivateMessageMode(); + else { + bool bRes = false; + if(iButton == LGLCDBUTTON_BUTTON0 || iButton == LGLCDBUTTON_UP) { + bRes = m_TextLog.ScrollUp(); + } else if(iButton == LGLCDBUTTON_BUTTON1 || iButton == LGLCDBUTTON_DOWN) { + bRes = m_TextLog.ScrollDown(); + } + + if(bRes && CConfig::GetBoolSetting(SESSION_SCROLL_MAXIMIZED)) { + Maximize(5000); + } + } + break; + case REPLY_STATE_FAILED: + if(iButton == LGLCDBUTTON_BUTTON2 || iButton == LGLCDBUTTON_CANCEL) { + DeactivateMessageMode(); + } else if(iButton == LGLCDBUTTON_BUTTON3 || iButton == LGLCDBUTTON_OK) { + ActivateMessageMode(); + } else if(iButton == LGLCDBUTTON_CANCEL) { + DeactivateMessageMode(); + CAppletManager::GetInstance()->ActivatePreviousScreen(); + } else if(iButton == LGLCDBUTTON_MENU) { + DeactivateMessageMode(); + CAppletManager::GetInstance()->ActivateEventScreen(); + } + break; + case REPLY_STATE_SENDING: + break; + case REPLY_STATE_INPUT: + if(iButton == LGLCDBUTTON_BUTTON0 || iButton == LGLCDBUTTON_UP) { + m_Input.ScrollLine(0); + } else if(iButton == LGLCDBUTTON_BUTTON1 || iButton == LGLCDBUTTON_DOWN) { + m_Input.ScrollLine(1); + // send the message + } else if(iButton == LGLCDBUTTON_BUTTON3 || iButton == LGLCDBUTTON_OK) { + SendCurrentMessage(); + // cancel message mode + } else if(iButton == LGLCDBUTTON_BUTTON2 || iButton == LGLCDBUTTON_CANCEL) { + DeactivateMessageMode(); + } + break; + } +} + +//************************************************************************ +// Called when an LCD-button event is repeated +//************************************************************************ +void CChatScreen::OnLCDButtonRepeated(int iButton) +{ + switch(m_eReplyState) + { + case REPLY_STATE_NONE: + if(iButton < 2) + { + bool bRes = false; + if(iButton == LGLCDBUTTON_BUTTON0 || iButton == LGLCDBUTTON_UP) { + bRes = m_TextLog.ScrollUp(); + } else if(iButton == LGLCDBUTTON_BUTTON1 || iButton == LGLCDBUTTON_DOWN) { + bRes = m_TextLog.ScrollDown(); + } + + if(bRes && CConfig::GetBoolSetting(SESSION_SCROLL_MAXIMIZED)) + Maximize(5000); + } + break; + case REPLY_STATE_INPUT: + if(iButton == LGLCDBUTTON_BUTTON0 || iButton == LGLCDBUTTON_UP) { + m_Input.ScrollLine(0); + } else if(iButton == LGLCDBUTTON_BUTTON1 || iButton == LGLCDBUTTON_DOWN) { + m_Input.ScrollLine(1); + } + } +} + +//************************************************************************ +// Called when an LCD-button is released +//************************************************************************ +void CChatScreen::OnLCDButtonUp(int iButton) +{ + +} + +//************************************************************************ +// Called when the screen is activated +//************************************************************************ +void CChatScreen::OnActivation() +{ + m_bCloseTimer = false; +} + +//************************************************************************ +// Called when the screen is deactivated +//************************************************************************ +void CChatScreen::OnDeactivation() +{ +} + +//************************************************************************ +// Called when the screen has expired +//************************************************************************ +void CChatScreen::OnExpiration() +{ +} \ No newline at end of file diff --git a/plugins/MirandaG15/src/CChatScreen.h b/plugins/MirandaG15/src/CChatScreen.h new file mode 100644 index 0000000000..7af002e46c --- /dev/null +++ b/plugins/MirandaG15/src/CChatScreen.h @@ -0,0 +1,113 @@ +#ifndef _CCHATSCREEN_H_ +#define _CCHATSCREEN_H_ + +#include "CScreen.h" + +#include "CLCDLabel.h" +#include "CLCDTextLog.h" +#include "CLCDInput.h" + +class CChatScreen : public CScreen +{ +public: + // Constructor + CChatScreen(); + // Destructor + ~CChatScreen(); + + // Initializes the screen + bool Initialize(); + // Shutdown the scren + bool Shutdown(); + // Updates the screen + bool Update(); + // Draws the screen + bool Draw(CLCDGfx *pGfx); + + // Called when an event is received + void OnEventReceived(CEvent *pEvent); + // Called when an LCD-button is pressed + void OnLCDButtonDown(int iButton); + // Called when an LCD-button event is repeated + void OnLCDButtonRepeated(int iButton); + // Called when an LCD-button is released + void OnLCDButtonUp(int iButton); + // Called when the screen is activated + void OnActivation(); + // Called when the screen is deactivated + void OnDeactivation(); + // Called when the screen has expired + void OnExpiration(); + // Called when the applet's configuration has changed + void OnConfigChanged(); + // Called when the screen size has changed + void OnSizeChanged(); + + // Set's the chat contact + bool SetContact(HANDLE hContact); + // returns the chat contact + HANDLE GetContact(); + + // returns wether the input mode is active + bool IsInputActive(); +protected: + // loads the contacts history + void LoadHistory(); + + // Adds an outgoing message to the log + void AddOutgoingMessage(tstring strMessage,tm *time,bool bIRC = false); + // Adds an incoming message to the log + void AddIncomingMessage(tstring strMessage,tm *time,bool bIRC = false); + + // maximizes the content object + void Maximize(DWORD dwTimer=INFINITE); + // minimizes the content object + void Minimize(); + // returns wether the content is maximized + bool IsMaximized(); + + // activates the input mode + void ActivateMessageMode(); + // deactivates the input mode + void DeactivateMessageMode(); + // sends the message + void SendCurrentMessage(); + // invalidates the message mode + void InvalidateMessageMode(tstring strError); + + // update's the screens objects ( sizes, fonts etc) + void UpdateObjects(); + // update's the screens title labels + void UpdateLabels(); + + bool m_bHideLabels,m_bHideTitle; + bool m_bMaximizedTimer; + + bool m_bContactTyping; + bool m_bTyping; + + enum { REPLY_STATE_NONE,REPLY_STATE_INPUT,REPLY_STATE_SENDING,REPLY_STATE_FAILED} m_eReplyState; + DWORD m_dwCloseTimer; + bool m_bCloseTimer; + DWORD m_dwMaximizedTimer; + DWORD m_dwMaximizedDuration; + + HANDLE m_hContact; + HANDLE m_hMessage; + + int m_iStatus; + + CLCDLabel m_UserProto; + CLCDLabel m_UserName; + CLCDLabel m_UserStatus; + CLCDLabel m_InfoText; + + CLCDInput m_Input; + CLCDTextLog m_TextLog; + CLCDBar m_Scrollbar; + + tstring m_strProto; + bool m_bIRCProtocol; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/CConfig.cpp b/plugins/MirandaG15/src/CConfig.cpp new file mode 100644 index 0000000000..76cfc68444 --- /dev/null +++ b/plugins/MirandaG15/src/CConfig.cpp @@ -0,0 +1,970 @@ +#include "StdAfx.h" +#include "Miranda.h" +#include "CConfig.h" + +#include "CAppletManager.h" + +#define FONTF_BOLD 1 +#define FONTF_ITALIC 2 + +HANDLE CConfig::m_hOptionsInitHook = NULL; +bool CConfig::m_bInitializingDialog = false; +bool CConfig::m_abBoolSettings[BOOL_SETTINGS]; +int CConfig::m_aiIntSettings[INT_SETTINGS]; +LOGFONT CConfig::m_logfont[FONT_SETTINGS]; +LOGFONT CConfig::m_templogfont[FONT_SETTINGS]; +HANDLE CConfig::m_hSampleFont[FONT_SETTINGS]; +TEXTMETRIC CConfig::m_tmFontInfo[FONT_SETTINGS]; +vector CConfig::m_ProtoList; +HWND CConfig::hDeviceBox = NULL; + +void CConfig::Initialize() +{ + CConfig::LoadSettings(); + m_hOptionsInitHook = HookEvent(ME_OPT_INITIALISE, CConfig::InitOptionsDialog); + +} + +void CConfig::Shutdown() +{ + if(m_hSampleFont) + DeleteObject(m_hSampleFont); + UnhookEvent(m_hOptionsInitHook); +} + +void CConfig::LoadSettings() +{ + m_abBoolSettings[SKIP_DRIVER_ERROR] = db_get_dw(NULL, "MirandaG15", "SkipDriverError",0); + + m_abBoolSettings[SCREENSAVER_LOCK] = db_get_dw(NULL, "MirandaG15", "ScreensaverLock",1); + m_abBoolSettings[NOTIFY_SHOWPROTO] = db_get_dw(NULL, "MirandaG15", "NotifyShowProto",0); + m_abBoolSettings[NOTIFY_NICKCUTOFF] = db_get_dw(NULL, "MirandaG15", "NotifyNickCutoff",0); + m_abBoolSettings[NOTIFY_CHANNELCUTOFF] = db_get_dw(NULL, "MirandaG15", "NotifyChannelCutoff",0); + + m_abBoolSettings[TRANSITIONS] = db_get_dw(NULL, "MirandaG15", "Transitions",0); + m_abBoolSettings[TIMESTAMP_SECONDS] = db_get_dw(NULL, "MirandaG15", "TimestampSeconds",0); + m_abBoolSettings[SESSION_TIMESTAMPS] = db_get_dw(NULL, "MirandaG15", "SessionTimestamps",0); + m_abBoolSettings[NOTIFY_TIMESTAMPS] = db_get_dw(NULL, "MirandaG15", "NotifyTimestamps",0); + + m_abBoolSettings[CONTROL_BACKLIGHTS] = db_get_dw(NULL, "MirandaG15", "ControlBacklights",0); + m_abBoolSettings[HOOK_VOLUMEWHEEL] = db_get_dw(NULL, "MirandaG15", "HookVolumeWheel",0); + + m_abBoolSettings[CLIST_SELECTION] = db_get_dw(NULL, "MirandaG15", "CListSelection",1); + m_abBoolSettings[CLIST_COLUMNS] = db_get_dw(NULL, "MirandaG15", "CListColumns",0); + m_abBoolSettings[CLIST_HIDEOFFLINE] = db_get_dw(NULL, "MirandaG15", "CListHideOffline",1); + m_abBoolSettings[CLIST_USEIGNORE] = db_get_dw(NULL, "MirandaG15", "CListUseIgnore",1); + m_abBoolSettings[CLIST_USEGROUPS] = db_get_dw(NULL, "MirandaG15", "CListUseGroups",1); + m_abBoolSettings[CLIST_SHOWPROTO] = db_get_dw(NULL, "MirandaG15", "CListShowProto",1); + m_abBoolSettings[CLIST_DRAWLINES] = db_get_dw(NULL, "MirandaG15", "CListDrawLines",1); + m_abBoolSettings[CLIST_COUNTERS] = db_get_dw(NULL, "MirandaG15", "CListCounters",1); + m_abBoolSettings[CLIST_POSITION] = db_get_dw(NULL, "MirandaG15", "CListPosition",0); + + m_abBoolSettings[NOTIFY_IRC_MESSAGES] = db_get_dw(NULL, "MirandaG15", "NotifyIRCMessages", 1); + m_abBoolSettings[NOTIFY_IRC_USERS] = db_get_dw(NULL, "MirandaG15", "NotifyIRCUsers", 0); + m_abBoolSettings[NOTIFY_IRC_EMOTES] = db_get_dw(NULL, "MirandaG15", "NotifyIRCEmotes", 0); + m_abBoolSettings[NOTIFY_IRC_NOTICES] = db_get_dw(NULL, "MirandaG15", "NotifyIRCNotices", 1); + m_abBoolSettings[NOTIFY_IRC_CHANNEL] = db_get_dw(NULL, "MirandaG15", "NotifyIRCChannel", 0); + m_abBoolSettings[NOTIFY_IRC_STATUS] = db_get_dw(NULL, "MirandaG15", "NotifyIRCStatus", 0); + + m_abBoolSettings[NOTIFY_PROTO_STATUS] = db_get_dw(NULL, "MirandaG15", "NotifyProtoStatus", 0); + m_abBoolSettings[NOTIFY_PROTO_SIGNON] = db_get_dw(NULL, "MirandaG15", "NotifyProtoSignOn", 1); + m_abBoolSettings[NOTIFY_PROTO_SIGNOFF] =db_get_dw(NULL, "MirandaG15", "NotifyProtoSignOff", 1); + m_abBoolSettings[NOTIFY_MESSAGES] = db_get_dw(NULL, "MirandaG15", "NotifyMessages", 1); + m_abBoolSettings[NOTIFY_SIGNON] = db_get_dw(NULL, "MirandaG15", "NotifySignOn", 1); + m_abBoolSettings[NOTIFY_SIGNOFF] = db_get_dw(NULL, "MirandaG15", "NotifySignOff", 1); + m_abBoolSettings[NOTIFY_STATUS] = db_get_dw(NULL, "MirandaG15", "NotifyStatus", 0); + m_abBoolSettings[NOTIFY_SKIP_MESSAGES] =db_get_dw(NULL, "MirandaG15", "NotifySkipMessages", 1); + m_abBoolSettings[NOTIFY_SKIP_SIGNON] = db_get_dw(NULL, "MirandaG15", "NotifySkipSignOn", 0); + m_abBoolSettings[NOTIFY_SKIP_SIGNOFF] = db_get_dw(NULL, "MirandaG15", "NotifySkipSignOff", 0); + m_abBoolSettings[NOTIFY_SKIP_STATUS] = db_get_dw(NULL, "MirandaG15", "NotifySkipStatus", 1); + m_abBoolSettings[NOTIFY_NO_SKIP_REPLY] = db_get_dw(NULL, "MirandaG15", "NotifyNoSkipReply",1); + m_abBoolSettings[NOTIFY_URL] = db_get_dw(NULL, "MirandaG15", "NotifyURL", 1); + m_abBoolSettings[NOTIFY_FILE] = db_get_dw(NULL, "MirandaG15", "NotifyFile", 1); + m_abBoolSettings[NOTIFY_CONTACTS] = db_get_dw(NULL, "MirandaG15", "NotifyContacts", 1); + + m_abBoolSettings[SESSION_SCROLL_MAXIMIZED] = db_get_dw(NULL, "MirandaG15", "SessionScrollMaximized", 1); + m_abBoolSettings[SESSION_REPLY_MAXIMIZED] = db_get_dw(NULL, "MirandaG15", "SessionReplyMaximized", 1); + m_abBoolSettings[SESSION_LOADDB] = db_get_dw(NULL, "MirandaG15", "SessionLoadDB", 0); + m_abBoolSettings[SESSION_MARKREAD] = db_get_dw(NULL, "MirandaG15", "SessionMarkRead", 1); + m_abBoolSettings[SESSION_SENDRETURN] = db_get_dw(NULL, "MirandaG15", "SessionSendReturn",0); + m_abBoolSettings[SESSION_SHOWTYPING] = db_get_dw(NULL, "MirandaG15", "SessionShowTyping",1); + m_abBoolSettings[SESSION_SENDTYPING] = db_get_dw(NULL, "MirandaG15", "SessionSendTyping",1); + m_abBoolSettings[SESSION_SYMBOLS] = db_get_dw(NULL, "MirandaG15", "SessionSymbols",0); + m_abBoolSettings[SESSION_CLOSE] = db_get_dw(NULL, "MirandaG15", "SessionClose",1); + + m_abBoolSettings[SHOW_LABELS] = db_get_dw(NULL, "MirandaG15", "ShowLabels", 1); + m_abBoolSettings[MAXIMIZED_TITLE] = db_get_dw(NULL, "MirandaG15", "MaximizedTitle", 0); + m_abBoolSettings[MAXIMIZED_LABELS] = db_get_dw(NULL, "MirandaG15", "MaximizedLabels", 1); + + m_aiIntSettings[NOTIFY_CHANNELCUTOFF_OFFSET] = db_get_dw(NULL, "MirandaG15", "NotifyChannelCutoffOffset", 10); + m_aiIntSettings[NOTIFY_NICKCUTOFF_OFFSET] = db_get_dw(NULL, "MirandaG15", "NotifyNickCutoffOffset", 10); + m_aiIntSettings[NOTIFY_DURATION] = db_get_dw(NULL, "MirandaG15", "NotifyDuration", 4); + m_aiIntSettings[NOTIFY_LOGSIZE] = db_get_dw(NULL, "MirandaG15", "NotifyLogSize", 10); + m_aiIntSettings[SESSION_LOGSIZE] = db_get_dw(NULL, "MirandaG15", "SessionLogSize", 10); + m_aiIntSettings[SESSION_AUTOSCROLL] = db_get_dw(NULL, "MirandaG15", "SessionAutoScroll", SESSION_AUTOSCROLL_FIRST); + m_aiIntSettings[SESSION_CLOSETIMER] = db_get_dw(NULL, "MirandaG15", "SessionCloseTimer", 15); + m_aiIntSettings[NOTIFY_TITLE] = db_get_dw(NULL, "MirandaG15", "NotifyTitle", NOTIFY_TITLE_NAME); + m_aiIntSettings[CLIST_GA] = db_get_dw(NULL, "MirandaG15", "CListGA",CLIST_GA_NONE); + m_aiIntSettings[DEVICE] = db_get_dw(NULL, "MirandaG15", "Device",0); + + for(int i=0;itype != PROTOTYPE_PROTOCOL) + continue;*/ + if (ppAccounts[i]->bIsEnabled == 0) + continue; + + iProtoCount++; + pProtoFilter = new CProtoFilter(); + pProtoFilter->strName = toTstring(ppAccounts[i]->szModuleName); + + strSetting = _T("ProtoFilter_") + pProtoFilter->strName; + pProtoFilter->bNotificationFilter = db_get_dw(NULL,"MirandaG15",toNarrowString(strSetting).c_str(),1); + strSetting = _T("ProtoCListFilter_") + pProtoFilter->strName; + pProtoFilter->bContactlistFilter = db_get_dw(NULL,"MirandaG15",toNarrowString(strSetting).c_str(),1); + m_ProtoList.push_back(pProtoFilter); + } +} + +void CConfig::SaveSettings() +{ + db_set_dw(NULL, "MirandaG15", "SkipDriverError", m_abBoolSettings[SKIP_DRIVER_ERROR]); + + db_set_dw(NULL, "MirandaG15", "ScreensaverLock", m_abBoolSettings[SCREENSAVER_LOCK]); + db_set_dw(NULL, "MirandaG15", "NotifyShowProto", m_abBoolSettings[NOTIFY_SHOWPROTO]); + db_set_dw(NULL, "MirandaG15", "NotifyChannelCutoff", m_abBoolSettings[NOTIFY_CHANNELCUTOFF]); + db_set_dw(NULL, "MirandaG15", "NotifyNickCutoff", m_abBoolSettings[NOTIFY_NICKCUTOFF]); + db_set_dw(NULL, "MirandaG15", "Transitions", m_abBoolSettings[TRANSITIONS]); + db_set_dw(NULL, "MirandaG15", "TimestampSeconds", m_abBoolSettings[TIMESTAMP_SECONDS]); + db_set_dw(NULL, "MirandaG15", "SessionTimestamps", m_abBoolSettings[SESSION_TIMESTAMPS]); + db_set_dw(NULL, "MirandaG15", "NotifyTimestamps", m_abBoolSettings[NOTIFY_TIMESTAMPS]); + + db_set_dw(NULL, "MirandaG15", "ControlBacklights", m_abBoolSettings[CONTROL_BACKLIGHTS]); + db_set_dw(NULL, "MirandaG15", "HookVolumeWheel", m_abBoolSettings[HOOK_VOLUMEWHEEL]); + + db_set_dw(NULL, "MirandaG15", "CListSelection", m_abBoolSettings[CLIST_SELECTION]); + db_set_dw(NULL, "MirandaG15", "CListColumns", m_abBoolSettings[CLIST_COLUMNS]); + db_set_dw(NULL, "MirandaG15", "CListHideOffline", m_abBoolSettings[CLIST_HIDEOFFLINE]); + db_set_dw(NULL, "MirandaG15", "CListUseIgnore", m_abBoolSettings[CLIST_USEIGNORE]); + db_set_dw(NULL, "MirandaG15", "CListUseGroups", m_abBoolSettings[CLIST_USEGROUPS]); + db_set_dw(NULL, "MirandaG15", "CListShowProto", m_abBoolSettings[CLIST_SHOWPROTO]); + db_set_dw(NULL, "MirandaG15", "CListDrawLines", m_abBoolSettings[CLIST_DRAWLINES]); + db_set_dw(NULL, "MirandaG15", "CListCounters", m_abBoolSettings[CLIST_COUNTERS]); + db_set_dw(NULL, "MirandaG15", "CListPosition", m_abBoolSettings[CLIST_POSITION]); + + db_set_dw(NULL, "MirandaG15", "NotifyIRCMessages", m_abBoolSettings[NOTIFY_IRC_MESSAGES]); + db_set_dw(NULL, "MirandaG15", "NotifyIRCUsers", m_abBoolSettings[NOTIFY_IRC_USERS]); + db_set_dw(NULL, "MirandaG15", "NotifyIRCEmotes", m_abBoolSettings[NOTIFY_IRC_EMOTES]); + db_set_dw(NULL, "MirandaG15", "NotifyIRCNotices", m_abBoolSettings[NOTIFY_IRC_NOTICES]); + db_set_dw(NULL, "MirandaG15", "NotifyIRCChannel", m_abBoolSettings[NOTIFY_IRC_CHANNEL]); + db_set_dw(NULL, "MirandaG15", "NotifyIRCStatus", m_abBoolSettings[NOTIFY_IRC_STATUS]); + + db_set_dw(NULL, "MirandaG15", "NotifyProtoStatus", m_abBoolSettings[NOTIFY_PROTO_STATUS]); + db_set_dw(NULL, "MirandaG15", "NotifyProtoSignOn", m_abBoolSettings[NOTIFY_PROTO_SIGNON]); + db_set_dw(NULL, "MirandaG15", "NotifyProtoSignOff",m_abBoolSettings[NOTIFY_PROTO_SIGNOFF]); + db_set_dw(NULL, "MirandaG15", "NotifyMessages", m_abBoolSettings[NOTIFY_MESSAGES]); + db_set_dw(NULL, "MirandaG15", "NotifySignOn", m_abBoolSettings[NOTIFY_SIGNON]); + db_set_dw(NULL, "MirandaG15", "NotifySignOff", m_abBoolSettings[NOTIFY_SIGNOFF]); + db_set_dw(NULL, "MirandaG15", "NotifyStatus", m_abBoolSettings[NOTIFY_STATUS]); + db_set_dw(NULL, "MirandaG15", "NotifySkipMessages", m_abBoolSettings[NOTIFY_SKIP_MESSAGES]); + db_set_dw(NULL, "MirandaG15", "NotifySkipSignOn", m_abBoolSettings[NOTIFY_SKIP_SIGNON]); + db_set_dw(NULL, "MirandaG15", "NotifySkipSignOff", m_abBoolSettings[NOTIFY_SKIP_SIGNOFF]); + db_set_dw(NULL, "MirandaG15", "NotifySkipStatus", m_abBoolSettings[NOTIFY_SKIP_STATUS]); + db_set_dw(NULL, "MirandaG15", "NotifyNoSkipReply", m_abBoolSettings[NOTIFY_NO_SKIP_REPLY]); + db_set_dw(NULL, "MirandaG15", "NotifyURL", m_abBoolSettings[NOTIFY_URL]); + db_set_dw(NULL, "MirandaG15", "NotifyFile", m_abBoolSettings[NOTIFY_FILE]); + db_set_dw(NULL, "MirandaG15", "NotifyContacts", m_abBoolSettings[NOTIFY_CONTACTS]); + + db_set_dw(NULL, "MirandaG15", "SessionScrollMaximized",m_abBoolSettings[SESSION_SCROLL_MAXIMIZED]); + db_set_dw(NULL, "MirandaG15", "SessionReplyMaximized",m_abBoolSettings[SESSION_REPLY_MAXIMIZED]); + db_set_dw(NULL, "MirandaG15", "SessionShowTyping", m_abBoolSettings[SESSION_SHOWTYPING]); + db_set_dw(NULL, "MirandaG15", "SessionSendTyping", m_abBoolSettings[SESSION_SENDTYPING]); + db_set_dw(NULL, "MirandaG15", "SessionLoadDB", m_abBoolSettings[SESSION_LOADDB]); + db_set_dw(NULL, "MirandaG15", "SessionSendReturn", m_abBoolSettings[SESSION_SENDRETURN]); + db_set_dw(NULL, "MirandaG15", "SessionMarkRead", m_abBoolSettings[SESSION_MARKREAD]); + db_set_dw(NULL, "MirandaG15", "SessionSymbols", m_abBoolSettings[SESSION_SYMBOLS]); + db_set_dw(NULL, "MirandaG15", "SessionClose", m_abBoolSettings[SESSION_CLOSE]); + + db_set_dw(NULL, "MirandaG15", "ShowLabels", m_abBoolSettings[SHOW_LABELS]); + db_set_dw(NULL, "MirandaG15", "MaximizedTitle", m_abBoolSettings[MAXIMIZED_TITLE]); + db_set_dw(NULL, "MirandaG15", "MaximizedLabels", m_abBoolSettings[MAXIMIZED_LABELS]); + + db_set_dw(NULL, "MirandaG15", "NotifyChannelCutoffOffset", m_aiIntSettings[NOTIFY_CHANNELCUTOFF_OFFSET]); + db_set_dw(NULL, "MirandaG15", "NotifyNickCutoffOffset", m_aiIntSettings[NOTIFY_NICKCUTOFF_OFFSET]); + db_set_dw(NULL, "MirandaG15", "NotifyDuration", m_aiIntSettings[NOTIFY_DURATION]); + db_set_dw(NULL, "MirandaG15", "NotifyLogSize", m_aiIntSettings[NOTIFY_LOGSIZE]); + db_set_dw(NULL, "MirandaG15", "SessionLogSize", m_aiIntSettings[SESSION_LOGSIZE]); + db_set_dw(NULL, "MirandaG15", "NotifyTitle", m_aiIntSettings[NOTIFY_TITLE]); + db_set_dw(NULL, "MirandaG15", "SessionAutoScroll", m_aiIntSettings[SESSION_AUTOSCROLL]); + db_set_dw(NULL, "MirandaG15", "SessionCloseTimer", m_aiIntSettings[SESSION_CLOSETIMER]); + db_set_dw(NULL, "MirandaG15", "CListGA", m_aiIntSettings[CLIST_GA]); + db_set_dw(NULL, "MirandaG15", "Device", m_aiIntSettings[DEVICE]); + + // Save font settings + for(int i=0;i::iterator iter = m_ProtoList.begin(); + tstring strSetting = _T(""); + while(iter != m_ProtoList.end()) + { + strSetting = _T("ProtoFilter_") + (*iter)->strName; + db_set_dw(NULL, "MirandaG15", toNarrowString(strSetting).c_str(),(*iter)->bNotificationFilter); + strSetting = _T("ProtoCListFilter_") + (*iter)->strName; + db_set_dw(NULL, "MirandaG15", toNarrowString(strSetting).c_str(),(*iter)->bContactlistFilter); + iter++; + } + + // Notify OutputManager of configuration change + if(CAppletManager::GetInstance()->IsInitialized()) + CAppletManager::GetInstance()->OnConfigChanged(); +} + +void CConfig::UpdateFontSettings(int iFont) +{ + if(m_hSampleFont[iFont]) + DeleteObject(m_hSampleFont[iFont]); + m_hSampleFont[iFont] = CreateFontIndirect(&m_logfont[iFont]); + HDC hDC = CreateCompatibleDC(NULL); + SelectObject(hDC, m_hSampleFont[iFont]); + GetTextMetrics(hDC,&m_tmFontInfo[iFont]); + DeleteObject(hDC); +} + +void CConfig::OnConnectionChanged() { + FillDeviceBox(CConfig::hDeviceBox); +} + +int CConfig::InitOptionsDialog(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp; + ZeroMemory(&odp, sizeof(odp)); + odp.cbSize = sizeof(odp); + odp.position = 847000000; + odp.hInstance = hInstance; + odp.pszGroup = "MirandaG15"; + odp.flags = ODPF_BOLDGROUPS; + + // --------------------- + odp.pszTemplate = MAKEINTRESOURCEA(IDD_FONTS); + odp.pszTitle = "Appearance"; + odp.pszGroup = "MirandaG15"; + odp.pfnDlgProc = CConfig::AppearanceDlgProc; + + Options_AddPage(wParam, &odp); + + // --------------------- + + odp.pszTemplate = MAKEINTRESOURCEA(IDD_NOTIFICATIONS); + odp.pszTitle = "Notifications"; + odp.pfnDlgProc = CConfig::NotificationsDlgProc; + + Options_AddPage(wParam, &odp); + + // --------------------- + + odp.pszTemplate = MAKEINTRESOURCEA(IDD_CHAT); + odp.pszTitle = "Chatsessions"; + odp.pfnDlgProc = CConfig::ChatDlgProc; + + Options_AddPage(wParam, &odp); + + // --------------------- + + odp.pszTemplate = MAKEINTRESOURCEA(IDD_CLIST); + odp.pszTitle = "Contactlist"; + odp.pfnDlgProc = CConfig::ContactlistDlgProc; + + Options_AddPage(wParam, &odp); + return 0; +} + +void CConfig::SaveFontSettings(int iFont) +{ + if(iFont > FONT_SETTINGS -1 || iFont < 0) + return; + + char szSetting[128]; + + // Height + sprintf(szSetting,"Font%dHeight",iFont); + db_set_b(NULL, "MirandaG15", szSetting, m_logfont[iFont].lfHeight); + // Style + int style = 0; + if(m_logfont[iFont].lfWeight == FW_BOLD) + style |= FONTF_BOLD; + if(m_logfont[iFont].lfItalic) + style |= FONTF_ITALIC; + sprintf(szSetting,"Font%dStyle",iFont); + db_set_b(NULL, "MirandaG15", szSetting, style); + // Charset + sprintf(szSetting,"Font%dCharset",iFont); + db_set_b(NULL, "MirandaG15", szSetting, m_logfont[iFont].lfCharSet); + // Name + sprintf(szSetting,"Font%dName",iFont); + db_set_ts(NULL, "MirandaG15", szSetting, m_logfont[iFont].lfFaceName); + + UpdateFontSettings(iFont); +} + +void CConfig::LoadFontSettings(int iFont) +{ + if(iFont > FONT_SETTINGS -1 || iFont < 0) + return; + + char szSetting[128]; + + // Fixed Values + m_logfont[iFont].lfOutPrecision = OUT_DEFAULT_PRECIS; + m_logfont[iFont].lfClipPrecision = CLIP_DEFAULT_PRECIS; + m_logfont[iFont].lfQuality = DEFAULT_QUALITY; + m_logfont[iFont].lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; + // Height + sprintf(szSetting,"Font%dHeight",iFont); + m_logfont[iFont].lfHeight = (char) db_get_b(NULL, "MirandaG15", szSetting, -MulDiv(6, 96, 72)); + // Style + sprintf(szSetting,"Font%dStyle",iFont); + int style = db_get_b(NULL, "MirandaG15", szSetting, 0); + m_logfont[iFont].lfWeight = style & FONTF_BOLD ? FW_BOLD : FW_NORMAL; + m_logfont[iFont].lfItalic = style & FONTF_ITALIC ? 1 : 0; + // Charset + sprintf(szSetting,"Font%dCharset",iFont); + m_logfont[iFont].lfCharSet = db_get_b(NULL, "MirandaG15", szSetting, DEFAULT_CHARSET); + // Name + sprintf(szSetting,"Font%dName",iFont); + DBVARIANT dbv; + if (db_get_ts(NULL, "MirandaG15", szSetting, &dbv)) + lstrcpy(m_logfont[iFont].lfFaceName,_T("Small Fonts")); + else { + lstrcpy(m_logfont[iFont].lfFaceName, dbv.ptszVal); + db_free(&dbv); + } + + UpdateFontSettings(iFont); +} + +LOGFONT &CConfig::GetFont(int iFont) +{ + return m_logfont[iFont]; +} + +int CConfig::GetFontHeight(int iFont) +{ + return m_tmFontInfo[iFont].tmHeight; +} + +int CConfig::GetSampleField(int iFont) +{ + switch(iFont) + { + case 0: return IDC_SAMPLE1; + case 1: return IDC_SAMPLE2; + case 2: return IDC_SAMPLE3; + case 3: return IDC_SAMPLE4; + case 4: return IDC_SAMPLE5; + }; + return 0; +} + +INT_PTR CALLBACK CConfig::AppearanceDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + char buf[128]; + + switch (uMsg) + { + case WM_INITDIALOG: + { + m_bInitializingDialog = true; + + // Translate the dialog + TranslateDialogDefault(hwndDlg); + + CheckDlgButton(hwndDlg, IDC_SKIP_DRIVER_ERROR, m_abBoolSettings[SKIP_DRIVER_ERROR] ? BST_CHECKED : BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_SCREENSAVER_LOCK, m_abBoolSettings[SCREENSAVER_LOCK] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_TRANSITIONS, m_abBoolSettings[TRANSITIONS] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CONTROL_BACKLIGHTS, m_abBoolSettings[CONTROL_BACKLIGHTS] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SHOW_LABELS, m_abBoolSettings[SHOW_LABELS] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_HOOK_VOLUMEWHEEL, m_abBoolSettings[HOOK_VOLUMEWHEEL] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_TIMESTAMP_SECONDS, m_abBoolSettings[TIMESTAMP_SECONDS] ? BST_CHECKED : BST_UNCHECKED); + + for(int i=0;icode) + { + case PSN_APPLY: + { + m_abBoolSettings[SKIP_DRIVER_ERROR] = IsDlgButtonChecked(hwndDlg,IDC_SKIP_DRIVER_ERROR) == BST_CHECKED ? true : false; + + m_abBoolSettings[SCREENSAVER_LOCK] = IsDlgButtonChecked(hwndDlg,IDC_SCREENSAVER_LOCK) == BST_CHECKED ? true : false; + m_abBoolSettings[TRANSITIONS] = IsDlgButtonChecked(hwndDlg,IDC_TRANSITIONS) == BST_CHECKED ? true : false; + m_abBoolSettings[SHOW_LABELS] = IsDlgButtonChecked(hwndDlg,IDC_SHOW_LABELS) == BST_CHECKED ? true : false; + m_abBoolSettings[CONTROL_BACKLIGHTS] = IsDlgButtonChecked(hwndDlg,IDC_CONTROL_BACKLIGHTS) == BST_CHECKED ? true : false; + m_abBoolSettings[HOOK_VOLUMEWHEEL] = IsDlgButtonChecked(hwndDlg,IDC_HOOK_VOLUMEWHEEL) == BST_CHECKED ? true : false; + m_abBoolSettings[TIMESTAMP_SECONDS] = IsDlgButtonChecked(hwndDlg,IDC_TIMESTAMP_SECONDS) == BST_CHECKED ? true : false; + m_aiIntSettings[DEVICE] = SendDlgItemMessage(hwndDlg,IDC_DEVICE,CB_GETCURSEL ,0,0); + + for(int i=0;iActivateCreditsScreen(); + break; + } + + int iFont = LOWORD(wParam); + switch(iFont) + { + case IDC_CHOOSEFONT1: iFont = 0; break; + case IDC_CHOOSEFONT2: iFont = 1; break; + case IDC_CHOOSEFONT3: iFont = 2; break; + case IDC_CHOOSEFONT4: iFont = 3; break; + case IDC_CHOOSEFONT5: iFont = 4; break; + default: iFont = -1; + }; + + if(iFont >= 0) + { + CHOOSEFONT cf = { 0 }; + cf.lStructSize = sizeof(cf); + cf.hwndOwner = hwndDlg; + cf.lpLogFont = &m_templogfont[iFont]; + cf.Flags = CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS; + if (ChooseFont(&cf)) + { + if(m_hSampleFont[iFont]) + DeleteObject(m_hSampleFont[iFont]); + m_hSampleFont[iFont] = CreateFontIndirect(&m_templogfont[iFont]); + SendDlgItemMessage(hwndDlg,CConfig::GetSampleField(iFont),WM_SETFONT,(WPARAM)m_hSampleFont[iFont],(LPARAM)true); + TRACE(_T("Font selected!")); + } + } + if(LOWORD(wParam) == IDC_DEVICE && SendDlgItemMessage(hwndDlg,IDC_DEVICE,CB_GETCURSEL ,0,0) != m_aiIntSettings[DEVICE]) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + + // Activate the apply button + if (!m_bInitializingDialog && ((HIWORD(wParam) == EN_CHANGE) || (HIWORD(wParam) == BN_CLICKED))) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + break; + } + } + return 0; +} + +INT_PTR CALLBACK CConfig::ChatDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + char buf[128]; + + switch (uMsg) + { + case WM_INITDIALOG: + { + m_bInitializingDialog = true; + + // Translate the dialog + TranslateDialogDefault(hwndDlg); + + CheckDlgButton(hwndDlg, IDC_MAXIMIZED_TITLE, m_abBoolSettings[MAXIMIZED_TITLE] ? BST_UNCHECKED : BST_CHECKED); + CheckDlgButton(hwndDlg, IDC_MAXIMIZED_LABELS, m_abBoolSettings[MAXIMIZED_LABELS] ? BST_UNCHECKED : BST_CHECKED); + CheckDlgButton(hwndDlg, IDC_SESSION_REPLY_MAXIMIZED, m_abBoolSettings[SESSION_REPLY_MAXIMIZED]? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SESSION_SCROLL_MAXIMIZED, m_abBoolSettings[SESSION_SCROLL_MAXIMIZED]? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SESSION_SHOWTYPING, m_abBoolSettings[SESSION_SHOWTYPING]? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SESSION_SENDTYPING, m_abBoolSettings[SESSION_SENDTYPING]? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SESSION_LOADDB, m_abBoolSettings[SESSION_LOADDB]? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SESSION_MARKREAD, m_abBoolSettings[SESSION_MARKREAD]? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SESSION_SYMBOLS, m_abBoolSettings[SESSION_SYMBOLS]? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SESSION_TIMESTAMPS, m_abBoolSettings[SESSION_TIMESTAMPS]? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SESSION_CLOSE, m_abBoolSettings[SESSION_CLOSE]? BST_CHECKED : BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_SESSION_SENDRETURN, m_abBoolSettings[SESSION_SENDRETURN]? BST_CHECKED : BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_SESSION_SCROLLNONE, m_aiIntSettings[SESSION_AUTOSCROLL] == SESSION_AUTOSCROLL_NONE? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SESSION_SCROLLFIRST, m_aiIntSettings[SESSION_AUTOSCROLL] == SESSION_AUTOSCROLL_FIRST? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SESSION_SCROLLLAST, m_aiIntSettings[SESSION_AUTOSCROLL] == SESSION_AUTOSCROLL_LAST? BST_CHECKED : BST_UNCHECKED); + + itoa(m_aiIntSettings[SESSION_LOGSIZE], buf, 10); + SetDlgItemTextA(hwndDlg, IDC_SESSION_LOGSIZE, buf); + + itoa(m_aiIntSettings[SESSION_CLOSETIMER], buf, 10); + SetDlgItemTextA(hwndDlg, IDC_SESSION_CLOSETIMER, buf); + + m_bInitializingDialog = false; + break; + } + case WM_NOTIFY: + { + switch (((LPNMHDR)lParam)->code) + { + case PSN_APPLY: + { + m_abBoolSettings[SESSION_SCROLL_MAXIMIZED] = IsDlgButtonChecked(hwndDlg,IDC_SESSION_SCROLL_MAXIMIZED) == BST_CHECKED ? true : false; + m_abBoolSettings[SESSION_REPLY_MAXIMIZED] = IsDlgButtonChecked(hwndDlg,IDC_SESSION_REPLY_MAXIMIZED) == BST_CHECKED ? true : false; + m_abBoolSettings[SESSION_SHOWTYPING] = IsDlgButtonChecked(hwndDlg,IDC_SESSION_SHOWTYPING) == BST_CHECKED ? true : false; + m_abBoolSettings[SESSION_SENDTYPING] = IsDlgButtonChecked(hwndDlg,IDC_SESSION_SENDTYPING) == BST_CHECKED ? true : false; + m_abBoolSettings[SESSION_LOADDB] = IsDlgButtonChecked(hwndDlg,IDC_SESSION_LOADDB) == BST_CHECKED ? true : false; + m_abBoolSettings[SESSION_SENDRETURN] = IsDlgButtonChecked(hwndDlg,IDC_SESSION_SENDRETURN) == BST_CHECKED ? true : false; + m_abBoolSettings[SESSION_MARKREAD] = IsDlgButtonChecked(hwndDlg,IDC_SESSION_MARKREAD) == BST_CHECKED ? true : false; + m_abBoolSettings[SESSION_SYMBOLS] = IsDlgButtonChecked(hwndDlg,IDC_SESSION_SYMBOLS) == BST_CHECKED ? true : false; + m_abBoolSettings[SESSION_TIMESTAMPS] = IsDlgButtonChecked(hwndDlg,IDC_SESSION_TIMESTAMPS) == BST_CHECKED ? true : false; + m_abBoolSettings[SESSION_CLOSE] = IsDlgButtonChecked(hwndDlg,IDC_SESSION_CLOSE) == BST_CHECKED ? true : false; + + if(IsDlgButtonChecked(hwndDlg,IDC_SESSION_SCROLLNONE) == BST_CHECKED) + m_aiIntSettings[SESSION_AUTOSCROLL] = SESSION_AUTOSCROLL_NONE; + else if(IsDlgButtonChecked(hwndDlg,IDC_SESSION_SCROLLFIRST) == BST_CHECKED) + m_aiIntSettings[SESSION_AUTOSCROLL] = SESSION_AUTOSCROLL_FIRST; + else + m_aiIntSettings[SESSION_AUTOSCROLL] = SESSION_AUTOSCROLL_LAST; + + m_abBoolSettings[MAXIMIZED_TITLE] = IsDlgButtonChecked(hwndDlg,IDC_MAXIMIZED_TITLE) == BST_UNCHECKED ? true : false; + m_abBoolSettings[MAXIMIZED_LABELS] = IsDlgButtonChecked(hwndDlg,IDC_MAXIMIZED_LABELS) == BST_UNCHECKED ? true : false; + + GetDlgItemTextA(hwndDlg,IDC_SESSION_LOGSIZE,buf,256); + m_aiIntSettings[SESSION_LOGSIZE] = atoi(buf) > 0 ? atoi(buf):1; + + GetDlgItemTextA(hwndDlg,IDC_SESSION_CLOSETIMER,buf,256); + m_aiIntSettings[SESSION_CLOSETIMER] = atoi(buf) >= 0 ? atoi(buf):1; + + CConfig::SaveSettings(); + SendMessage(hwndDlg, WM_INITDIALOG, 0, 0); + break; + } + } + break; + } + case WM_COMMAND: + { + // Activate the apply button + if (!m_bInitializingDialog && ((HIWORD(wParam) == EN_CHANGE) || (HIWORD(wParam) == BN_CLICKED))) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + + break; + } + } + return 0; +} + +INT_PTR CALLBACK CConfig::NotificationsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + char buf[128]; + + switch (uMsg) + { + case WM_INITDIALOG: + { + m_bInitializingDialog = true; + + // Translate the dialog + TranslateDialogDefault(hwndDlg); + + // Initialize the protocol filter list + SetWindowLong(GetDlgItem(hwndDlg,IDC_PROTOCOLS),GWL_STYLE,GetWindowLong(GetDlgItem(hwndDlg,IDC_PROTOCOLS),GWL_STYLE)|TVS_NOHSCROLL); + int iRes = 0; + + HIMAGELIST himlCheckBoxes; + himlCheckBoxes=ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),ILC_COLOR32|ILC_MASK,2,2); + iRes = ImageList_AddIcon(himlCheckBoxes,LoadIcon(hInstance,MAKEINTRESOURCE(IDI_NOTICK))); + iRes = ImageList_AddIcon(himlCheckBoxes,LoadIcon(hInstance,MAKEINTRESOURCE(IDI_TICK))); + TreeView_SetImageList(GetDlgItem(hwndDlg,IDC_PROTOCOLS),himlCheckBoxes,TVSIL_NORMAL); + + FillTree(GetDlgItem(hwndDlg,IDC_PROTOCOLS)); + + CheckDlgButton(hwndDlg, IDC_NOTIFY_TIMESTAMPS, m_abBoolSettings[NOTIFY_TIMESTAMPS] ? BST_CHECKED : BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_NOTIFY_SHOWPROTO, m_abBoolSettings[NOTIFY_SHOWPROTO] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_CHANNELCUTOFF, m_abBoolSettings[NOTIFY_CHANNELCUTOFF] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_NICKCUTOFF, m_abBoolSettings[NOTIFY_NICKCUTOFF] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_IRC_MESSAGES, m_abBoolSettings[NOTIFY_IRC_MESSAGES] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_IRC_USERS, m_abBoolSettings[NOTIFY_IRC_USERS] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_IRC_EMOTES, m_abBoolSettings[NOTIFY_IRC_EMOTES] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_IRC_NOTICES, m_abBoolSettings[NOTIFY_IRC_NOTICES] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_IRC_CHANNEL, m_abBoolSettings[NOTIFY_IRC_CHANNEL] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_IRC_STATUS, m_abBoolSettings[NOTIFY_IRC_STATUS] ? BST_CHECKED : BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_NOTIFY_PROTO_STATUS, m_abBoolSettings[NOTIFY_PROTO_STATUS] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_PROTO_SIGNON, m_abBoolSettings[NOTIFY_PROTO_SIGNON] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_PROTO_SIGNOFF, m_abBoolSettings[NOTIFY_PROTO_SIGNOFF] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_SIGNON, m_abBoolSettings[NOTIFY_SIGNON] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_SIGNOFF, m_abBoolSettings[NOTIFY_SIGNOFF] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_STATUS, m_abBoolSettings[NOTIFY_STATUS] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_MESSAGES, m_abBoolSettings[NOTIFY_MESSAGES] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_FILE, m_abBoolSettings[NOTIFY_FILE] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_CONTACTS, m_abBoolSettings[NOTIFY_CONTACTS] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_URL, m_abBoolSettings[NOTIFY_URL] ? BST_CHECKED : BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_NOTIFY_NO_SKIP_REPLY, m_abBoolSettings[NOTIFY_NO_SKIP_REPLY] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_SKIP_SIGNON, m_abBoolSettings[NOTIFY_SKIP_SIGNON] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_SKIP_SIGNOFF, m_abBoolSettings[NOTIFY_SKIP_SIGNOFF] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_SKIP_STATUS, m_abBoolSettings[NOTIFY_SKIP_STATUS] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_SKIP_MESSAGES, m_abBoolSettings[NOTIFY_SKIP_MESSAGES] ? BST_CHECKED : BST_UNCHECKED); + + itoa(m_aiIntSettings[NOTIFY_CHANNELCUTOFF_OFFSET], buf, 10); + SetDlgItemTextA(hwndDlg, IDC_NOTIFY_CHANNELCUTOFF_OFFSET, buf); + + itoa(m_aiIntSettings[NOTIFY_NICKCUTOFF_OFFSET], buf, 10); + SetDlgItemTextA(hwndDlg, IDC_NOTIFY_NICKCUTOFF_OFFSET, buf); + + itoa(m_aiIntSettings[NOTIFY_LOGSIZE], buf, 10); + SetDlgItemTextA(hwndDlg, IDC_NOTIFY_LOGSIZE, buf); + + itoa(m_aiIntSettings[NOTIFY_DURATION], buf, 10); + SetDlgItemTextA(hwndDlg, IDC_NOTIFY_DURATION, buf); + + CheckDlgButton(hwndDlg, IDC_NOTIFY_TITLEHIDE, m_aiIntSettings[NOTIFY_TITLE] == NOTIFY_TITLE_HIDE? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_TITLENAME, m_aiIntSettings[NOTIFY_TITLE] == NOTIFY_TITLE_NAME? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NOTIFY_TITLEINFO, m_aiIntSettings[NOTIFY_TITLE] == NOTIFY_TITLE_INFO? BST_CHECKED : BST_UNCHECKED); + + m_bInitializingDialog = false; + break; + } + case WM_NOTIFY: + { + if(((LPNMHDR)lParam)->idFrom == IDC_PROTOCOLS) + { + if(((LPNMHDR)lParam)->code != NM_CLICK) + return 0; + + 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_ONITEMICON) { + 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; + ((CProtoFilter *)tvi.lParam)->bTempNotificationFilter=tvi.iImage; + TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + + } + break; + } + switch (((LPNMHDR)lParam)->code) + { + case PSN_APPLY: + { + m_abBoolSettings[NOTIFY_TIMESTAMPS] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_TIMESTAMPS) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_CHANNELCUTOFF] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_CHANNELCUTOFF) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_NICKCUTOFF] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_NICKCUTOFF) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_SHOWPROTO] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_SHOWPROTO) == BST_CHECKED ? true : false; + + m_abBoolSettings[NOTIFY_IRC_MESSAGES] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_IRC_MESSAGES) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_IRC_USERS] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_IRC_USERS) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_IRC_EMOTES] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_IRC_EMOTES) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_IRC_NOTICES] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_IRC_NOTICES) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_IRC_CHANNEL] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_IRC_CHANNEL) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_IRC_STATUS] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_IRC_STATUS) == BST_CHECKED ? true : false; + + m_abBoolSettings[NOTIFY_PROTO_STATUS] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_PROTO_STATUS) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_PROTO_SIGNON] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_PROTO_SIGNON) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_PROTO_SIGNOFF] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_PROTO_SIGNOFF) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_MESSAGES] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_MESSAGES) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_SIGNON] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_SIGNON) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_SIGNOFF] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_SIGNOFF) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_STATUS] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_STATUS) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_URL] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_URL) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_FILE] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_FILE) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_CONTACTS] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_CONTACTS) == BST_CHECKED ? true : false; + + m_abBoolSettings[NOTIFY_NO_SKIP_REPLY] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_NO_SKIP_REPLY) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_SKIP_MESSAGES] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_SKIP_MESSAGES) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_SKIP_SIGNON] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_SKIP_SIGNON) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_SKIP_SIGNOFF] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_SKIP_SIGNOFF) == BST_CHECKED ? true : false; + m_abBoolSettings[NOTIFY_SKIP_STATUS] = IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_SKIP_STATUS) == BST_CHECKED ? true : false; + + GetDlgItemTextA(hwndDlg,IDC_NOTIFY_CHANNELCUTOFF_OFFSET,buf,256); + m_aiIntSettings[NOTIFY_CHANNELCUTOFF_OFFSET] = atoi(buf) > 0 ? atoi(buf):1; + + GetDlgItemTextA(hwndDlg,IDC_NOTIFY_NICKCUTOFF_OFFSET,buf,256); + m_aiIntSettings[NOTIFY_NICKCUTOFF_OFFSET] = atoi(buf) > 0 ? atoi(buf):1; + + GetDlgItemTextA(hwndDlg,IDC_NOTIFY_DURATION,buf,256); + m_aiIntSettings[NOTIFY_DURATION] = atoi(buf) > 0 ? atoi(buf):1; + + GetDlgItemTextA(hwndDlg,IDC_NOTIFY_LOGSIZE,buf,256); + m_aiIntSettings[NOTIFY_LOGSIZE] = atoi(buf) > 0 ? atoi(buf):1; + + if(IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_TITLEHIDE) == BST_CHECKED) + m_aiIntSettings[NOTIFY_TITLE] = NOTIFY_TITLE_HIDE; + else if(IsDlgButtonChecked(hwndDlg,IDC_NOTIFY_TITLENAME) == BST_CHECKED) + m_aiIntSettings[NOTIFY_TITLE] = NOTIFY_TITLE_NAME; + else + m_aiIntSettings[NOTIFY_TITLE] = NOTIFY_TITLE_INFO; + + // apply all contactlist protocol filters + vector::iterator iter = m_ProtoList.begin(); + while(iter != m_ProtoList.end()) + { + (*iter)->bNotificationFilter = (*iter)->bTempNotificationFilter; + iter++; + } + + CConfig::SaveSettings(); + SendMessage(hwndDlg, WM_INITDIALOG, 0, 0); + break; + } + } + break; + } + case WM_COMMAND: + { + // Activate the apply button + if (!m_bInitializingDialog && ((HIWORD(wParam) == EN_CHANGE) || (HIWORD(wParam) == BN_CLICKED))) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + + break; + } + } + return 0; +} + +INT_PTR CALLBACK CConfig::ContactlistDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + char buf[128]; + + switch (uMsg) + { + case WM_INITDIALOG: + { + m_bInitializingDialog = true; + + // Translate the dialog + TranslateDialogDefault(hwndDlg); + + // Initialize the protocol filter list + SetWindowLong(GetDlgItem(hwndDlg,IDC_CLIST_PROTOFILTER),GWL_STYLE,GetWindowLong(GetDlgItem(hwndDlg,IDC_CLIST_PROTOFILTER),GWL_STYLE)|TVS_NOHSCROLL); + int iRes = 0; + + HIMAGELIST himlCheckBoxes; + himlCheckBoxes=ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),ILC_COLOR32|ILC_MASK,2,2); + iRes = ImageList_AddIcon(himlCheckBoxes,LoadIcon(hInstance,MAKEINTRESOURCE(IDI_NOTICK))); + iRes = ImageList_AddIcon(himlCheckBoxes,LoadIcon(hInstance,MAKEINTRESOURCE(IDI_TICK))); + TreeView_SetImageList(GetDlgItem(hwndDlg,IDC_CLIST_PROTOFILTER),himlCheckBoxes,TVSIL_NORMAL); + + FillTree(GetDlgItem(hwndDlg,IDC_CLIST_PROTOFILTER),true); + + CheckDlgButton(hwndDlg, IDC_CLIST_SELECTION, m_abBoolSettings[CLIST_SELECTION] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CLIST_COLUMNS, m_abBoolSettings[CLIST_COLUMNS] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CLIST_HIDEOFFLINE, m_abBoolSettings[CLIST_HIDEOFFLINE] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CLIST_USEIGNORE, m_abBoolSettings[CLIST_USEIGNORE] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CLIST_USEGROUPS, m_abBoolSettings[CLIST_USEGROUPS] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CLIST_SHOWPROTO, m_abBoolSettings[CLIST_SHOWPROTO]? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CLIST_DRAWLINES, m_abBoolSettings[CLIST_DRAWLINES]? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CLIST_POSITION, m_abBoolSettings[CLIST_POSITION]? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CLIST_COUNTERS, m_abBoolSettings[CLIST_COUNTERS]? BST_CHECKED : BST_UNCHECKED); + + if(m_aiIntSettings[CLIST_GA] == CLIST_GA_NONE) + CheckDlgButton(hwndDlg, IDC_CLIST_GA_NONE, BST_CHECKED); + else if(m_aiIntSettings[CLIST_GA] == CLIST_GA_COLLAPSE) + CheckDlgButton(hwndDlg, IDC_CLIST_GA_COLLAPSE, BST_CHECKED); + else + CheckDlgButton(hwndDlg, IDC_CLIST_GA_EXPAND, BST_CHECKED); + + m_bInitializingDialog = false; + break; + } + case WM_NOTIFY: + { + if(((LPNMHDR)lParam)->idFrom == IDC_CLIST_PROTOFILTER) + { + if(((LPNMHDR)lParam)->code != NM_CLICK) + return 0; + + 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_ONITEMICON) { + 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; + ((CProtoFilter *)tvi.lParam)->bTempContactlistFilter=tvi.iImage; + TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + break; + } + switch (((LPNMHDR)lParam)->code) + { + case PSN_APPLY: + { + m_abBoolSettings[CLIST_SELECTION] = IsDlgButtonChecked(hwndDlg,IDC_CLIST_SELECTION) == BST_CHECKED ? true : false; + m_abBoolSettings[CLIST_COLUMNS] = IsDlgButtonChecked(hwndDlg,IDC_CLIST_COLUMNS) == BST_CHECKED ? true : false; + m_abBoolSettings[CLIST_HIDEOFFLINE] = IsDlgButtonChecked(hwndDlg,IDC_CLIST_HIDEOFFLINE) == BST_CHECKED ? true : false; + m_abBoolSettings[CLIST_USEGROUPS] = IsDlgButtonChecked(hwndDlg,IDC_CLIST_USEGROUPS) == BST_CHECKED ? true : false; + m_abBoolSettings[CLIST_USEIGNORE] = IsDlgButtonChecked(hwndDlg,IDC_CLIST_USEIGNORE) == BST_CHECKED ? true : false; + m_abBoolSettings[CLIST_SHOWPROTO] = IsDlgButtonChecked(hwndDlg,IDC_CLIST_SHOWPROTO) == BST_CHECKED ? true : false; + m_abBoolSettings[CLIST_DRAWLINES] = IsDlgButtonChecked(hwndDlg,IDC_CLIST_DRAWLINES) == BST_CHECKED ? true : false; + m_abBoolSettings[CLIST_POSITION] = IsDlgButtonChecked(hwndDlg,IDC_CLIST_POSITION) == BST_CHECKED ? true : false; + m_abBoolSettings[CLIST_COUNTERS] = IsDlgButtonChecked(hwndDlg,IDC_CLIST_COUNTERS) == BST_CHECKED ? true : false; + + if(IsDlgButtonChecked(hwndDlg,IDC_CLIST_GA_NONE) == BST_CHECKED) + m_aiIntSettings[CLIST_GA] = CLIST_GA_NONE; + else if(IsDlgButtonChecked(hwndDlg,IDC_CLIST_GA_COLLAPSE) == BST_CHECKED) + m_aiIntSettings[CLIST_GA] = CLIST_GA_COLLAPSE; + else + m_aiIntSettings[CLIST_GA] = CLIST_GA_EXPAND; + + // apply all contactlist protocol filters + vector::iterator iter = m_ProtoList.begin(); + while(iter != m_ProtoList.end()) + { + (*iter)->bContactlistFilter = (*iter)->bTempContactlistFilter; + iter++; + } + CConfig::SaveSettings(); + SendMessage(hwndDlg, WM_INITDIALOG, 0, 0); + break; + } + } + break; + } + case WM_COMMAND: + { + // Activate the apply button + if (!m_bInitializingDialog && ((HIWORD(wParam) == EN_CHANGE) || (HIWORD(wParam) == BN_CLICKED))) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + + break; + } + } + return 0; +} + + +bool CConfig::GetProtocolContactlistFilter(tstring strProtocol) +{ + vector::iterator iter = m_ProtoList.begin(); + while(iter != m_ProtoList.end()) + { + if((*iter)->strName == strProtocol) + return (*iter)->bContactlistFilter; + iter++; + } + return false; +} + +bool CConfig::GetProtocolNotificationFilter(tstring strProtocol) +{ + vector::iterator iter = m_ProtoList.begin(); + while(iter != m_ProtoList.end()) + { + if((*iter)->strName == strProtocol) + return (*iter)->bNotificationFilter; + iter++; + } + return false; +} + +bool CConfig::GetBoolSetting(int iSetting) +{ + if(iSetting >= 0 && iSetting < BOOL_SETTINGS) + return m_abBoolSettings[iSetting]; + return false; +} + +int CConfig::GetIntSetting(int iSetting) +{ + if(iSetting >= 0 && iSetting < INT_SETTINGS) + return m_aiIntSettings[iSetting]; + return false; +} + +void CConfig::ClearTree(HWND hTree) +{ + TreeView_DeleteAllItems(hTree); +} + +void CConfig::FillDeviceBox(HWND hBox) { + CLCDConnection *connection = CAppletManager::GetInstance()->GetLCDConnection(); + CLCDDevice *device = NULL; + int i = 0; + SendMessage(hBox,CB_RESETCONTENT,0,0); + + while((device = connection->GetAttachedDevice(i++)) != NULL) { + SendMessage(hBox,CB_ADDSTRING,0,(LPARAM)device->GetDisplayName().c_str()); + } + + if(i == 1) { + SendMessage(hBox,CB_ADDSTRING,0,(LPARAM)_T("No device attached")); + } + + int iDevice = CConfig::GetIntSetting(DEVICE); + if( iDevice >= i) + iDevice = 0; + + SendMessage(hBox,CB_SETCURSEL ,iDevice,0); +} + +void CConfig::FillTree(HWND hTree,bool bCList) +{ + TreeView_DeleteAllItems(hTree); + + TVINSERTSTRUCT tvis; + tvis.hParent=NULL; + tvis.hInsertAfter=TVI_LAST; + tvis.item.mask=TVIF_PARAM|TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE; + + vector::iterator iter = m_ProtoList.begin(); + while(iter != m_ProtoList.end()) + { + tvis.item.lParam=(LPARAM)(*iter); + tvis.item.pszText= (LPTSTR)(*iter)->strName.c_str(); + if(!bCList) + { + tvis.item.iImage= (*iter)->bNotificationFilter; + (*iter)->bTempNotificationFilter = (*iter)->bNotificationFilter; + } + else + { + tvis.item.iImage= (*iter)->bContactlistFilter; + (*iter)->bTempContactlistFilter = (*iter)->bContactlistFilter; + } + tvis.item.iSelectedImage= tvis.item.iImage; + + TreeView_InsertItem(hTree,&tvis); + iter++; + } +} \ No newline at end of file diff --git a/plugins/MirandaG15/src/CConfig.h b/plugins/MirandaG15/src/CConfig.h new file mode 100644 index 0000000000..e35b68f772 --- /dev/null +++ b/plugins/MirandaG15/src/CConfig.h @@ -0,0 +1,166 @@ +#ifndef _CCONFIG_H_ +#define _CCONFIG_H_ + +// Tabs +#define TAB_OPTIONS 0 +#define TAB_NOTIFICATIONS 1 +#define TAB_CHAT 2 +#define TAB_CLIST 3 + +// Fonts +#define FONT_LOG 0 +#define FONT_SESSION 1 +#define FONT_CLIST 2 +#define FONT_TITLE 3 +#define FONT_NOTIFICATION 4 + +#define FONT_SETTINGS 5 + +// Bool settings +#define CLIST_HIDEOFFLINE 0 +#define NOTIFY_MESSAGES 1 +#define NOTIFY_SIGNON 2 +#define NOTIFY_SIGNOFF 3 +#define NOTIFY_STATUS 4 +#define SESSION_LOADDB 5 +#define SHOW_LABELS 6 +#define SESSION_MARKREAD 7 +#define NOTIFY_CONTACTS 8 +#define NOTIFY_FILE 9 +#define NOTIFY_URL 10 +#define SESSION_SENDRETURN 11 +#define NOTIFY_PROTO_STATUS 12 +#define SESSION_SHOWTYPING 13 +#define SESSION_SENDTYPING 14 +#define SESSION_SCROLL_MAXIMIZED 15 +#define SESSION_REPLY_MAXIMIZED 16 +#define MAXIMIZED_TITLE 17 +#define MAXIMIZED_LABELS 18 +#define CLIST_USEGROUPS 19 +#define CLIST_USEIGNORE 20 +#define NOTIFY_PROTO_SIGNON 21 +#define NOTIFY_PROTO_SIGNOFF 22 +#define CLIST_SHOWPROTO 23 +#define SESSION_SYMBOLS 24 +#define CLIST_COUNTERS 24 +#define CLIST_DRAWLINES 25 +#define CLIST_POSITION 26 +#define CONTROL_BACKLIGHTS 28 +#define HOOK_VOLUMEWHEEL 29 +#define NOTIFY_SKIP_MESSAGES 30 +#define NOTIFY_SKIP_STATUS 31 +#define NOTIFY_SKIP_SIGNON 32 +#define NOTIFY_SKIP_SIGNOFF 33 +#define SESSION_TIMESTAMPS 34 +#define NOTIFY_TIMESTAMPS 35 +#define TIMESTAMP_SECONDS 36 +#define NOTIFY_IRC_MESSAGES 37 +#define NOTIFY_IRC_USERS 38 +#define NOTIFY_IRC_EMOTES 39 +#define NOTIFY_IRC_NOTICES 40 +#define NOTIFY_IRC_CHANNEL 41 +#define NOTIFY_IRC_STATUS 42 +#define CLIST_COLUMNS 43 +#define TRANSITIONS 44 +#define NOTIFY_NICKCUTOFF 45 +#define NOTIFY_SHOWPROTO 46 +#define NOTIFY_NO_SKIP_REPLY 47 +#define CLIST_SELECTION 48 +#define NOTIFY_CHANNELCUTOFF 49 +#define SCREENSAVER_LOCK 50 +#define SESSION_CLOSE 52 +#define SKIP_DRIVER_ERROR 53 + +#define BOOL_SETTINGS 54 + +// Int Settings +#define SESSION_LOGSIZE 0 +#define NOTIFY_LOGSIZE 1 +#define NOTIFY_DURATION 2 +#define NOTIFY_TITLE 3 +#define SESSION_AUTOSCROLL 4 +#define CLIST_GA 5 +#define NOTIFY_NICKCUTOFF_OFFSET 6 +#define DEVICE 7 +#define NOTIFY_CHANNELCUTOFF_OFFSET 8 +#define SESSION_CLOSETIMER 9 + +#define INT_SETTINGS 10 + +// Enums +#define CLIST_GA_NONE 0 +#define CLIST_GA_EXPAND 1 +#define CLIST_GA_COLLAPSE 2 + +#define NOTIFY_TITLE_HIDE 0 +#define NOTIFY_TITLE_INFO 1 +#define NOTIFY_TITLE_NAME 2 + +#define SESSION_AUTOSCROLL_NONE 0 +#define SESSION_AUTOSCROLL_FIRST 1 +#define SESSION_AUTOSCROLL_LAST 2 + +struct CProtoFilter +{ + tstring strName; + bool bNotificationFilter; + bool bContactlistFilter; + + bool bTempNotificationFilter; + bool bTempContactlistFilter; +}; + +class CConfig +{ +public: + static void Initialize(); + static void Shutdown(); + + static void LoadSettings(); + static void SaveSettings(); + + // InitDialogHook Callback + static int InitOptionsDialog(WPARAM wParam, LPARAM lParam); + // OnConnectionChanged + static void OnConnectionChanged(); + + // Dialog WndProc + static INT_PTR CALLBACK AppearanceDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK ChatDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK NotificationsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK ContactlistDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + + static bool GetBoolSetting(int iSetting); + static int GetIntSetting(int iSetting); + static bool GetProtocolNotificationFilter(tstring strProtocol); + static bool GetProtocolContactlistFilter(tstring strProtocol); + + static LOGFONT &GetFont(int iFont); + static int GetFontHeight(int iFont); +private: + static int GetSampleField(int iFont); + static void ClearTree(HWND hTree); + static void FillTree(HWND hTree,bool bCList=false); + static void FillDeviceBox(HWND hBox); + + static HWND hDeviceBox; + static vector m_ProtoList; + + static HANDLE m_hSampleFont[FONT_SETTINGS]; + static TEXTMETRIC m_tmFontInfo[FONT_SETTINGS]; + static LOGFONT m_logfont[FONT_SETTINGS]; + static LOGFONT m_templogfont[FONT_SETTINGS]; + + static void LoadFontSettings(int iFont); + static void SaveFontSettings(int iFont); + + static void UpdateFontSettings(int iFont); + + static bool m_abBoolSettings[BOOL_SETTINGS]; + static int m_aiIntSettings[INT_SETTINGS]; + static bool m_bInitializingDialog; + static HANDLE m_hOptionsInitHook; + +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/CContactList.cpp b/plugins/MirandaG15/src/CContactList.cpp new file mode 100644 index 0000000000..c2ba33e529 --- /dev/null +++ b/plugins/MirandaG15/src/CContactList.cpp @@ -0,0 +1,1174 @@ +#include "stdafx.h" +#include "CContactList.h" +#include "CConfig.h" +#include "CAppletManager.h" + +const int aiStatusPriority[] = { 0, // ID_STATUS_OFFLINE 40071 + 9, // ID_STATUS_ONLINE 40072 + 8, // ID_STATUS_AWAY 40073 + 1, // ID_STATUS_DND 40074 + 7, // ID_STATUS_NA 40075 + 6, // ID_STATUS_OCCUPIED 40076 + 10, // ID_STATUS_FREECHAT 40077 + 9, // ID_STATUS_INVISIBLE 40078 + 8, // ID_STATUS_ONTHEPHONE 40079 + 8 // ID_STATUS_OUTTOLUNCH 40080 + }; + +//************************************************************************ +// constructor +//************************************************************************ +CContactList::CContactList() +{ + m_bUseGroups = false; + m_bUseMetaContacts = false; + m_dwLastScroll = 0; +} + +//************************************************************************ +// destructor +//************************************************************************ +CContactList::~CContactList() +{ +} + +//************************************************************************ +// initializes the list +//************************************************************************ +bool CContactList::Initialize() +{ + if(!CLCDList::Initialize()) + return false; + + InitializeGroupObjects(); + + RefreshList(); + + return true; +} + +//************************************************************************ +// deinitializes the list +//************************************************************************ +bool CContactList::Shutdown() +{ + if(!CLCDList::Shutdown()) + return false; + + UninitializeGroupObjects(); + + return false; +} + + + +//************************************************************************ +// returns the contacts ccontactlistentry class +//************************************************************************ +CContactListEntry *CContactList::GetContactData(CListEntry *pEntry) +{ + if(pEntry->GetType() == ITEM) + return ((CListItem*)pEntry)->GetItemData(); + else + return ((CListContainer*)pEntry)->GetGroupData()->pContactListEntry; +} + + + +//************************************************************************ +// returns the contacts group path +//************************************************************************ +tstring CContactList::GetContactGroupPath(HANDLE hContact) +{ + tstring strGroup = _T(""); + if(db_get_b(0, "MetaContacts", "Enabled", 1) && CAppletManager::IsSubContact(hContact)) + { + HANDLE hMetaContact = (HANDLE)CallService(MS_MC_GETMETACONTACT, (WPARAM)hContact, NULL); + if(CConfig::GetBoolSetting(CLIST_USEGROUPS)) + strGroup = CAppletManager::GetContactGroup(hMetaContact); + + tstring strMetaName = CAppletManager::GetContactDisplayname(hMetaContact); + strGroup += (strGroup.empty()?_T(""):_T("\\"))+ strMetaName; + } + else + strGroup = CAppletManager::GetContactGroup(hContact); + return strGroup; +} + +//************************************************************************ +// adds a contact to the list +//************************************************************************ +void CContactList::AddContact(HANDLE hContact) +{ + CListContainer *pGroup = NULL; + + tstring strName = CAppletManager::GetContactDisplayname(hContact); + char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(UINT)hContact,0); + + tstring strGroup = GetContactGroupPath(hContact); + // ignore contacts without a valid protocoll + if(szProto == NULL) + return; + + int iStatus = db_get_w(hContact,szProto,"Status",ID_STATUS_OFFLINE); + char *szStatus = (char *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iStatus, 0); + + CContactListEntry *psContact = new CContactListEntry(); + + psContact->strName = strName; + psContact->iMessages = 0; + psContact->hHandle = hContact; + + psContact->iStatus = iStatus; + + if(szStatus != NULL) + psContact->strStatus =toTstring(szStatus); + psContact->strProto = toTstring(szProto); + + // check wether the contact should be listed + if(!IsVisible(psContact)) { + delete psContact; + return; + } + + // Don't add metacontacts as contacts + if(!stricmp(szProto,"MetaContacts")) + { + if(!CConfig::GetBoolSetting(CLIST_USEGROUPS)) + strGroup = _T(""); + strGroup += (strGroup.empty()?_T(""):_T("\\"))+psContact->strName; + pGroup = GetGroupByString(strGroup); + if(pGroup == NULL) + pGroup = AddGroupByString(strGroup); + pGroup->GetGroupData()->hMetaContact = hContact; + pGroup->GetGroupData()->pContactListEntry = psContact; + + pGroup = (CListContainer*)pGroup->GetParent(); + if(pGroup->GetType() != ROOT && iStatus != ID_STATUS_OFFLINE) + ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,1); + + pGroup->sort(CContactList::CompareEntries); + + // check that all subcontacts exist + int numContacts = CallService(MS_MC_GETNUMCONTACTS,(WPARAM)hContact,0); + HANDLE hSubContact = NULL; + for(int i=0;i *pItem = NULL; + if((!CAppletManager::IsSubContact(hContact) && !CConfig::GetBoolSetting(CLIST_USEGROUPS)) || strGroup.empty()) + { + pItem = AddItem(psContact); + ((CListContainer*)this)->sort(CContactList::CompareEntries); + } + else + { + pGroup = GetGroupByString(strGroup); + if(pGroup == NULL) { + pGroup = AddGroupByString(strGroup); + } + pItem = pGroup->AddItem(psContact); + + if(!CAppletManager::IsSubContact(hContact) && iStatus != ID_STATUS_OFFLINE) + ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,1); + + pGroup->sort(CContactList::CompareEntries); + } + + UpdateMessageCounter((CListEntry*)pItem); +} + +//************************************************************************ +// returns wether a contact should be listed or not +//************************************************************************ +bool CContactList::IsVisible(CContactListEntry *pEntry) { + if(!pEntry) { + return false; + } + + if(pEntry->strProto != _T("MetaContacts")) { + if(pEntry->iStatus == ID_STATUS_OFFLINE && CConfig::GetBoolSetting(CLIST_HIDEOFFLINE)) { + return false; + } + } else { + if(pEntry->iStatus == ID_STATUS_OFFLINE) { + DWORD dwNumContacts = (DWORD)CallService(MS_MC_GETNUMCONTACTS,(WPARAM)pEntry->hHandle,0); + HANDLE hSubContact = NULL; + char *szProto; + for(int i=0;ihHandle,i); + szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(UINT)hSubContact,0); + if(db_get_w(hSubContact,szProto,"Status",ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) { + return true; + } + } + } + } + + if(pEntry->iMessages > 0) + return true; + + if(CConfig::GetBoolSetting(CLIST_USEIGNORE)) { + if(db_get_b(pEntry->hHandle,"CList","Hidden",0)) + return false; + else if(CAppletManager::IsSubContact(pEntry->hHandle)) { + HANDLE hMetaContact = (HANDLE) CallService(MS_MC_GETMETACONTACT, (WPARAM)pEntry->hHandle, 0); + if(db_get_b(hMetaContact,"CList","Hidden",0)) { + return false; + } + } + } + + + if(!CConfig::GetProtocolContactlistFilter(pEntry->strProto)) + return false; + + if(CConfig::GetBoolSetting(CLIST_HIDEOFFLINE) && pEntry->iStatus == ID_STATUS_OFFLINE) + return false; + + return true; +} + +//************************************************************************ +// removes a contact from the list +//************************************************************************ +void CContactList::RemoveContact(HANDLE hContact) { + CListContainer *pGroup = NULL; + + ///tstring strGroup = GetContactGroupPath(hContact); + + CListEntry *pContactEntry = FindContact(hContact); + if(!pContactEntry) { + return; + } + + if( !CConfig::GetBoolSetting(CLIST_USEGROUPS)){ + if(pContactEntry->GetType() == ITEM) + RemoveItem(((CListItem*)pContactEntry)->GetItemData()); + else + RemoveGroup(((CListContainer*)pContactEntry)->GetGroupData()); + } else { + pGroup = (CListContainer*)pContactEntry->GetParent(); + ASSERT(pGroup != NULL); + + CContactListEntry *pEntry = GetContactData(pContactEntry); + if(!pEntry) { + return; + } + // Update the contacts group if it has one + if(pGroup->GetType() != ROOT) + { + if(!CAppletManager::IsSubContact(hContact) && pEntry->iStatus != ID_STATUS_OFFLINE) + ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,-1); + + if(!CAppletManager::IsSubContact(hContact) && pEntry->iMessages > 0) + ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,0,-pEntry->iMessages); + } + + if(pContactEntry->GetType() == ITEM) + pGroup->RemoveItem(((CListItem*)pContactEntry)->GetItemData()); + else { + pGroup->RemoveGroup(((CListContainer*)pContactEntry)->GetGroupData()); + // Reenumerate all subcontacts (maybe MetaContacts was disabled + int numContacts = CallService(MS_MC_GETNUMCONTACTS,(WPARAM)hContact,0); + HANDLE hSubContact = NULL; + for(int i=0;i *pParent = (CListContainer*)pGroup->GetParent(); + while(pParent != NULL && pGroup->IsEmpty() && !pGroup->GetGroupData()->hMetaContact) + { + pParent->RemoveGroup(pGroup->GetGroupData()); + pGroup = pParent; + pParent = (CListContainer*)pGroup->GetParent(); + } + } +} + +//************************************************************************ +// get group by string +//************************************************************************ +CListContainer *CContactList::GetGroupByString(tstring strGroup) +{ + tstring strParse = strGroup; + CListContainer *pGroup = (CListContainer*)this; + tstring::size_type pos; + while((pos = strParse.find('\\')) != tstring::npos ) + { + strGroup = strParse.substr(0,pos); + strParse = strParse.substr(pos+1); + + pGroup = FindGroupInGroup(strGroup,pGroup); + if(pGroup == NULL) + return NULL; + } + pGroup = FindGroupInGroup(strParse,pGroup); + return pGroup; +} + +//************************************************************************ +// Adds a group +//************************************************************************ +CListContainer *CContactList::AddGroupByString(tstring strGroup) +{ + tstring strParse = strGroup; + tstring strPath = _T(""); + + CListContainer *pGroup = (CListContainer*)this; + CListContainer *pGroup2 = NULL; + tstring::size_type pos; + while((pos = strParse.find('\\')) != tstring::npos ) + { + strGroup = strParse.substr(0,pos); + strParse = strParse.substr(pos+1); + strPath += strGroup; + + if(pGroup2 = FindGroupInGroup(strGroup,pGroup)) + pGroup = pGroup2; + else + { + CContactListGroup *pGroupObject = GetGroupObjectByPath(strPath); + if(!pGroupObject) + pGroupObject = CreateGroupObjectByPath(strPath); + pGroup2 = pGroup->InsertGroup(pGroup->begin(),pGroupObject); + pGroup->sort(CContactList::CompareEntries); + pGroup = pGroup2; + } + ASSERT(pGroup != NULL); + strPath += _T("\\"); + } + strPath += strParse; + if(pGroup2 = FindGroupInGroup(strParse,pGroup)) + return pGroup2; + else + { + CContactListGroup *pGroupObject = GetGroupObjectByPath(strPath); + if(!pGroupObject) + pGroupObject = CreateGroupObjectByPath(strPath); + pGroup2 = pGroup->InsertGroup(pGroup->begin(),pGroupObject); + pGroup->sort(CContactList::CompareEntries); + return pGroup2; + } +} + +//************************************************************************ +// returns the contact's status +//************************************************************************ +int CContactList::GetContactStatus(HANDLE hContact) +{ + CListEntry *pContactEntry = FindContact(hContact); + if(!pContactEntry) + return ID_STATUS_OFFLINE; + + + CContactListEntry *pEntry = GetContactData(pContactEntry); + if(!pEntry) { + return ID_STATUS_OFFLINE; + } + return pEntry->iStatus; +} + + + +//************************************************************************ +// Called to delete the specified item +//************************************************************************ +void CContactList::DeleteItem(CContactListEntry *pEntry) +{ + delete pEntry; +} + +//************************************************************************ +// Called to delete the specified group +//************************************************************************ +void CContactList::DeleteGroup(CContactListGroup *pGroup) +{ +} + +//************************************************************************ +// Called to draw the specified entry +//************************************************************************ +void CContactList::DrawEntry(CLCDGfx *pGfx,CContactListEntry *pEntry,bool bSelected) +{ + if(pEntry == NULL) { + return; + } + + int iOffset = 0; + tstring strText = _T(""); + if(pEntry->iMessages > 0) + { + strText = _T("["); + strText += pEntry->strMessages; + strText += _T("]"); + } + strText += pEntry->strName; + + if(CConfig::GetBoolSetting(CLIST_SHOWPROTO) && !CConfig::GetBoolSetting(CLIST_COLUMNS)) + { + int w = pGfx->GetClipWidth(); + pGfx->DrawText(w-w*0.3,0,w*0.3,pEntry->strProto); + pGfx->DrawText(8,0,w*0.7-8,strText); + } + else + pGfx->DrawText(8,0,pGfx->GetClipWidth()-8,strText); + + + pGfx->DrawBitmap(1,ceil((pGfx->GetClipHeight()-5)/2.0f),5,5,CAppletManager::GetInstance()->GetStatusBitmap(pEntry->iStatus)); + + if(bSelected && (GetTickCount() - m_dwLastScroll < 1000 || !CConfig::GetBoolSetting(CLIST_SELECTION))) + { + RECT invert = { 0,0,GetWidth(),m_iFontHeight}; + InvertRect(pGfx->GetHDC(), &invert); + } +} + +//************************************************************************ +// Called to draw the specified group +//************************************************************************ +void CContactList::DrawGroup(CLCDGfx *pGfx,CContactListGroup *pGroup,bool bOpen,bool bSelected) +{ + if(pGroup == NULL || ( pGroup->hMetaContact && pGroup->pContactListEntry == NULL)) { + return; + } + + char num[10],num2[10]; + itoa(pGroup->iMembers,num,10); + itoa(pGroup->iOnline,num2,10); + + int iEvents = pGroup->iEvents; + tstring strText = pGroup->strName; + + if(!pGroup->hMetaContact) + { + if(CConfig::GetBoolSetting(CLIST_COUNTERS)) + strText = strText + _T(" (") + toTstring(num2).c_str()+ _T("/") + toTstring(num).c_str() + _T(")"); + } + else + { + pGfx->DrawBitmap(8,ceil((pGfx->GetClipHeight()-5)/2.0f),5,5,CAppletManager::GetInstance()->GetStatusBitmap(pGroup->pContactListEntry->iStatus)); + iEvents += pGroup->pContactListEntry->iMessages; + } + + if(iEvents != 0) + { + itoa(iEvents,num,10); + strText = _T("[") + toTstring(num) + _T("]") + strText; + } + + int iOffset = !pGroup->hMetaContact?m_iFontHeight*0.8:m_iFontHeight*0.8+8; + pGfx->DrawText(iOffset,0,pGfx->GetClipWidth()-iOffset,strText.c_str()); + + if(bOpen) + pGfx->DrawText(1,0,_T("-")); + else + pGfx->DrawText(1,0,_T("+")); + + if(bSelected && (GetTickCount() - m_dwLastScroll < 1000|| !CConfig::GetBoolSetting(CLIST_SELECTION))) + { + RECT invert2 = { 0,0,GetWidth(),m_iFontHeight}; + InvertRect(pGfx->GetHDC(),&invert2); + } +} + + +//************************************************************************ +// Called to compare two entrys +//************************************************************************ +bool CContactList::CompareEntries(CListEntry *pLeft,CListEntry *pRight) +{ + CContactListEntry *pLeftEntry = GetContactData(pLeft); + CContactListEntry *pRightEntry = GetContactData(pRight); + + if(pLeftEntry && pRightEntry) + { + int iLeftMessages = pLeftEntry->iMessages; + int iRightMessages = pRightEntry->iMessages; + + if(pLeft->GetType() == CONTAINER) + iLeftMessages += ((CListContainer*)pLeft)->GetGroupData()->iEvents; + if(pRight->GetType() == CONTAINER) + iRightMessages += ((CListContainer*)pRight)->GetGroupData()->iEvents; + + if (!iRightMessages && iLeftMessages) + return true; + else if (iRightMessages && !iLeftMessages) + return false; + else if (iLeftMessages && iRightMessages) + return (iLeftMessages > iRightMessages); + else if(pLeftEntry->iStatus != pRightEntry->iStatus) + return (aiStatusPriority[pLeftEntry->iStatus - ID_STATUS_OFFLINE] > aiStatusPriority[pRightEntry->iStatus - ID_STATUS_OFFLINE]); + else + return _tcsicmp(pLeftEntry->strName.c_str(),pRightEntry->strName.c_str())<0; + } + else if(pLeft->GetType() == ITEM && pRight->GetType() == CONTAINER) + return false; + else if(pLeft->GetType() == CONTAINER && pRight->GetType() == ITEM) + return true; + else if(pLeft->GetType() == CONTAINER && pRight->GetType() == CONTAINER) + { + CContactListGroup *pGroup1 = ((CListContainer*)pLeft)->GetGroupData(); + CContactListGroup *pGroup2 = ((CListContainer*)pRight)->GetGroupData(); + + if (!pGroup2->iEvents && pGroup1->iEvents) + return true; + else if (pGroup2->iEvents && !pGroup1->iEvents) + return false; + else if (pGroup1->iEvents && pGroup2->iEvents) + return (pGroup1->iEvents > pGroup2->iEvents); + else + return _tcsicmp(pGroup1->strName.c_str(),pGroup2->strName.c_str())<0; + } +} + +//************************************************************************ +// refreshes the list +//************************************************************************ +void CContactList::RefreshList() +{ + if(db_get_b(NULL,"MetaContacts","Enabled",1) != m_bUseMetaContacts || + CConfig::GetBoolSetting(CLIST_USEGROUPS) != m_bUseGroups) + { + InitializeGroupObjects(); + Clear(); + } + m_bUseGroups = CConfig::GetBoolSetting(CLIST_USEGROUPS); + m_bUseMetaContacts = db_get_b(NULL,"MetaContacts","Enabled",1); + + CListEntry *pContactEntry = NULL; + HANDLE hContact = db_find_first(); + while(hContact != NULL) + { + pContactEntry = FindContact(hContact); + if(!pContactEntry) + AddContact(hContact); + else if(pContactEntry && !IsVisible(GetContactData(pContactEntry))) + RemoveContact(hContact); + hContact = db_find_next(hContact); + } +} + +//************************************************************************ +// set the contactlists font +//************************************************************************ +bool CContactList::SetFont(LOGFONT &lf) +{ + if(!CLCDList::SetFont(lf)) + return false; + + SetEntryHeight(m_iFontHeight<5?5:m_iFontHeight); + + return true; +} + +//************************************************************************ +// called when the configuration has changed +//************************************************************************ +void CContactList::OnConfigChanged() +{ + RefreshList(); +} + + +//************************************************************************ +// returns the entry for the specified group name +//************************************************************************ +CListContainer *CContactList::FindGroup(tstring strGroup) +{ + return FindGroupInGroup(strGroup,(CListContainer*)this); +} + +//************************************************************************ +// returns the entry for the specified group name +//************************************************************************ +CListContainer *CContactList::FindGroupInGroup(tstring strGroup,CListContainer *pGroup) +{ + CListContainer::iterator iter = pGroup->begin(); + CListContainer *pItem = NULL; + while(!pGroup->empty() && iter != pGroup->end()) + { + if((*iter)->GetType() == CONTAINER) + { + pItem = (CListContainer*)*iter; + if(pItem->GetGroupData()->strName == strGroup) + return pItem; + + //pItem = FindGroupInGroup(strGroup,(CListContainer *)*iter); + //if(pItem) + // return pItem; + } + iter++; + } + return NULL; +} + +//************************************************************************ +// returns the entry for the specified handle +//************************************************************************ +CListEntry *CContactList::FindContact(HANDLE hContact) +{ + if(hContact == NULL) + return NULL; + + return FindContactInGroup(hContact,(CListContainer*)this); +} + +//************************************************************************ +// returns the entry for the specified handle +//************************************************************************ +CListEntry *CContactList::FindContactInGroup(HANDLE hContact,CListContainer *pGroup) +{ + if(hContact == NULL) + return NULL; + + CListItem *pItemEntry = NULL; + CListEntry *pEntry = NULL; + CListContainer *pGroupEntry = NULL; + CListContainer::iterator iter = pGroup->begin(); + while(iter != pGroup->end()) + { + if((*iter)->GetType() == ITEM) + { + pItemEntry = (CListItem*)*iter; + if(pItemEntry->GetItemData()->hHandle == hContact) + return *iter; + } + else + { + pGroupEntry = (CListContainer *)*iter; + if(pGroupEntry->GetGroupData()->hMetaContact == hContact) + return *iter; + + pEntry = FindContactInGroup(hContact,pGroupEntry); + if(pEntry) + return pEntry; + } + iter++; + } + return NULL; +} + + +//************************************************************************ +// called when a contacts hidden flag has changed +//************************************************************************ +void CContactList::OnContactHiddenChanged(HANDLE hContact, bool bHidden) +{ + CListEntry *pContactEntry = FindContact(hContact); + + if(!pContactEntry && !bHidden) + { + AddContact(hContact); + return; + } + else if(!pContactEntry) + return; + + if(!IsVisible(GetContactData(pContactEntry))) + RemoveContact(hContact); +} + +//************************************************************************ +// called when a contacts nickname has changed +//************************************************************************ +void CContactList::OnContactNickChanged(HANDLE hContact, tstring strNick) +{ + CListEntry *pContactEntry = FindContact(hContact); + if(!pContactEntry) + return; + + if(pContactEntry->GetType() == CONTAINER) + { + CListContainer *pGroup = ((CListContainer*)pContactEntry); + pGroup->GetGroupData()->strName = strNick; + tstring strPath = GetContactGroupPath(hContact); + pGroup->GetGroupData()->strPath = strPath + (strPath.empty()?_T(""):_T("\\")) + strNick; + } + + CContactListEntry* pEntry = GetContactData(pContactEntry); + if(!pEntry) { + return; + } + + pEntry->strName = strNick; + ((CListContainer*)pContactEntry->GetParent())->sort(CContactList::CompareEntries); +} + +//************************************************************************ +// called when a contacts status has changed +//************************************************************************ +void CContactList::OnStatusChange(HANDLE hContact,int iStatus) +{ + // find the entry in the list + CListEntry *pContactEntry = FindContact(hContact); + if(!pContactEntry) + { + AddContact(hContact); + return; + } + + + CContactListEntry *pItemData = GetContactData(pContactEntry); + if(!pItemData) { + return; + } + // get the old status + int iOldStatus = pItemData->iStatus; + + // Update the list entry + char *szStatus = (char *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iStatus, 0); + if(szStatus != NULL) + pItemData->strStatus =toTstring(szStatus); + + pItemData->iStatus = iStatus; + + // update the contacts group + CListContainer* pGroup = ((CListContainer*)pContactEntry->GetParent()); + if(pGroup->GetType() != ROOT) + { + if(!CAppletManager::IsSubContact(hContact) && iStatus == ID_STATUS_OFFLINE && iOldStatus != ID_STATUS_OFFLINE) + ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,-1); + + else if(!CAppletManager::IsSubContact(hContact) && iStatus != ID_STATUS_OFFLINE && iOldStatus == ID_STATUS_OFFLINE) + ChangeGroupObjectCounters(pGroup->GetGroupData()->strPath,0,1); + } + + // check if the entry is still visible + if(!IsVisible(pItemData)) + { + RemoveContact(hContact); + return; + } + + // sort the list + pGroup->sort(CContactList::CompareEntries); + +} + + + +//************************************************************************ +// called when the contacts message count has changed +//************************************************************************ +void CContactList::OnMessageCountChanged(HANDLE hContact) +{ + CListEntry *pContactEntry = FindContact(hContact); + if(!pContactEntry) + { + AddContact(hContact); + return; + } + + UpdateMessageCounter(pContactEntry); + + if(!IsVisible(GetContactData(pContactEntry))) + RemoveContact(hContact); + ((CListContainer*)pContactEntry->GetParent())->sort(CContactList::CompareEntries); + +} + +//************************************************************************ +// called when a contact has been added +//************************************************************************ +void CContactList::OnContactAdded(HANDLE hContact) +{ + // Update the list + AddContact(hContact); + + // increase the membercount of the new group, and check if it needs to be created + tstring strGroup = GetContactGroupPath(hContact); + if(!strGroup.empty()) + { + CContactListGroup *pGroup = GetGroupObjectByPath(strGroup); + if(!pGroup) + pGroup = CreateGroupObjectByPath(strGroup); + + if(!CAppletManager::IsSubContact(hContact)) + ChangeGroupObjectCounters(strGroup,1); + } +} + +//************************************************************************ +// called when a contact has been deleted +//************************************************************************ +void CContactList::OnContactDeleted(HANDLE hContact) +{ + // Update the list + RemoveContact(hContact); + + // Decrease the membercount of the old group, and check if it needs to be deleted + int res = 0; + tstring strGroup = GetContactGroupPath(hContact); + if(!strGroup.empty()) + { + CContactListGroup *pGroup = GetGroupObjectByPath(strGroup); + + + if(!CAppletManager::IsSubContact(hContact)) + ChangeGroupObjectCounters(strGroup,-1); + + if(pGroup->iMembers <= 0) + DeleteGroupObjectByPath(pGroup->strPath); + } +} + +//************************************************************************ +// called when a contacts group has changed +//************************************************************************ +void CContactList::OnContactGroupChanged(HANDLE hContact,tstring strGroup) +{ + bool bMetaContact = false; + + + strGroup = GetContactGroupPath(hContact); + + // Decrease the membercount of the old group + CListEntry *pContactEntry = FindContact(hContact); + CContactListGroup *pOldGroup = NULL; + // If the contactentry was not found, try adding the contact (metacontacts fix) + if(!pContactEntry) { + return; + } + if(pContactEntry->GetType() == CONTAINER) + bMetaContact = true; + + + CListContainer* pContainer = ((CListContainer*)pContactEntry->GetParent()); + // Update the contacts group if it has one + if(pContainer->GetType() != ROOT) + { + pOldGroup = pContainer->GetGroupData(); + if(!CAppletManager::IsSubContact(hContact)) + ChangeGroupObjectCounters(pOldGroup->strPath,-1); + } + + // increase the membercount of the new group, and check if it needs to be created + if(!strGroup.empty()) + { + CContactListGroup *pGroup = GetGroupObjectByPath(strGroup); + if(!pGroup) + pGroup = CreateGroupObjectByPath(strGroup); + if(!CAppletManager::IsSubContact(hContact)) + ChangeGroupObjectCounters(strGroup,1); + } + + // move subcontacts + if(pContactEntry->GetType() == CONTAINER) + { + CListContainer *pGroup = (CListContainer*)pContactEntry; + CListContainer::iterator iter = pGroup->begin(); + while(!pGroup->empty()) + { + iter = pGroup->begin(); + if((*iter)->GetType() == ITEM) + OnContactGroupChanged(GetContactData(*iter)->hHandle,_T("")); + bool b = pGroup->empty(); + int i = pGroup->size(); + Sleep(1); + } + } + + // update the list + RemoveContact(hContact); + AddContact(hContact); + + if(bMetaContact) + { + tstring strName = CAppletManager::GetContactDisplayname(hContact); + tstring strPath = _T(""); + if(pOldGroup) + strPath += pOldGroup->strPath; + strPath += (strPath.empty()?_T(""):_T("\\")) + strName; + DeleteGroupObjectByPath(strPath); + } + + // check if the old group ( if it exists ) needs to be deleted + if(pOldGroup && !pOldGroup->hMetaContact && pOldGroup->iMembers <= 0 && pOldGroup->iGroups <= 0) + DeleteGroupObjectByPath(pOldGroup->strPath); +} + +//************************************************************************ +// updates the message count for the specified contact +//************************************************************************ +void CContactList::UpdateMessageCounter(CListEntry *pContactEntry) +{ + CContactListEntry *pEntry = GetContactData(pContactEntry); + if(!pEntry) { + return; + } + int iOldMessages = pEntry->iMessages; + + bool bSort = false; + HANDLE hEvent= NULL; + + hEvent = db_event_firstUnread(pEntry->hHandle); + if(CAppletManager::IsMessageWindowOpen(pEntry->hHandle) || (hEvent == NULL && pEntry->iMessages > 0)) + { + pEntry->iMessages = 0; + bSort = true; + } + else + { + pEntry->iMessages = 0; + HANDLE hLastEvent = db_event_last(pEntry->hHandle); + while(hLastEvent != NULL && hEvent != NULL) + { + pEntry->iMessages++; + if(hLastEvent == hEvent) + break; + hLastEvent = db_event_prev(hLastEvent); + } + } + if(pEntry->iMessages >= 100) + pEntry->strMessages = _T(">99"); + else + { + char buffer[8]; + buffer[0] = 0; + itoa(pEntry->iMessages,buffer,10); + pEntry->strMessages = toTstring(buffer); + } + + CListContainer* pContainer = ((CListContainer*)pContactEntry->GetParent()); + // Update the contacts group if it has one + if(pContainer->GetType() != ROOT) + { + // Update the groups event count + if(iOldMessages != 0 && pEntry->iMessages == 0) + ChangeGroupObjectCounters(pContainer->GetGroupData()->strPath,0,0,-1); + else if(iOldMessages == 0 && pEntry->iMessages != 0) + ChangeGroupObjectCounters(pContainer->GetGroupData()->strPath,0,0,1); + else + return; + + // sort the groups parent + ((CListContainer*)pContainer->GetParent())->sort(CContactList::CompareEntries); + } +} + +//************************************************************************ +// changes the groups membercount +//************************************************************************ +void CContactList::ChangeGroupObjectCounters(tstring strGroup,int iMembers,int iOnline,int iEvents) +{ + CContactListGroup* pGroup = GetGroupObjectByPath(strGroup); + if(!pGroup) + return; + + pGroup->iMembers += iMembers; + pGroup->iOnline += iOnline; + pGroup->iEvents += iEvents; + + tstring strParse = pGroup->strPath; + tstring::size_type pos; + + while((pos = strParse.rfind('\\')) != tstring::npos ) + { + strParse = strParse.substr(0,pos); + + pGroup = GetGroupObjectByPath(strParse); + if(!pGroup) + break; + pGroup->iMembers += iMembers; + pGroup->iOnline += iOnline; + pGroup->iEvents += iEvents; + } +} + +//************************************************************************ +// uninitializes the group objects +//************************************************************************ +void CContactList::UninitializeGroupObjects() +{ + vector::iterator iter = m_Groups.begin(); + while(iter != m_Groups.end()) + { + delete (*iter); + iter++; + } + m_Groups.clear(); +} + +//************************************************************************ +// initializes the group objects +//************************************************************************ +void CContactList::InitializeGroupObjects() +{ + UninitializeGroupObjects(); + + int res = 0; + CContactListGroup *pGroup = NULL; + + HANDLE hContact = db_find_first(); + HANDLE hMetaContact = NULL; + char *szProto = NULL; + while(hContact != NULL) + { + tstring strGroup = GetContactGroupPath(hContact); + szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(UINT)hContact,0); + if(szProto && db_get_b(NULL,"MetaContacts","Enabled",1) && !stricmp(szProto,"MetaContacts")) + { + tstring strName = CAppletManager::GetContactDisplayname(hContact); + tstring strPath = _T(""); + if(CConfig::GetBoolSetting(CLIST_USEGROUPS)) + strPath += strGroup; + strPath += (strPath.empty()?_T(""):_T("\\")) + strName; + + pGroup = CreateGroupObjectByPath(strPath); + pGroup->hMetaContact = hContact; + + if(!strGroup.empty()) + ChangeGroupObjectCounters(strGroup,1); + } + // If the contact has no group, continue + else if(!strGroup.empty() && CConfig::GetBoolSetting(CLIST_USEGROUPS)) + { + pGroup = GetGroupObjectByPath(strGroup); + + // create the group + if(!pGroup) + pGroup = CreateGroupObjectByPath(strGroup); + + // update it's counters + if(!CAppletManager::IsSubContact(hContact)) + ChangeGroupObjectCounters(strGroup,1); + } + + hContact = db_find_next(hContact); + } +} + +//************************************************************************ +// get group object by string +//************************************************************************ +CContactListGroup *CContactList::GetGroupObjectByPath(tstring strPath) +{ + ASSERT(!strPath.empty()); + + CContactListGroup *pGroup = NULL; + vector::iterator iter = m_Groups.begin(); + for(;iter != m_Groups.end();iter++) + { + if((*iter)->strPath == strPath) + { + pGroup = *iter; + break; + } + } + return pGroup; +} + +//************************************************************************ +// creates a group object by string +//************************************************************************ +CContactListGroup *CContactList::CreateGroupObjectByPath(tstring strPath) +{ + ASSERT(!strPath.empty()); + + CContactListGroup *pNewGroup = new CContactListGroup(); + CContactListGroup *pParentGroup = NULL; + + tstring strParsePath = _T(""); + tstring strName = strPath; + tstring::size_type pos; + + while((pos = strName.find('\\')) != tstring::npos ) + { + strParsePath += strName.substr(0,pos); + strName = strName.substr(pos+1); + + pParentGroup = GetGroupObjectByPath(strParsePath); + if(!pParentGroup) + pParentGroup = CreateGroupObjectByPath(strParsePath); + strParsePath += _T("\\"); + } + + if(pParentGroup) + pParentGroup->iGroups++; + + pNewGroup->strName = strName; + pNewGroup->strPath = strPath; + pNewGroup->iMembers = 0; + pNewGroup->iOnline = 0; + pNewGroup->iGroups = 0; + pNewGroup->iEvents = 0; + pNewGroup->hMetaContact = NULL; + pNewGroup->pContactListEntry = NULL; + + m_Groups.push_back(pNewGroup); + + return pNewGroup; +} + +//************************************************************************ +// deletes a group object by string +//************************************************************************ +void CContactList::DeleteGroupObjectByPath(tstring strPath) +{ + ASSERT(!strPath.empty()); + + CContactListGroup *pParentGroup = NULL; + vector::iterator iter = m_Groups.begin(); + for(iter = m_Groups.begin();iter != m_Groups.end();iter++) + { + if((*iter)->strPath == strPath) + { + CContactListGroup *pGroup = *iter; + m_Groups.erase(iter); + if(pGroup->pContactListEntry) + { + DeleteEntry(pGroup->pContactListEntry); + } + delete pGroup; + + tstring strParse = strPath; + tstring::size_type pos = strParse.rfind('\\'); + if(pos != tstring::npos ) + { + strParse = strParse.substr(0,pos); + pParentGroup = GetGroupObjectByPath(strParse); + pParentGroup->iGroups--; + if(pParentGroup->iMembers <= 0 && pParentGroup->iGroups <= 0) + DeleteGroupObjectByPath(strParse); + } + return; + } + } +} + +void CContactList::SetPosition(CListEntry *pEntry) +{ + CLCDList::SetPosition(pEntry); +} + +bool CContactList::ScrollUp() +{ + m_dwLastScroll = GetTickCount(); + return CLCDList::ScrollUp(); +} + +bool CContactList::ScrollDown() +{ + m_dwLastScroll = GetTickCount(); + return CLCDList::ScrollDown(); +} + +void CContactList::ShowSelection() { + m_dwLastScroll = GetTickCount(); +} \ No newline at end of file diff --git a/plugins/MirandaG15/src/CContactList.h b/plugins/MirandaG15/src/CContactList.h new file mode 100644 index 0000000000..75b129f8fc --- /dev/null +++ b/plugins/MirandaG15/src/CContactList.h @@ -0,0 +1,145 @@ +#ifndef _CCONTACTLIST_H_ +#define _CCONTACTLIST_H_ + +#include "CLCDList.h" + +class CContactListEntry +{ +public: + int iMessages; + tstring strMessages; + HANDLE hHandle; + tstring strName; + tstring strProto; + tstring strStatus; + int iStatus; +}; + +class CContactListGroup +{ +public: + tstring strName; + tstring strPath; + int iMembers; + int iGroups; + int iOnline; + int iEvents; + + HANDLE hMetaContact; + CContactListEntry *pContactListEntry; +}; + +class CContactList : public CLCDList +{ +public: + // constructor + CContactList(); + // destructor + ~CContactList(); + + // initializes the list + bool Initialize(); + // deinitializes the list + bool Shutdown(); + + // called when a contact has been added + void OnContactAdded(HANDLE hContact); + // called when a contact has been deleted + void OnContactDeleted(HANDLE hContact); + // called when the configuration has changed + void OnConfigChanged(); + // called when a contacts group has changed + void OnContactGroupChanged(HANDLE hContact,tstring strGroup); + // called when a contacts hidden flag has changed + void OnContactHiddenChanged(HANDLE hContact, bool bVisibility); + // called when a contacts nickname has changed + void OnContactNickChanged(HANDLE hContact, tstring strNick); + // called when a contacts status has changed + void OnStatusChange(HANDLE hContact,int iStatus); + // called when the contacts message count has changed + void OnMessageCountChanged(HANDLE hContact); + // returns the contact's status + int GetContactStatus(HANDLE hContact); + + // Called to compare two entrys + static bool CompareEntries(CListEntry *pLeft,CListEntry *pRight); + + void SetPosition(CListEntry *pEntry); + bool ScrollUp(); + bool ScrollDown(); + void ShowSelection(); + + bool SetFont(LOGFONT &lf); +protected: + // returns the contacts group path + tstring GetContactGroupPath(HANDLE hContact); + + // adds a contact to the list + void AddContact(HANDLE hContact); + // removes a contact from the list + void RemoveContact(HANDLE hContact); + + // uninitializes the group objects + void UninitializeGroupObjects(); + + // initializes the group objects + void InitializeGroupObjects(); + // get group object by string + CContactListGroup *GetGroupObjectByPath(tstring strPath); + // creates a group object by string + CContactListGroup *CreateGroupObjectByPath(tstring strPath); + // deletes a group object by string + void DeleteGroupObjectByPath(tstring strPath); + + // changes the groups membercount + void ChangeGroupObjectCounters(tstring strGroup,int iMembers,int iOnline=0,int iEvents=0); + + // returns wether a contact should be listed or not + bool IsVisible(CContactListEntry *pEntry); + + // sorts all entries of a group + void SortGroup(CListContainer *pGroup); + + // tries to find a contact in the specified group + CListEntry *FindContactInGroup(HANDLE hContact,CListContainer *pGroup); + + // tries to find a group in the specified group + CListContainer *FindGroupInGroup(tstring strGroup,CListContainer *pGroup); + + // Adds a group + CListContainer *AddGroupByString(tstring strGroup); + // get group by string + CListContainer *GetGroupByString(tstring strGroup); + + // updates the message counter for the specified entry + void UpdateMessageCounter(CListEntry *pContactEntry); + // refreshes the list + void RefreshList(); + + // returns the entry for the specified handle + CListEntry *FindContact(HANDLE hContact); + + // returns the entry for the specified group name + CListContainer *FindGroup(tstring strGroup); + + // returns the contacts ccontactlistentry class + static CContactListEntry *GetContactData(CListEntry *pEntry); + + // Called to delete the specified item + void DeleteItem(CContactListEntry *pEntry); + // Called to delete the specified group + void DeleteGroup(CContactListGroup* pGroup); + // Called to draw the specified group + void DrawGroup(CLCDGfx *pGfx,CContactListGroup* pGroup,bool bOpen,bool bSelected); + // Called to draw the specified entry + void DrawEntry(CLCDGfx *pGfx,CContactListEntry *pEntry,bool bSelected); + + bool m_bUseGroups; + bool m_bUseMetaContacts; + vector m_Groups; + DWORD m_dwLastScroll; + + HBITMAP m_ahBitmaps[8]; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/CContactlistScreen.cpp b/plugins/MirandaG15/src/CContactlistScreen.cpp new file mode 100644 index 0000000000..b9cbebf5b2 --- /dev/null +++ b/plugins/MirandaG15/src/CContactlistScreen.cpp @@ -0,0 +1,315 @@ +#include "stdafx.h" +#include "CContactlistScreen.h" +#include "CConfig.h" +#include "CAppletManager.h" + +//************************************************************************ +// Constructor +//************************************************************************ +CContactlistScreen::CContactlistScreen() +{ +} + +//************************************************************************ +// Destructor +//************************************************************************ +CContactlistScreen::~CContactlistScreen() +{ +} + +//************************************************************************ +// Initializes the screen +//************************************************************************ +bool CContactlistScreen::Initialize() +{ + if(!CScreen::Initialize()) + return false; + + m_ContactList.Initialize(); + m_ContactList.SetOrigin(0, 0); + m_ContactList.SetSize(GetWidth()-5, GetHeight()-(CConfig::GetBoolSetting(SHOW_LABELS)?6:0)); + m_ContactList.SetFont(CConfig::GetFont(FONT_CLIST)); + m_ContactList.SetDrawTreeLines(CConfig::GetBoolSetting(CLIST_DRAWLINES)); + m_ContactList.SetColumns(CConfig::GetBoolSetting(CLIST_COLUMNS)?2:1); + + AddObject(&m_ContactList); + + m_Scrollbar.Initialize(); + m_Scrollbar.SetOrigin(GetWidth()-4,0); + m_Scrollbar.SetSize(4,GetHeight()-(CConfig::GetBoolSetting(SHOW_LABELS)?5:0)); + m_ContactList.SetScrollbar(&m_Scrollbar); + + AddObject(&m_Scrollbar); + + SetButtonBitmap(0,IDB_UP); + SetButtonBitmap(1,IDB_DOWN); + SetButtonBitmap(2,IDB_HISTORY); + SetButtonBitmap(3,IDB_CHAT); + + return true; +} + +//************************************************************************ +// Shutdown the screen +//************************************************************************ +bool CContactlistScreen::Shutdown() +{ + if(!CScreen::Shutdown()) + return false; + + return true; +} + +//************************************************************************ +// Updates the screen +//************************************************************************ +bool CContactlistScreen::Update() +{ + if(!CScreen::Update()) + return false; + + return true; +} + +//************************************************************************ +// Draws the screen +//************************************************************************ +bool CContactlistScreen::Draw(CLCDGfx *pGfx) +{ + if(!CScreen::Draw(pGfx)) + return false; + + return true; +} + +//************************************************************************ +// returns the online status of the specified contact +//************************************************************************ +int CContactlistScreen::GetContactStatus(HANDLE hContact) +{ + return m_ContactList.GetContactStatus(hContact); +} + +//************************************************************************ +// resets the position of the contactlist +//************************************************************************ +void CContactlistScreen::ResetPosition() +{ + // collapse all groups if setting is active + switch(CConfig::GetIntSetting(CLIST_GA)) + { + case CLIST_GA_COLLAPSE: + m_ContactList.CollapseAll(); + break; + case CLIST_GA_EXPAND: + m_ContactList.ExpandAll(); + break; + } + + // select the first item if setting is active + if(CConfig::GetBoolSetting(CLIST_POSITION)) + m_ContactList.SetPosition(m_ContactList.GetFirstEntry()); + + UpdateUseSoftkeyLabel(); +} + +//************************************************************************ +// Called when the screen size has changed +//************************************************************************ +void CContactlistScreen::OnSizeChanged() +{ + CScreen::OnSizeChanged(); + + m_ContactList.OnConfigChanged(); + m_ContactList.SetSize(GetWidth()-5, GetHeight()-(CConfig::GetBoolSetting(SHOW_LABELS)?6:0)); + + m_Scrollbar.SetOrigin(GetWidth()-4,0); + m_Scrollbar.SetSize(4,GetHeight()-(CConfig::GetBoolSetting(SHOW_LABELS)?5:0)); +} + +//************************************************************************ +// Called when the configuration has changed +//************************************************************************ +void CContactlistScreen::OnConfigChanged() +{ + CScreen::OnConfigChanged(); + + m_ContactList.OnConfigChanged(); + m_ContactList.SetDrawTreeLines(CConfig::GetBoolSetting(CLIST_DRAWLINES)); + m_ContactList.SetSize(GetWidth()-5, GetHeight()-(CConfig::GetBoolSetting(SHOW_LABELS)?6:0)); + m_ContactList.SetFont(CConfig::GetFont(FONT_CLIST)); + m_ContactList.SetColumns(CConfig::GetBoolSetting(CLIST_COLUMNS)?2:1); + + m_Scrollbar.SetOrigin(GetWidth()-4,0); + m_Scrollbar.SetSize(4,GetHeight()-(CConfig::GetBoolSetting(SHOW_LABELS)?5:0)); +} + +//************************************************************************ +// Called when an event is received +//************************************************************************ +void CContactlistScreen::OnEventReceived(CEvent *pEvent) +{ + int iStatus = 0; + switch(pEvent->eType) + { + case EVENT_SIGNED_ON: + case EVENT_SIGNED_OFF: + case EVENT_STATUS: + m_ContactList.OnStatusChange(pEvent->hContact,pEvent->iValue); + break; + case EVENT_CONTACT_NICK: + m_ContactList.OnContactNickChanged(pEvent->hContact,pEvent->strValue); + break; + case EVENT_CONTACT_ADDED: + m_ContactList.OnContactAdded(pEvent->hContact); + break; + case EVENT_CONTACT_DELETED: + m_ContactList.OnContactDeleted(pEvent->hContact); + break; + case EVENT_MSG_RECEIVED: + case EVENT_MESSAGEWINDOW: + m_ContactList.OnMessageCountChanged(pEvent->hContact); + break; + case EVENT_CONTACT_HIDDEN: + m_ContactList.OnContactHiddenChanged(pEvent->hContact,pEvent->iValue); + break; + case EVENT_CONTACT_GROUP: + m_ContactList.OnContactGroupChanged(pEvent->hContact,pEvent->strValue); + break; + } +} + +//************************************************************************ +// Called when a chat session was opened +//************************************************************************ +void CContactlistScreen::OnSessionOpened(HANDLE hContact) +{ + m_ContactList.OnMessageCountChanged(hContact); +} + +//************************************************************************ +// Called when an LCD-button is pressed +//************************************************************************ +void CContactlistScreen::OnLCDButtonDown(int iButton) +{ + m_bLongPress = false; + if(iButton == LGLCDBUTTON_CANCEL) { + CAppletManager::GetInstance()->ActivatePreviousScreen(); + } else if(iButton == LGLCDBUTTON_BUTTON1 || iButton == LGLCDBUTTON_DOWN) { + m_ContactList.ScrollDown(); + } else if(iButton == LGLCDBUTTON_BUTTON0 || iButton == LGLCDBUTTON_UP) { + m_ContactList.ScrollUp(); + } else if(iButton == LGLCDBUTTON_BUTTON2 || iButton == LGLCDBUTTON_MENU) { + CAppletManager::GetInstance()->ActivateEventScreen(); + return; + } else if(iButton == LGLCDBUTTON_BUTTON3 || iButton == LGLCDBUTTON_OK) { + CListEntry *pEntry = m_ContactList.GetSelectedEntry(); + if(!pEntry) + return; + if(pEntry->GetType() == CONTAINER) { + CListContainer *pContainer = (CListContainer*)pEntry; + if(pContainer->GetGroupData()->hMetaContact == NULL) { + pContainer->ToggleOpen(); + } + } else if(pEntry->GetType() == ITEM) + { + CContactListEntry *pContact = ((CListItem*)pEntry)->GetItemData(); + if(!pContact->hHandle) + return; + CAppletManager::GetInstance()->ActivateChatScreen(pContact->hHandle); + return; + } + } + + UpdateUseSoftkeyLabel(); +} + +//************************************************************************ +// Called when an LCD-button event is repeated +//************************************************************************ +void CContactlistScreen::OnLCDButtonRepeated(int iButton) +{ + m_bLongPress = true; + if(iButton == LGLCDBUTTON_BUTTON1 || iButton == LGLCDBUTTON_DOWN) { + m_ContactList.ScrollDown(); + } else if(iButton == LGLCDBUTTON_BUTTON0 || iButton == LGLCDBUTTON_UP) { + m_ContactList.ScrollUp(); + } else if(iButton == LGLCDBUTTON_BUTTON3 || iButton == LGLCDBUTTON_OK) { + UpdateUseSoftkeyLabel(); + } +} + +//************************************************************************ +// Called when an LCD-button is released +//************************************************************************ +void CContactlistScreen::OnLCDButtonUp(int iButton) +{ + if(iButton == LGLCDBUTTON_BUTTON3 || iButton == LGLCDBUTTON_OK) { + m_ContactList.ShowSelection(); + + CListEntry *pEntry = m_ContactList.GetSelectedEntry(); + if(!pEntry) + return; + if(pEntry->GetType() == CONTAINER) { + CListContainer *pContainer = (CListContainer*)pEntry; + if(pContainer->GetGroupData()->hMetaContact != NULL) { + if(m_bLongPress) { + pContainer->ToggleOpen(); + } else { + CAppletManager::GetInstance()->ActivateChatScreen(pContainer->GetGroupData()->hMetaContact); + } + } + } + } + m_bLongPress = false; + UpdateUseSoftkeyLabel(); +} + +//************************************************************************ +// Called when the screen is activated +//************************************************************************ +void CContactlistScreen::OnActivation() +{ + +} + +//************************************************************************ +// Called when the screen is deactivated +//************************************************************************ +void CContactlistScreen::OnDeactivation() +{ +} + +//************************************************************************ +// Called when the screen has expired +//************************************************************************ +void CContactlistScreen::OnExpiration() +{ +} + +//************************************************************************ +// updates the use softkey label +//************************************************************************ +void CContactlistScreen::UpdateUseSoftkeyLabel() +{ + CListEntry *pEntry = m_ContactList.GetSelectedEntry(); + if(!pEntry) + return; + + if(pEntry->GetType() == CONTAINER) + { + CListContainer *pContainer = (CListContainer*)pEntry; + if(pContainer->GetGroupData()->hMetaContact == NULL || m_bLongPress) { + if(((CListContainer*)pEntry)->IsOpen()) + SetButtonBitmap(3,IDB_MINUS); + else + SetButtonBitmap(3,IDB_PLUS); + } else { + SetButtonBitmap(3,IDB_CHAT); + } + } + else + { + SetButtonBitmap(3,IDB_CHAT); + } +} \ No newline at end of file diff --git a/plugins/MirandaG15/src/CContactlistScreen.h b/plugins/MirandaG15/src/CContactlistScreen.h new file mode 100644 index 0000000000..3b9a5f6f95 --- /dev/null +++ b/plugins/MirandaG15/src/CContactlistScreen.h @@ -0,0 +1,62 @@ +#ifndef _CCONTACTLISTSCREEN_H_ +#define _CCONTACTLISTSCREEN_H_ + +#include "CScreen.h" +#include "CContactList.h" +#include "CLCDBar.h" + +class CContactlistScreen : public CScreen +{ +public: + // Constructor + CContactlistScreen(); + // Destructor + ~CContactlistScreen(); + + // Initializes the screen + bool Initialize(); + // Shutdown the scren + bool Shutdown(); + // Updates the screen + bool Update(); + // Draws the screen + bool Draw(CLCDGfx *pGfx); + + // resets the position of the contactlist + void ResetPosition(); + + // returns the online status of the specified contact + int GetContactStatus(HANDLE hContact); + + // Called when a chat session was opened + void OnSessionOpened(HANDLE hContact); + + // Called when the configuration has changed + void OnConfigChanged(); + // Called when the screen size has changed + void OnSizeChanged(); + // Called when an event is received + void OnEventReceived(CEvent *pEvent); + // Called when an LCD-button is pressed + void OnLCDButtonDown(int iButton); + // Called when an LCD-button event is repeated + void OnLCDButtonRepeated(int iButton); + // Called when an LCD-button is released + void OnLCDButtonUp(int iButton); + // Called when the screen is activated + void OnActivation(); + // Called when the screen is deactivated + void OnDeactivation(); + // Called when the screen has expired + void OnExpiration(); + +private: + // updates the use softkey label + void UpdateUseSoftkeyLabel(); + + CContactList m_ContactList; + CLCDBar m_Scrollbar; + bool m_bLongPress; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/CCreditsScreen.cpp b/plugins/MirandaG15/src/CCreditsScreen.cpp new file mode 100644 index 0000000000..5c3cd9669b --- /dev/null +++ b/plugins/MirandaG15/src/CCreditsScreen.cpp @@ -0,0 +1,266 @@ +#include "stdafx.h" +#include "CCreditsScreen.h" +#include "CAppletManager.h" + +//************************************************************************ +// Constructor +//************************************************************************ +CCreditsScreen::CCreditsScreen() +{ +} + +//************************************************************************ +// Destructor +//************************************************************************ +CCreditsScreen::~CCreditsScreen() +{ +} + +//************************************************************************ +// Initializes the screen +//************************************************************************ +bool CCreditsScreen::Initialize() +{ + if(!CScreen::Initialize()) + return false; + + m_Label.Initialize(); + + m_Label.SetAlignment(DT_CENTER); + m_Label.SetWordWrap(TRUE); + m_Label.SetText(_T("")); + m_Label.SetFontFaceName(_T("Microsoft Sans Serif")); + m_Label.SetFontPointSize(10); + m_Label.SetFontWeight(FW_BOLD); + + m_Label2.Initialize(); + + AddObject(&m_Label); + AddObject(&m_Label2); + return true; +} + +//************************************************************************ +// Shutdown the scren +//************************************************************************ +bool CCreditsScreen::Shutdown() +{ + if(!CScreen::Shutdown()) + return false; + + return true; +} + +//************************************************************************ +// Updates the screen +//************************************************************************ +bool CCreditsScreen::Update() +{ + if(!CScreen::Update()) + return false; + + DWORD dwTimeElapsed = GetTickCount() - m_dwActivation; + int iOldPosition = m_iPosition; + + if(dwTimeElapsed > m_dwDuration) + { + m_dwDuration = 4000; + m_Label.SetText(_T("")); + m_Label2.SetText(_T("")); + switch(m_iPosition) + { + case 0: + m_Label.SetText(_T("MirandaG15")); + m_Label2.SetText(_T("2008 by Martin Kleinhans")); + m_dwDuration = 2500; + break; + case 1: + m_Label.SetSize(GetWidth(),GetHeight()); + m_Label.SetText(_T("Special thanks to:")); + m_dwDuration = 2000; + break; + case 2: + m_Label.SetSize(GetWidth(),25); + m_Label.SetText(_T("Shere Khan\n")); + m_Label2.SetText(_T("Concept, Ideas, Testing")); + m_dwDuration = 2500; + break; + case 3: + m_Label.SetSize(GetWidth(),25); + m_Label.SetText(_T("Tauu and Cloonix\n")); + m_Label2.SetText(_T("Ideas, Testing")); + m_dwDuration = 2500; + break; + case 4: + m_Label.SetSize(GetWidth(),GetHeight()); + m_Label.SetFontPointSize(10); + m_Label.SetFontWeight(FW_BOLD); + m_Label.SetText(_T("Betatesters:")); + m_dwDuration = 2000; + break; + case 5: + m_Label.SetSize(GetWidth(),25); + m_Label2.SetFontPointSize(10); + m_Label2.SetFontWeight(FW_BOLD); + m_Label.SetText(_T("Cyberz")); + m_Label2.SetText(_T("Cimlite")); + m_dwDuration = 2000; + break; + case 6: + m_Label.SetText(_T("Vullcan")); + m_Label2.SetText(_T("Snake")); + m_dwDuration = 2000; + break; + case 7: + m_Label.SetText(_T("Wiebbe")); + m_Label2.SetText(_T("Maluku")); + m_dwDuration = 2000; + break; + case 8: + m_Label.SetText(_T("lastwebpage")); + m_dwDuration = 2000; + break; + case 9: + m_Label.SetSize(GetWidth(),GetHeight()); + m_Label.SetText(_T("Additional thanks to:")); + m_dwDuration = 2000; + break; + case 10: + m_Label.SetSize(GetWidth(),25); + m_Label2.SetFontPointSize(8); + m_Label2.SetFontWeight(FW_NORMAL); + m_Label.SetText(_T("Everyone")); + m_Label2.SetText(_T("on G15Forums.com")); + m_dwDuration = 2000; + break; + case 11: + m_Label.SetText(_T("Everyone else")); + m_Label2.SetText(_T("for feedback and suggestions")); + m_dwDuration = 2000; + break; + case 12: + m_Label.SetFontPointSize(10); + m_Label.SetFontWeight(FW_BOLD); + m_Label.SetSize(GetWidth(),25); + m_Label.SetText(_T("Logitech")); + m_Label2.SetText(_T("for obvious reasons")); + m_dwDuration = 2000; + break; + case 13: + m_Label.SetSize(GetWidth(),10); + m_Label.SetText(_T("You can contact me at:")); + m_Label2.SetSize(GetWidth(),33); + m_Label2.SetOrigin(0,10); + m_Label2.SetFontPointSize(8); + m_Label2.SetText(_T("mail@mkleinhans.de\nwww.mkleinhans.de")); + m_dwDuration = 2500; + break; + default: + CAppletManager::GetInstance()->ActivateEventScreen(); + return true; + } + m_iPosition++; + CAppletManager::GetInstance()->StartTransition(TRANSITION_MORPH); + } + + if(m_iPosition != iOldPosition) + m_dwActivation = GetTickCount(); + return true; +} + +//************************************************************************ +// Resets the credits screens state +//************************************************************************ +void CCreditsScreen::Reset() +{ + m_dwActivation = GetTickCount(); + m_dwDuration = 0; + + m_iPosition = 0; + + CAppletManager::GetInstance()->GetLCDConnection()->SetAsForeground(true); + + m_Label2.SetAlignment(DT_CENTER); + m_Label2.SetWordWrap(TRUE); + m_Label2.SetText(_T("")); + m_Label2.SetFontFaceName(_T("Microsoft Sans Serif")); + m_Label2.SetFontPointSize(8); + + m_Label.SetOrigin(0,0); + m_Label.SetSize(GetWidth(),20); + + m_Label2.SetOrigin(0,23); + m_Label2.SetSize(GetWidth(),20); +} + + +//************************************************************************ +// Draws the screen +//************************************************************************ +bool CCreditsScreen::Draw(CLCDGfx *pGfx) +{ + if(!CScreen::Draw(pGfx)) + return false; + + return true; +} + +//************************************************************************ +// Called when the configuration has changed +//************************************************************************ +void CCreditsScreen::OnConfigChanged() +{ + CLCDScreen::OnSizeChanged(); + CScreen::OnConfigChanged(); +} + +//************************************************************************ +// Called when the screen size has changed +//************************************************************************ +void CCreditsScreen::OnSizeChanged() +{ + CScreen::OnSizeChanged(); +} + +//************************************************************************ +// Called when an LCD-button is pressed +//************************************************************************ +void CCreditsScreen::OnLCDButtonDown(int iButton) +{ +} + +//************************************************************************ +// Called when an LCD-button event is repeated +//************************************************************************ +void CCreditsScreen::OnLCDButtonRepeated(int iButton) +{ +} + +//************************************************************************ +// Called when an LCD-button is released +//************************************************************************ +void CCreditsScreen::OnLCDButtonUp(int iButton) +{ +} + +//************************************************************************ +// Called when the screen is activated +//************************************************************************ +void CCreditsScreen::OnActivation() +{ +} + +//************************************************************************ +// Called when the screen is deactivated +//************************************************************************ +void CCreditsScreen::OnDeactivation() +{ + CAppletManager::GetInstance()->GetLCDConnection()->SetAsForeground(false); +} + +//************************************************************************ +// Called when the screen has expired +//************************************************************************ +void CCreditsScreen::OnExpiration() +{ +} diff --git a/plugins/MirandaG15/src/CCreditsScreen.h b/plugins/MirandaG15/src/CCreditsScreen.h new file mode 100644 index 0000000000..3873fc2c79 --- /dev/null +++ b/plugins/MirandaG15/src/CCreditsScreen.h @@ -0,0 +1,53 @@ +#ifndef _CCREDITSSCREEN_H_ +#define _CCREDITSSCREEN_H_ + +#include "CScreen.h" +#include "CLCDLabel.h" + +class CCreditsScreen : public CScreen +{ +public: + // Constructor + CCreditsScreen(); + // Destructor + ~CCreditsScreen(); + + // Initializes the screen + bool Initialize(); + // Shutdown the scren + bool Shutdown(); + // Updates the screen + bool Update(); + // Draws the screen + bool Draw(CLCDGfx *pGfx); + + // Called when the configuration has changed + void OnConfigChanged(); + // Called when the screen size has changed + void OnSizeChanged(); + // Called when an LCD-button is pressed + void OnLCDButtonDown(int iButton); + // Called when an LCD-button event is repeated + void OnLCDButtonRepeated(int iButton); + // Called when an LCD-button is released + void OnLCDButtonUp(int iButton); + // Called when the screen is activated + void OnActivation(); + // Called when the screen is deactivated + void OnDeactivation(); + // Called when the screen has expired + void OnExpiration(); + + // Resets the credits screens state + void Reset(); +private: + + CLCDLabel m_Label; + CLCDLabel m_Label2; + + DWORD m_dwActivation; + DWORD m_dwDuration; + int m_iPosition; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/CEvent.h b/plugins/MirandaG15/src/CEvent.h new file mode 100644 index 0000000000..cf23af037e --- /dev/null +++ b/plugins/MirandaG15/src/CEvent.h @@ -0,0 +1,71 @@ +#ifndef _CEVENT_H_ +#define _CEVENT_H_ + +enum EventType { EVENT_MSG_RECEIVED = 0, + EVENT_MSG_SENT = 3, + EVENT_MESSAGE_ACK = 4, + EVENT_STATUS = 1, + EVENT_MSG_ACK = 2, + + EVENT_URL = 5, + EVENT_FILE = 6, + EVENT_AUTHREQUEST = 7, + EVENT_CONTACTS = 8, + EVENT_ADDED = 9, + + EVENT_CONTACT_ADDED = 10, + EVENT_CONTACT_DELETED = 11, + EVENT_CONTACT_NICK = 12, + EVENT_CONTACT_HIDDEN = 13, + EVENT_CONTACT_GROUP = 14, + + EVENT_SIGNED_ON = 15, + EVENT_SIGNED_OFF = 16, + + EVENT_PROTO_STATUS = 17, + EVENT_PROTO_CONNECTED = 18, + EVENT_PROTO_DISCONNECTED = 19, + + EVENT_TYPING_NOTIFICATION = 20, + EVENT_MESSAGEWINDOW = 21, + EVENT_IRC_SENT = 22, + EVENT_IRC_RECEIVED = 23}; + +#define MSG_READ 0 +#define MSG_UNREAD 1 + +class CEvent +{ +public: + CEvent() + { + bTime = false; + dwFlags = NULL; + hContact = NULL; + bNotification = false; + bLog = true; + strDescription = _T(""); + + iValue = NULL; + hValue = NULL; + strValue = _T(""); + } + + enum EventType eType; + DWORD dwFlags; + HANDLE hContact; + tm Time; + bool bTime; + + bool bNotification; + bool bLog; + + tstring strDescription; + tstring strSummary; + + HANDLE hValue; + int iValue; + tstring strValue; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/CEventLog.cpp b/plugins/MirandaG15/src/CEventLog.cpp new file mode 100644 index 0000000000..dd82d923f4 --- /dev/null +++ b/plugins/MirandaG15/src/CEventLog.cpp @@ -0,0 +1,120 @@ +#include "stdafx.h" +#include "CEventLog.h" +#include "CConfig.h" +#include "CAppletManager.h" + +//************************************************************************ +// constructor +//************************************************************************ +CEventLog::CEventLog() +{ + m_dwLastScroll = 0; +} + +//************************************************************************ +// destructor +//************************************************************************ +CEventLog::~CEventLog() +{ + +} + +//************************************************************************ +// deinitializes the list +//************************************************************************ +bool CEventLog::Shutdown() +{ + if(!CLCDList::Shutdown()) + return false; + + return true; +} + +//************************************************************************ +// initializes the list +//************************************************************************ +bool CEventLog::Initialize() +{ + if(!CLCDList::Initialize()) + return false; + + return true; +} + +//************************************************************************ +// Called to set the objects font +//************************************************************************ +bool CEventLog::SetFont(LOGFONT &lf) +{ + if(!CLCDList::SetFont(lf)) + return false; + + SetEntryHeight(m_iFontHeight<6?6:m_iFontHeight); + + return true; +} + +//************************************************************************ +// adds an entry to the list +//************************************************************************ +CListItem *CEventLog::AddItem(CEventLogEntry *pEntry) +{ + CListItem *pItem = CLCDList::AddItem(pEntry); + if(GetEntryCount() > CConfig::GetIntSetting(NOTIFY_LOGSIZE)) + RemoveItem(((CListItem*)GetFirstEntry())->GetItemData()); + + if(GetTickCount() - m_dwLastScroll > 10000) + SetPosition(pItem); + return pItem; +} + +//************************************************************************ +// Called to delete the specified entry +//************************************************************************ +void CEventLog::DeleteEntry(CEventLogEntry *pEntry) +{ + delete pEntry; +} + +//************************************************************************ +// Called to draw the specified entry +//************************************************************************ +void CEventLog::DrawEntry(CLCDGfx *pGfx,CEventLogEntry *pEntry,bool bSelected) +{ + SelectObject(pGfx->GetHDC(),m_hFont); + + bool bLargeIcons = GetEntryHeight() > 8; + int iOffset = (m_iFontHeight-(bLargeIcons?8:6))/2; + HBITMAP hBitmap = CAppletManager::GetInstance()->GetEventBitmap(pEntry->eType,bLargeIcons); + pGfx->DrawBitmap(0,iOffset<0?0:iOffset,bLargeIcons?8:6,bLargeIcons?8:6,hBitmap); + + iOffset = bLargeIcons?10:7; + if(CConfig::GetBoolSetting(NOTIFY_TIMESTAMPS)) + pGfx->DrawText(iOffset,0,pGfx->GetClipWidth()-iOffset,pEntry->strTimestamp + pEntry->strValue); + else + pGfx->DrawText(iOffset,0,pGfx->GetClipWidth()-iOffset,pEntry->strValue); + + if(bSelected && GetTickCount() - m_dwLastScroll < 1000) + { + RECT invert = { 0,0,GetWidth(),m_iFontHeight}; + InvertRect(pGfx->GetHDC(),&invert); + } +} + + +void CEventLog::SetPosition(CListEntry *pEntry) +{ + CLCDList::SetPosition(pEntry); +} + +bool CEventLog::ScrollUp() +{ + m_dwLastScroll = GetTickCount(); + return CLCDList::ScrollUp(); +} + +bool CEventLog::ScrollDown() +{ + m_dwLastScroll = GetTickCount(); + return CLCDList::ScrollDown(); +} diff --git a/plugins/MirandaG15/src/CEventLog.h b/plugins/MirandaG15/src/CEventLog.h new file mode 100644 index 0000000000..e5953f92c7 --- /dev/null +++ b/plugins/MirandaG15/src/CEventLog.h @@ -0,0 +1,46 @@ +#ifndef _CEVENTLOG_H_ +#define _CEVENTLOG_H_ + +#include "CLCDList.h" + +class CEventLogEntry +{ +public: + HANDLE hContact; + tstring strValue; + tstring strTimestamp; + tm Time; + EventType eType; +}; + +class CEventLog : public CLCDList +{ +public: + // constructor + CEventLog(); + // destructor + ~CEventLog(); + + // initializes the list + bool Initialize(); + // deinitializes the list + bool Shutdown(); + // adds an entry to the list + CListItem *AddItem(CEventLogEntry *); + + void SetPosition(CListEntry *pEntry); + bool ScrollUp(); + bool ScrollDown(); + + bool SetFont(LOGFONT &lf); + +protected: + // Called to delete the specified entry + void DeleteEntry(CEventLogEntry *pEntry); + // Called to draw the specified entry + void DrawEntry(CLCDGfx *pGfx,CEventLogEntry *pEntry,bool bSelected); + + DWORD m_dwLastScroll; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/CEventScreen.cpp b/plugins/MirandaG15/src/CEventScreen.cpp new file mode 100644 index 0000000000..cda38b07b4 --- /dev/null +++ b/plugins/MirandaG15/src/CEventScreen.cpp @@ -0,0 +1,239 @@ +#include "stdafx.h" +#include "CEventScreen.h" +#include "CConfig.h" +#include "CAppletManager.h" + +//************************************************************************ +// Constructor +//************************************************************************ +CEventScreen::CEventScreen() +{ +} + +//************************************************************************ +// Destructor +//************************************************************************ +CEventScreen::~CEventScreen() +{ +} + +//************************************************************************ +// Initializes the screen +//************************************************************************ +bool CEventScreen::Initialize() +{ + if(!CScreen::Initialize()) + return false; + + m_EventLog.Initialize(); + m_EventLog.SetOrigin(0,0); + m_EventLog.SetSize(GetWidth()-5,GetHeight()-(CConfig::GetBoolSetting(SHOW_LABELS)?6:0)); + m_EventLog.SetFont(CConfig::GetFont(FONT_LOG)); + + AddObject(&m_EventLog); + + m_Scrollbar.Initialize(); + m_Scrollbar.SetOrigin(GetWidth()-4,0); + m_Scrollbar.SetSize(4,GetHeight()-(CConfig::GetBoolSetting(SHOW_LABELS)?5:0)); + m_EventLog.SetScrollbar(&m_Scrollbar); + + AddObject(&m_Scrollbar); + + SetButtonBitmap(0,IDB_UP); + SetButtonBitmap(1,IDB_DOWN); + SetButtonBitmap(2,IDB_CLIST); + SetButtonBitmap(3,NULL); + + return true; +} + +//************************************************************************ +// Shutdown the screen +//************************************************************************ +bool CEventScreen::Shutdown() +{ + if(!CScreen::Shutdown()) + return false; + + return true; +} + +//************************************************************************ +// Updates the screen +//************************************************************************ +bool CEventScreen::Update() +{ + if(!CScreen::Update()) + return false; + + return true; +} + +//************************************************************************ +// Draws the screen +//************************************************************************ +bool CEventScreen::Draw(CLCDGfx *pGfx) +{ + if(!CScreen::Draw(pGfx)) + return false; + + return true; +} + +//************************************************************************ +// Called when the screen size has changed +//************************************************************************ +void CEventScreen::OnSizeChanged() +{ + CScreen::OnSizeChanged(); + + m_EventLog.SetFont(CConfig::GetFont(FONT_LOG)); + m_EventLog.SetSize(GetWidth()-5,GetHeight()-(CConfig::GetBoolSetting(SHOW_LABELS)?6:0)); + + m_Scrollbar.SetOrigin(GetWidth()-4,0); + + m_Scrollbar.SetSize(4,GetHeight()-(CConfig::GetBoolSetting(SHOW_LABELS)?5:0)); +} + +//************************************************************************ +// Called when the configuration has changed +//************************************************************************ +void CEventScreen::OnConfigChanged() +{ + CScreen::OnConfigChanged(); + + m_EventLog.SetFont(CConfig::GetFont(FONT_LOG)); + m_EventLog.SetSize(GetWidth()-5,GetHeight()-(CConfig::GetBoolSetting(SHOW_LABELS)?6:0)); + + // Update all timestamps + list*>::iterator iter = m_EventLog.begin(); + CListItem *pItem = NULL; + while(iter != m_EventLog.end()) + { + pItem = static_cast*>(*iter); + pItem->GetItemData()->strTimestamp = CAppletManager::GetFormattedTimestamp(&pItem->GetItemData()->Time) + _T(" "); + iter++; + } + + m_Scrollbar.SetSize(4,GetHeight()-(CConfig::GetBoolSetting(SHOW_LABELS)?5:0)); +} + +//************************************************************************ +// Called when an event is received +//************************************************************************ +void CEventScreen::OnEventReceived(CEvent *pEvent) +{ + // check if the event needs to be listed + if(!pEvent->bLog) + return; + + // create a list entry structure + CEventLogEntry *pEntry = new CEventLogEntry(); + pEntry->hContact = pEvent->hContact; + pEntry->eType = pEvent->eType; + + pEntry->Time = pEvent->Time; + pEntry->strTimestamp = CAppletManager::GetFormattedTimestamp(&pEvent->Time) + _T(" "); + pEntry->strValue = pEvent->strDescription; + + // add it to the list and scroll to it + m_EventLog.AddItem(pEntry); + + UpdateChatButton(); +} + +//************************************************************************ +// Updates the 4th softkey label +//************************************************************************ +void CEventScreen::UpdateChatButton() +{ + CListEntry *pItem = m_EventLog.GetSelectedEntry(); + if(!pItem || pItem->GetType() != ITEM) + return; + CEventLogEntry *pEntry = ((CListItem*)pItem)->GetItemData(); + if(pEntry->hContact) + SetButtonBitmap(3,IDB_CHAT); + else + SetButtonBitmap(3,NULL); +} + +//************************************************************************ +// Called when an LCD-button is pressed +//************************************************************************ +void CEventScreen::OnLCDButtonDown(int iButton) +{ + if(iButton == LGLCDBUTTON_CANCEL) { + CAppletManager::GetInstance()->ActivatePreviousScreen(); + } else if(iButton == LGLCDBUTTON_BUTTON1 || iButton == LGLCDBUTTON_DOWN) { + m_EventLog.ScrollDown(); + UpdateChatButton(); + } else if(iButton == LGLCDBUTTON_BUTTON0 || iButton == LGLCDBUTTON_UP) { + m_EventLog.ScrollUp(); + UpdateChatButton(); + } else if(iButton == LGLCDBUTTON_BUTTON2 || iButton == LGLCDBUTTON_MENU) { + CAppletManager::GetInstance()->ActivateCListScreen(); + } else if(iButton == LGLCDBUTTON_BUTTON3 || iButton == LGLCDBUTTON_OK) + { + CListEntry *pItem = m_EventLog.GetSelectedEntry(); + if(!pItem || pItem->GetType() != ITEM) + return; + CEventLogEntry *pEntry = ((CListItem*)pItem)->GetItemData(); + + if(!pEntry->hContact) + return; + + // if the contact is an irc chatroom, check if it is hidden (user left the channel) + char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)pEntry->hContact, 0); + CIRCConnection *pIRCCon = CAppletManager::GetInstance()->GetIRCConnection(toTstring(szProto)); + + if(pIRCCon && db_get_b(pEntry->hContact, szProto, "ChatRoom", 0) != 0 && + db_get_b((HANDLE)pEntry->hContact,"CList","Hidden",0)) + return; + + CAppletManager::GetInstance()->ActivateChatScreen(pEntry->hContact); + } +} + +//************************************************************************ +// Called when an LCD-button event is repeated +//************************************************************************ +void CEventScreen::OnLCDButtonRepeated(int iButton) +{ + if(iButton == LGLCDBUTTON_BUTTON1 || iButton == LGLCDBUTTON_DOWN) { + m_EventLog.ScrollDown(); + UpdateChatButton(); + } else if(iButton == LGLCDBUTTON_BUTTON0 || iButton == LGLCDBUTTON_UP) { + m_EventLog.ScrollUp(); + UpdateChatButton(); + } +} + +//************************************************************************ +// Called when an LCD-button is released +//************************************************************************ +void CEventScreen::OnLCDButtonUp(int iButton) +{ + +} + +//************************************************************************ +// Called when the screen is activated +//************************************************************************ +void CEventScreen::OnActivation() +{ + +} + +//************************************************************************ +// Called when the screen is deactivated +//************************************************************************ +void CEventScreen::OnDeactivation() +{ +} + +//************************************************************************ +// Called when the screen has expired +//************************************************************************ +void CEventScreen::OnExpiration() +{ +} \ No newline at end of file diff --git a/plugins/MirandaG15/src/CEventScreen.h b/plugins/MirandaG15/src/CEventScreen.h new file mode 100644 index 0000000000..e2eeccc24c --- /dev/null +++ b/plugins/MirandaG15/src/CEventScreen.h @@ -0,0 +1,51 @@ +#ifndef _CEVENTSCREEN_H_ +#define _CEVENTSCREEN_H_ + +#include "CScreen.h" +#include "CEventLog.h" +#include "CLCDBar.h" + +class CEventScreen : public CScreen +{ +public: + // Constructor + CEventScreen(); + // Destructor + ~CEventScreen(); + + // Initializes the screen + bool Initialize(); + // Shutdown the scren + bool Shutdown(); + // Updates the screen + bool Update(); + // Draws the screen + bool Draw(CLCDGfx *pGfx); + + // Called when the configuration has changed + void OnConfigChanged(); + // Called when the screen size has changed + void OnSizeChanged(); + // Called when an event is received + void OnEventReceived(CEvent *pEvent); + // Called when an LCD-button is pressed + void OnLCDButtonDown(int iButton); + // Called when an LCD-button event is repeated + void OnLCDButtonRepeated(int iButton); + // Called when an LCD-button is released + void OnLCDButtonUp(int iButton); + // Called when the screen is activated + void OnActivation(); + // Called when the screen is deactivated + void OnDeactivation(); + // Called when the screen has expired + void OnExpiration(); + +private: + void UpdateChatButton(); + + CEventLog m_EventLog; + CLCDBar m_Scrollbar; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/CIRCConnection.h b/plugins/MirandaG15/src/CIRCConnection.h new file mode 100644 index 0000000000..4067941cea --- /dev/null +++ b/plugins/MirandaG15/src/CIRCConnection.h @@ -0,0 +1,12 @@ +#ifndef _CIRCCONNECTION_H_ +#define _CIRCCONNECTION_H_ + +class CIRCConnection +{ +public: + HANDLE hEventHook; + tstring strProtocol; + tstring strNetwork; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/CIRCHistory.h b/plugins/MirandaG15/src/CIRCHistory.h new file mode 100644 index 0000000000..299a80544b --- /dev/null +++ b/plugins/MirandaG15/src/CIRCHistory.h @@ -0,0 +1,23 @@ +#ifndef _CIRCHISTORY_H_ +#define _CIRCHISTORY_H_ + +struct SIRCMessage +{ + tm Time; + bool bIsMe; + tstring strMessage; +}; + + +class CIRCHistory +{ +public: + tstring strChannel; + tstring strProtocol; + HANDLE hContact; + list LMessages; + list LUsers; +}; + + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/CNotificationScreen.cpp b/plugins/MirandaG15/src/CNotificationScreen.cpp new file mode 100644 index 0000000000..d950eccac8 --- /dev/null +++ b/plugins/MirandaG15/src/CNotificationScreen.cpp @@ -0,0 +1,374 @@ +#include "stdafx.h" +#include "CNotificationScreen.h" +#include "CConfig.h" +#include "CAppletManager.h" + +//************************************************************************ +// Constructor +//************************************************************************ +CNotificationScreen::CNotificationScreen() +{ + m_pEntry = NULL; + //m_bMessageMode = false; +} + +//************************************************************************ +// Destructor +//************************************************************************ +CNotificationScreen::~CNotificationScreen() +{ +} + +//************************************************************************ +// Initializes the screen +//************************************************************************ +bool CNotificationScreen::Initialize() +{ + if(!CScreen::Initialize()) + return false; + + m_EventText.Initialize(); + m_MessageText.Initialize(); + m_TitleText.Initialize(); + m_Scrollbar.Initialize(); + m_Timestamp.Initialize(); + //m_Input.Initialize(); + //m_Input.Show(0); + + m_TitleText.SetText(_T("Miranda-IM")); + m_TitleText.SetAlignment(DT_LEFT); + + m_Timestamp.SetAlignment(DT_RIGHT); + + m_EventText.SetAlignment(DT_CENTER); + m_EventText.SetWordWrap(TRUE); + + m_MessageText.SetScrollbar(&m_Scrollbar); + + UpdateObjects(); + + AddObject(&m_Scrollbar); + AddObject(&m_EventText); + AddObject(&m_MessageText); + AddObject(&m_TitleText); + AddObject(&m_Timestamp); + //AddObject(&m_Input); + + SetButtonBitmap(0,IDB_UP); + SetButtonBitmap(1,IDB_DOWN); + + return true; +} + +//************************************************************************ +// Shutdown the screen +//************************************************************************ +bool CNotificationScreen::Shutdown() +{ + CNotificationEntry *pEntry = NULL; + while(!m_LNotifications.empty()) + { + pEntry = *(m_LNotifications.begin()); + m_LNotifications.pop_front(); + delete pEntry; + } + + if(!CScreen::Shutdown()) + return false; + + return true; +} + +//************************************************************************ +// Updates the screen +//************************************************************************ +bool CNotificationScreen::Update() +{ + if(!CScreen::Update()) + return false; + + return true; +} + +//************************************************************************ +// Draws the screen +//************************************************************************ +bool CNotificationScreen::Draw(CLCDGfx *pGfx) +{ + if(!CScreen::Draw(pGfx)) + return false; + + if(CConfig::GetIntSetting(NOTIFY_TITLE) != NOTIFY_TITLE_HIDE) + { + int iTitleHeight = CConfig::GetFontHeight(FONT_TITLE); + pGfx->DrawLine(0,iTitleHeight < 7?7:iTitleHeight,GetWidth(),iTitleHeight < 7?7:iTitleHeight); + if(m_pEntry) + { + int iOffset = (iTitleHeight-(iTitleHeight>8?8:6))/2; + HBITMAP hBitmap = CAppletManager::GetInstance()->GetEventBitmap(m_pEntry->eType,iTitleHeight>8); + pGfx->DrawBitmap(0,iOffset,iTitleHeight>8?8:6,iTitleHeight>8?8:6,hBitmap); + } + } + return true; +} + +//************************************************************************ +// displays the specified notification +//************************************************************************ +void CNotificationScreen::DisplayNotification(CNotificationEntry *pEntry) +{ + if(m_pEntry != NULL) + delete m_pEntry; + + + tstring strTime = CAppletManager::GetFormattedTimestamp(&pEntry->Time); + + m_pEntry = pEntry; + if(CConfig::GetIntSetting(NOTIFY_TITLE) == NOTIFY_TITLE_NAME || pEntry->strTitle.empty()) + m_TitleText.SetText(_T("Miranda-IM")); + else + m_TitleText.SetText(pEntry->strTitle); + + if(CConfig::GetBoolSetting(NOTIFY_TIMESTAMPS)) + m_Timestamp.SetText(strTime); + else + m_Timestamp.SetText(_T("")); + + + if(pEntry->hContact) + SetButtonBitmap(3,IDB_CHAT); + else + SetButtonBitmap(3,NULL); + + if(pEntry->bMessage) + { + SetButtonBitmap(0,IDB_UP); + SetButtonBitmap(1,IDB_DOWN); + + m_MessageText.Show(1); + m_Scrollbar.Show(1); + m_EventText.Show(0); + m_MessageText.SetText(pEntry->strText.c_str()); + } + else + { + SetButtonBitmap(0,NULL); + SetButtonBitmap(1,NULL); + + m_Scrollbar.Show(0); + m_MessageText.Show(0); + m_EventText.Show(1); + m_EventText.SetText(pEntry->strText.c_str()); + } +} + +//************************************************************************ +// updates all objects +//************************************************************************ +void CNotificationScreen::UpdateObjects() +{ + int iHeight = GetHeight() - (CConfig::GetBoolSetting(SHOW_LABELS)?6:0); + int iOrigin = 0; + + if(CConfig::GetIntSetting(NOTIFY_TITLE) == NOTIFY_TITLE_HIDE) + { + m_TitleText.Show(false); + m_Timestamp.Show(false); + } + else + { + iOrigin = CConfig::GetFontHeight(FONT_TITLE); + iHeight -= iOrigin; + m_Timestamp.Show(true); + m_TitleText.Show(true); + } + + + m_MessageText.SetFont(CConfig::GetFont(FONT_NOTIFICATION)); + m_TitleText.SetFont(CConfig::GetFont(FONT_TITLE)); + m_EventText.SetFont(CConfig::GetFont(FONT_NOTIFICATION)); + m_Timestamp.SetFont(CConfig::GetFont(FONT_TITLE)); + + m_Timestamp.SetSize((GetWidth()/3),CConfig::GetFontHeight(FONT_TITLE)); + m_Timestamp.SetOrigin((GetWidth()/3)*2,0); + + m_TitleText.SetSize(((GetWidth()/3)*2) -5,CConfig::GetFontHeight(FONT_TITLE)); + m_TitleText.SetOrigin(9,0); + + m_EventText.SetOrigin(0,iOrigin + 1); + m_EventText.SetSize(GetWidth()-4, iHeight); + + m_MessageText.SetOrigin(0, iOrigin+1); + m_MessageText.SetSize(GetWidth()-4, iHeight); + + //m_Input.SetOrigin(0, iOrigin+1); + //m_Input.SetSize(GetWidth()-4, iHeight); + + m_Scrollbar.SetOrigin(GetWidth()-4,iOrigin+1); + m_Scrollbar.SetSize(4,iHeight); +} + +//************************************************************************ +// Called when the screen size has changed +//************************************************************************ +void CNotificationScreen::OnSizeChanged() +{ + CScreen::OnSizeChanged(); + + UpdateObjects(); +} + +//************************************************************************ +// Called when the configuration has changed +//************************************************************************ +void CNotificationScreen::OnConfigChanged() +{ + CScreen::OnConfigChanged(); + + UpdateObjects(); +} + +//************************************************************************ +// Called when an event is received +//************************************************************************ +void CNotificationScreen::OnEventReceived(CEvent *pEvent) +{ + // check wether this events needs notification + if(!pEvent->bNotification) + return; + + CNotificationEntry *pEntry = new CNotificationEntry(); + pEntry->eType = pEvent->eType; + pEntry->strTitle = pEvent->strSummary; + if(pEvent->eType == EVENT_MSG_RECEIVED || + (pEvent->eType == EVENT_IRC_RECEIVED && (pEvent->iValue == GC_EVENT_MESSAGE || pEvent->iValue == GC_EVENT_NOTICE))) + { + pEntry->bMessage = true; + tstring strUser = CAppletManager::GetContactDisplayname(pEvent->hContact); + + if(CConfig::GetIntSetting(NOTIFY_TITLE) == NOTIFY_TITLE_INFO) + pEntry->strText = pEvent->strValue; + else + pEntry->strText = strUser + (pEvent->eType == EVENT_IRC_RECEIVED?_T(" - "):_T(": "))+ pEvent->strValue; + } + else + { + pEntry->bMessage = false; + if(CConfig::GetIntSetting(NOTIFY_TITLE) == NOTIFY_TITLE_INFO && pEvent->eType == EVENT_IRC_RECEIVED ) + pEntry->strText = pEvent->strValue; + else + pEntry->strText = pEvent->strDescription; + } + + pEntry->hContact = pEvent->hContact; + pEntry->Time = pEvent->Time; + + if(m_pEntry) + { + m_LNotifications.push_back(pEntry); + SetButtonBitmap(2,IDB_NEXT); + } + else + { + DisplayNotification(pEntry); + SetButtonBitmap(2,NULL); + } +} +//************************************************************************ +// Called when an LCD-button is pressed +//************************************************************************ +void CNotificationScreen::OnLCDButtonDown(int iButton) +{ + CScreen::OnLCDButtonDown(iButton); + + if((iButton == LGLCDBUTTON_BUTTON2 || iButton == LGLCDBUTTON_RIGHT) && m_LNotifications.size() >= 1) + { + CNotificationEntry *pEntry = *(m_LNotifications.begin()); + m_LNotifications.pop_front(); + + if(m_LNotifications.size() >= 1) + SetButtonBitmap(2,IDB_NEXT); + else + SetButtonBitmap(2,NULL); + + DisplayNotification(pEntry); + SetExpiration(CConfig::GetIntSetting(NOTIFY_DURATION)*1000); + } + else if((iButton == LGLCDBUTTON_BUTTON3 || iButton == LGLCDBUTTON_OK) && m_pEntry && m_pEntry->hContact) + { + SetExpiration(0); + + CLCDConnection *pLCDCon = CAppletManager::GetInstance()->GetLCDConnection(); + pLCDCon->SetAsForeground(1); + pLCDCon->SetAsForeground(0); + CAppletManager::GetInstance()->ActivateChatScreen(m_pEntry->hContact); + } else if(!m_MessageText.IsVisible()) { + SetExpiration(0); + } else { + if(iButton == LGLCDBUTTON_BUTTON1 || iButton == LGLCDBUTTON_DOWN) { + m_MessageText.ScrollDown(); + } else if(iButton == LGLCDBUTTON_BUTTON0 || iButton == LGLCDBUTTON_UP) { + m_MessageText.ScrollUp(); + } + SetExpiration(CConfig::GetIntSetting(NOTIFY_DURATION)*1000); + } +} + +//************************************************************************ +// Called when an LCD-button event is repeated +//************************************************************************ +void CNotificationScreen::OnLCDButtonRepeated(int iButton) +{ + CScreen::OnLCDButtonDown(iButton); + if(m_MessageText.IsVisible()) { + if(iButton == LGLCDBUTTON_BUTTON1 || iButton == LGLCDBUTTON_DOWN) { + m_MessageText.ScrollDown(); + } else if(iButton == LGLCDBUTTON_BUTTON0 || iButton == LGLCDBUTTON_UP) { + m_MessageText.ScrollUp(); + } + SetExpiration(CConfig::GetIntSetting(NOTIFY_DURATION)*1000); + } +} + +//************************************************************************ +// Called when an LCD-button is released +//************************************************************************ +void CNotificationScreen::OnLCDButtonUp(int iButton) +{ + +} + +//************************************************************************ +// Called when the screen is activated +//************************************************************************ +void CNotificationScreen::OnActivation() +{ + +} + +//************************************************************************ +// Called when the screen is deactivated +//************************************************************************ +void CNotificationScreen::OnDeactivation() +{ +} + +//************************************************************************ +// Called when the screen has expired +//************************************************************************ +void CNotificationScreen::OnExpiration() +{ + // clear the cached events + CNotificationEntry *pEntry = NULL; + while(!m_LNotifications.empty()) + { + pEntry = *(m_LNotifications.begin()); + m_LNotifications.pop_front(); + delete pEntry; + } + // reset the object's content + m_EventText.SetText(_T("")); + m_MessageText.SetText(_T("")); + + m_pEntry = NULL; +} \ No newline at end of file diff --git a/plugins/MirandaG15/src/CNotificationScreen.h b/plugins/MirandaG15/src/CNotificationScreen.h new file mode 100644 index 0000000000..837398238a --- /dev/null +++ b/plugins/MirandaG15/src/CNotificationScreen.h @@ -0,0 +1,95 @@ +#ifndef _CNOTIFICATIONSCREEN_H_ +#define _CNOTIFICATIONSCREEN_H_ + +#include "CScreen.h" +#include "CLCDLabel.h" +#include "CLCDTextLog.h" +#include "CLCDBar.h" +#include "CLCDInput.h" + +class CNotificationEntry +{ +public: + bool bMessage; + tm Time; + tstring strText; + tstring strTitle; + HANDLE hContact; + EventType eType; +}; + +class CNotificationScreen : public CScreen +{ +public: + // Constructor + CNotificationScreen(); + // Destructor + ~CNotificationScreen(); + + // Initializes the screen + bool Initialize(); + // Shutdown the scren + bool Shutdown(); + // Updates the screen + bool Update(); + // Draws the screen + bool Draw(CLCDGfx *pGfx); + + // Called when the screen size has changed + void OnSizeChanged(); + // Called when the configuration has changed + void OnConfigChanged(); + // Called when an event is received + void OnEventReceived(CEvent *pEvent); + // Called when an LCD-button is pressed + void OnLCDButtonDown(int iButton); + // Called when an LCD-button event is repeated + void OnLCDButtonRepeated(int iButton); + // Called when an LCD-button is released + void OnLCDButtonUp(int iButton); + // Called when the screen is activated + void OnActivation(); + // Called when the screen is deactivated + void OnDeactivation(); + // Called when the screen has expired + void OnExpiration(); +private: + /* + // activates the input box + void ActivateMessageMode(); + // deactivates the input box + void DeactivateMessageMode(); + // sends the message + void SendCurrentMessage(); + // invalidates the message + void InvalidateMessageMode(tstring strMessage); + */ + + // displays the specified notification + void DisplayNotification(CNotificationEntry *pEntry); + // updates all objects + void UpdateObjects(); + + // cached notifications + list m_LNotifications; + + // objects + CLCDLabel m_EventText; + CLCDTextLog m_MessageText; + CLCDLabel m_TitleText; + CLCDLabel m_Timestamp; + CLCDBar m_Scrollbar; + //CLCDInput m_Input; + + // Contact off the current event + CNotificationEntry *m_pEntry; + + // message mode variables + /* + bool m_bMessageMode; + enum { REPLY_STATE_NONE,REPLY_STATE_INPUT,REPLY_STATE_SENDING,REPLY_STATE_FAILED} m_eReplyState; + HANDLE m_hMessage; + */ +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/CProtocolData.h b/plugins/MirandaG15/src/CProtocolData.h new file mode 100644 index 0000000000..cd2282377d --- /dev/null +++ b/plugins/MirandaG15/src/CProtocolData.h @@ -0,0 +1,13 @@ +#ifndef _CPROTOCLDATA_H_INCLUDED_ +#define _CPROTOCLDATA_H_INCLUDED_ + +class CProtocolData +{ +public: + tstring strProtocol; + int iStatus; + int iDesiredStatus; + long lTimeStamp; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/CScreen.cpp b/plugins/MirandaG15/src/CScreen.cpp new file mode 100644 index 0000000000..1759fa9686 --- /dev/null +++ b/plugins/MirandaG15/src/CScreen.cpp @@ -0,0 +1,180 @@ +#include "stdafx.h" +#include "CScreen.h" +#include "CConfig.h" + +//************************************************************************ +// Constructor +//************************************************************************ +CScreen::CScreen() +{ + m_bHideButtons = false; +} + +//************************************************************************ +// Destructor +//************************************************************************ +CScreen::~CScreen() +{ +} + +//************************************************************************ +// Initializes the screen +//************************************************************************ +bool CScreen::Initialize() +{ + if(!CLCDScreen::Initialize()) + return false; + + // initialize the four button labels + for (int i = 0; i < 4; i++) + { + m_aButtons[i].Initialize(); + m_aButtons[i].SetSize(17, 3); + m_aButtons[i].Show(0); + m_abShowButtons[i] = false; + m_ahBitmaps[i] = NULL; + if(GetWidth() == 160) { + m_aButtons[i].SetOrigin(10+i*29+(i/2)*36, GetHeight()-3); + } else { + m_aButtons[i].SetOrigin((280/4)*(i+0.5f) + (i/2)*40, GetHeight()-3); + } + AddObject(&m_aButtons[i]); + } + + /* + m_Clock.Initialize(); + + m_Clock.SetOrigin(68,0); + m_Clock.SetSize(40,2); + m_Clock.SetText(_T("23:00 - ")); + + m_Clock.SetFontFaceName(_T("Small Fonts"));//Digital Limit 3õ3 C")); + m_Clock.SetFontPointSize(10); + //m_Clock.SetFont(CConfig::GetFont(FONT_CLIST)); + + AddObject(&m_Clock); + */ + return true; +} + +//************************************************************************ +// Shutdown the scren +//************************************************************************ +bool CScreen::Shutdown() +{ + if(!CLCDScreen::Shutdown()) + return false; + + for(int i=0; i < 4; i++) + if(m_ahBitmaps[i] != NULL) + DeleteObject(m_ahBitmaps[i]); + + return true; +} + +//************************************************************************ +// Updates the screen +//************************************************************************ +bool CScreen::Update() +{ + if(!CLCDScreen::Update()) + return false; + + return true; +} + +//************************************************************************ +// Draws the screen +//************************************************************************ +bool CScreen::Draw(CLCDGfx *pGfx) +{ + if(!CLCDScreen::Draw(pGfx)) + return false; + + for(int i=0;i<4;i++) + if(m_aButtons[i].IsVisible()) + { + pGfx->DrawLine(0,GetHeight()-5,GetWidth(),GetHeight()-5); + break; + } + + return true; +} + +//************************************************************************ +// Set the specified button label +//************************************************************************ +void CScreen::SetButtonBitmap(int iButton, int iBitmap) +{ + if(iButton <0 || iButton > 3) + return; + if(iBitmap == 0) + { + m_aButtons[iButton].Show(0); + m_abShowButtons[iButton] = false; + } + else + { + if(m_ahBitmaps[iButton] != NULL) + DeleteObject(m_ahBitmaps[iButton]); + + m_ahBitmaps[iButton] = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(iBitmap), + IMAGE_BITMAP,17, 3, LR_MONOCHROME); + m_aButtons[iButton].SetBitmap(m_ahBitmaps[iButton]); + + if(CConfig::GetBoolSetting(SHOW_LABELS)) + m_aButtons[iButton].Show(1); + m_abShowButtons[iButton] = true; + } +} + +//************************************************************************ +// shows/hides the buttons +//************************************************************************ +void CScreen::ShowButtons(bool bShow) +{ + m_bHideButtons = !bShow; + UpdateButtons(); +} + +//************************************************************************ +// Update the buttons +//************************************************************************ +void CScreen::UpdateButtons() +{ + for (int i = 0; i < 4; i++) + { + if(GetWidth() == 160) { + m_aButtons[i].SetOrigin(10+i*29+(i/2)*36, GetHeight()-3); + } else { + m_aButtons[i].SetOrigin((280/4)*(i+0.5f) + (i/2)*40, GetHeight()-3); + } + + if(m_abShowButtons[i]) + m_aButtons[i].Show(CConfig::GetBoolSetting(SHOW_LABELS) && !m_bHideButtons); + } +} + +//************************************************************************ +// Called when an event is received +//************************************************************************ +void CScreen::OnEventReceived(CEvent *pEvent) +{ +} + +//************************************************************************ +// Called when the configuration has changed +//************************************************************************ +void CScreen::OnConfigChanged() +{ + UpdateButtons(); +} + +//************************************************************************ +// Called when the screens size has changed +//************************************************************************ +void CScreen::OnSizeChanged() { + CLCDScreen::OnSizeChanged(); + + UpdateButtons(); +} \ No newline at end of file diff --git a/plugins/MirandaG15/src/CScreen.h b/plugins/MirandaG15/src/CScreen.h new file mode 100644 index 0000000000..53b05a96e3 --- /dev/null +++ b/plugins/MirandaG15/src/CScreen.h @@ -0,0 +1,47 @@ +#ifndef _CSCREEN_H_ +#define _CSCREEN_H_ + +#include "CLCDScreen.h" +#include "CLCDBitmap.h" +//#include "CLCDLabel.h" + +class CScreen : public CLCDScreen +{ +public: + // Constructor + CScreen(); + // Destructor + ~CScreen(); + + // Initializes the screen + bool Initialize(); + // Shutdown the scren + bool Shutdown(); + // Updates the screen + bool Update(); + // Draws the screen + bool Draw(CLCDGfx *pGfx); + + // Called when an event is received + virtual void OnEventReceived(CEvent *pEvent); + // Called when the configuration has changed + virtual void OnConfigChanged(); + // Called when the screens size has changed + virtual void OnSizeChanged(); +protected: + // Set the specified button label + void SetButtonBitmap(int iButton, int iBitmap); + // Hide/Show the buttons + void ShowButtons(bool bShow); +private: + //CLCDLabel m_Clock; + + CLCDBitmap m_aButtons[4]; + HBITMAP m_ahBitmaps[4]; + bool m_abShowButtons[4]; + bool m_bHideButtons; + + void UpdateButtons(); +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/CScreensaverScreen.cpp b/plugins/MirandaG15/src/CScreensaverScreen.cpp new file mode 100644 index 0000000000..6c8a915a49 --- /dev/null +++ b/plugins/MirandaG15/src/CScreensaverScreen.cpp @@ -0,0 +1,200 @@ +#include "stdafx.h" +#include "CScreensaverScreen.h" +#include "CAppletManager.h" + +//************************************************************************ +// Constructor +//************************************************************************ +CScreensaverScreen::CScreensaverScreen() +{ +} + +//************************************************************************ +// Destructor +//************************************************************************ +CScreensaverScreen::~CScreensaverScreen() +{ +} + +//************************************************************************ +// Initializes the screen +//************************************************************************ +bool CScreensaverScreen::Initialize() +{ + if(!CScreen::Initialize()) + return false; + + m_Label.Initialize(); + m_Label2.Initialize(); + + m_Label.SetAlignment(DT_CENTER); + m_Label.SetWordWrap(TRUE); + m_Label.SetText(_T("Screensaver is active")); + m_Label.SetFontFaceName(_T("Microsoft Sans Serif")); + m_Label.SetFontPointSize(10); + m_Label.SetFontWeight(FW_BOLD); + + m_Label2.SetAlignment(DT_CENTER); + m_Label2.SetWordWrap(TRUE); + m_Label2.SetText(_T("")); + m_Label2.SetFontFaceName(_T("Microsoft Sans Serif")); + m_Label2.SetFontPointSize(8); + + m_Label.SetOrigin(0,0); + m_Label.SetSize(GetWidth(),20); + + m_Label2.SetOrigin(0,23); + m_Label2.SetSize(GetWidth(),20); + + + + AddObject(&m_Label); + AddObject(&m_Label2); + + return true; +} + +//************************************************************************ +// Shutdown the scren +//************************************************************************ +bool CScreensaverScreen::Shutdown() +{ + if(!CScreen::Shutdown()) + return false; + + return true; +} + +//************************************************************************ +// Updates the screen +//************************************************************************ +bool CScreensaverScreen::Update() +{ + if(!CScreen::Update()) + return false; + + DWORD dwTimeElapsed = GetTickCount() - m_dwActivation; + int iOldPosition = m_iPosition; + + if(dwTimeElapsed > m_dwDuration) + { + m_dwDuration = 4000; + m_Label.SetText(_T("")); + m_Label2.SetText(_T("")); + switch(m_iPosition) + { + case 0: + m_Label.SetFontPointSize(8); + m_Label.SetText(_T("MirandaG15")); + m_Label2.SetText(_T("Screensaver is active")); + m_dwDuration = 1800; + break; + case 1: + m_Label.SetFontPointSize(11); + m_Label.SetText(_T("MirandaG15")); + m_Label2.SetText(_T("Applet locked")); + m_dwDuration = 1800; + m_iPosition = -1; + break; + + default: + CAppletManager::GetInstance()->ActivateEventScreen(); + return true; + } + m_iPosition++; + CAppletManager::GetInstance()->StartTransition(TRANSITION_MORPH); + } + + if(m_iPosition != iOldPosition) + m_dwActivation = GetTickCount(); + + return true; +} + +//************************************************************************ +// Resets the credits screens state +//************************************************************************ +void CScreensaverScreen::Reset() +{ + m_dwDuration = 0; + m_iPosition = 0; + + m_Label.SetFontPointSize(10); + + m_Label.SetText(_T("")); + m_Label2.SetText(_T("")); + + CAppletManager::GetInstance()->GetLCDConnection()->SetAsForeground(true); +} + + +//************************************************************************ +// Draws the screen +//************************************************************************ +bool CScreensaverScreen::Draw(CLCDGfx *pGfx) +{ + if(!CScreen::Draw(pGfx)) + return false; + + return true; +} + +//************************************************************************ +// Called when the configuration has changed +//************************************************************************ +void CScreensaverScreen::OnConfigChanged() +{ + CScreen::OnConfigChanged(); +} + +//************************************************************************ +// Called when the screen size has changed +//************************************************************************ +void CScreensaverScreen::OnSizeChanged() +{ + CScreen::OnSizeChanged(); +} + +//************************************************************************ +// Called when an LCD-button is pressed +//************************************************************************ +void CScreensaverScreen::OnLCDButtonDown(int iButton) +{ +} + +//************************************************************************ +// Called when an LCD-button event is repeated +//************************************************************************ +void CScreensaverScreen::OnLCDButtonRepeated(int iButton) +{ +} + +//************************************************************************ +// Called when an LCD-button is released +//************************************************************************ +void CScreensaverScreen::OnLCDButtonUp(int iButton) +{ +} + +//************************************************************************ +// Called when the screen is activated +//************************************************************************ +void CScreensaverScreen::OnActivation() +{ +} + +//************************************************************************ +// Called when the screen is deactivated +//************************************************************************ +void CScreensaverScreen::OnDeactivation() +{ + CAppletManager::GetInstance()->GetLCDConnection()->SetAsForeground(false); + CAppletManager::GetInstance()->StartTransition(TRANSITION_MORPH); +} + +//************************************************************************ +// Called when the screen has expired +//************************************************************************ +void CScreensaverScreen::OnExpiration() +{ +} diff --git a/plugins/MirandaG15/src/CScreensaverScreen.h b/plugins/MirandaG15/src/CScreensaverScreen.h new file mode 100644 index 0000000000..19592a204b --- /dev/null +++ b/plugins/MirandaG15/src/CScreensaverScreen.h @@ -0,0 +1,51 @@ +#ifndef _CSCREENSAVERSSCREEN_H_ +#define _CSCREENSAVERSSCREEN_H_ + +#include "CScreen.h" +#include "CLCDLabel.h" + +class CScreensaverScreen : public CScreen +{ +public: + // Constructor + CScreensaverScreen(); + // Destructor + ~CScreensaverScreen(); + + // Initializes the screen + bool Initialize(); + // Shutdown the scren + bool Shutdown(); + // Updates the screen + bool Update(); + // Draws the screen + bool Draw(CLCDGfx *pGfx); + + // Called when the configuration has changed + void OnConfigChanged(); + // Called when the screen size has changed + void OnSizeChanged(); + // Called when an LCD-button is pressed + void OnLCDButtonDown(int iButton); + // Called when an LCD-button event is repeated + void OnLCDButtonRepeated(int iButton); + // Called when an LCD-button is released + void OnLCDButtonUp(int iButton); + // Called when the screen is activated + void OnActivation(); + // Called when the screen is deactivated + void OnDeactivation(); + // Called when the screen has expired + void OnExpiration(); + + // Resets the credits screens state + void Reset(); +private: + + CLCDLabel m_Label,m_Label2; + DWORD m_dwActivation; + DWORD m_dwDuration; + int m_iPosition; +}; + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/Miranda.cpp b/plugins/MirandaG15/src/Miranda.cpp new file mode 100644 index 0000000000..6776c397ef --- /dev/null +++ b/plugins/MirandaG15/src/Miranda.cpp @@ -0,0 +1,223 @@ + +/* + * Miranda IM LCD Plugin + * Displays incoming text messages on an LCD. + * + * Copyright (c) 2003 Martin Rubli, mrubli@gmx.net + * + ****************************************************************************** + * This file is part of Miranda IM LCD Plugin. + * + * Miranda IM LCD Plugin 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; either version 2 of the License, or (at + * your option) any later version. + * + * Miranda IM LCD Plugin 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 Miranda IM LCD Plugin; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + ****************************************************************************** + * + * Miranda.cpp: Miranda plugin initialisation + */ + +/* + * TODO: + +*/ +/* + * CHANGES: + */ +/* + * KNOWN BUGS: + * + */ + +/* + * IDEAS: + * + */ + +#ifdef _DEBUG + #include + #define _CRTDBG_MAP_ALLOC +#endif + +#include "StdAfx.h" + +#include "CAppletManager.h" +#include "CConfig.h" + +#include "m_system.h" + +// SETTINGS +#define LCD_FPS 10 + +//************************************************************************ +// Variables +//************************************************************************ +bool g_bInitialized; +bool g_bUnicode; +// AppletManager object + CAppletManager* g_AppletManager; + +// Plugin Information + +HINSTANCE hInstance; +int hLangpack; + +// Initialization Hook +static HANDLE hMIHookModulesLoaded; + +// {58D63981-14C1-4099-A3F7-F4FAA4C8FC59} +#define MIID_G15APPLET { 0x58d63981, 0x14c1, 0x4099, { 0xa3, 0xf7, 0xf4, 0xfa, 0xa4, 0xc8, 0xfc, 0x59 } } + +static const MUUID interfaces[] = {MIID_G15APPLET, MIID_LAST}; + +static PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), + APP_NAME, + PLUGIN_MAKE_VERSION(0,1,2,0), + "Provides an interface to use Miranda from the LCD of various Logitech devices", + "Martin Kleinhans", + "mail@mkleinhans.de", + "© 2009 Martin Kleinhans", + "http://www.mkleinhans.de", + 0, // not transient + // {798221E1-E47A-4dc8-9077-1E576F9C4307} + { 0x798221e1, 0xe47a, 0x4dc8, { 0x90, 0x77, 0x1e, 0x57, 0x6f, 0x9c, 0x43, 0x7 } } +}; + +// Function Prototypes +int Init(WPARAM,LPARAM); +void UnInit(); + + + +//************************************************************************ +// Exported Functions +//************************************************************************ +extern "C" { + __declspec(dllexport) const MUUID * MirandaPluginInterfaces(void) + { + return interfaces; + } + + __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) + { + // Are we running under Unicode Windows version ? + g_bUnicode = (GetVersion() & 0x80000000) == 0; + if (g_bUnicode) { + pluginInfo.flags = 1; // UNICODE_AWARE + } + return &pluginInfo; + } + + + // Called by Miranda to load the plugin. + // We defer initialization until Miranda's module loading process completed and return 0 to + // mark success, everything else will cause the plugin to be freed right away. + int __declspec(dllexport) Load() + { + g_bInitialized = false; + InitDebug(); + TRACE(_T("Plugin loaded\n")); + // Schedule actual initialization for later + // (We don't really need the handle but want to be able to release it properly later ...) + hMIHookModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, Init); + if(hMIHookModulesLoaded == 0) + { + tstring text = _T("Failed to initialize the Applet.\nThe plugin will not be loaded. "); + tstring title = _T(APP_SHORTNAME); + MessageBox(NULL, text.c_str(), title.c_str(), MB_OK | MB_ICONEXCLAMATION); + return 1; + } + return 0; + } + + // Called by Miranda when the plugin should unload itself. + int __declspec(dllexport) Unload(void) + { + if(!g_bInitialized) { + TRACE(_T("ERROR: Unload requested, but plugin is not initialized?!\n")); + return 0; + } + TRACE(_T("-------------------------------------------\nUnloading started\n")); + UnInit(); + TRACE(_T("Unloading successful\n")); + TRACE(_T("Cleaning up: ")); + UnhookEvent(hMIHookModulesLoaded); // just to be really correct ... + UnInitDebug(); + TRACE(_T("OK!\n")); + return 0; + } +} + +//************************************************************************ +// DllMain +// +// EntryPoint of the DLL +//************************************************************************ +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + + hInstance = hinstDLL; + return TRUE; +} + +//************************************************************************ +// Init +// +// Called after Miranda has finished loading all modules +// This is where the main plugin initialization happens and the +// connection to the LCD is established, +//************************************************************************ +int Init(WPARAM wParam,LPARAM lParam) +{ + g_AppletManager = new CAppletManager(); + // Memoryleak Detection + #ifdef _DEBUG + _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); + + #endif + + // set up the LCD context as non-autostart, non-persist, callbacked + CConfig::Initialize(); + + // Initialize the output object + if(!g_AppletManager->Initialize(toTstring(APP_SHORTNAME))) + { + if(CConfig::GetBoolSetting(SKIP_DRIVER_ERROR)) { + tstring text = _T("Failed to initialize the LCD connection\n Make sure you have the newest Logitech drivers installed (>=1.03).\n"); + tstring title = _T(APP_SHORTNAME); + MessageBox(NULL, text.c_str(), title.c_str(), MB_OK | MB_ICONEXCLAMATION); + } + + TRACE(_T("Initialization failed!.\n")); + return 0; + } + + g_bInitialized = true; + TRACE(_T("Initialization completed successfully.\n-------------------------------------------\n")); + return 0; +} +//************************************************************************ +// UnInit +// +// Called when the plugin is about to be unloaded +//************************************************************************ +void UnInit(void) +{ + g_AppletManager->Shutdown(); + delete g_AppletManager; + UnhookEvent(hMIHookModulesLoaded); + +//#ifdef _DEBUG +// _CrtDumpMemoryLeaks(); +//#endif +} diff --git a/plugins/MirandaG15/src/Miranda.h b/plugins/MirandaG15/src/Miranda.h new file mode 100644 index 0000000000..851da133cb --- /dev/null +++ b/plugins/MirandaG15/src/Miranda.h @@ -0,0 +1,4 @@ +extern HINSTANCE hInstance; +extern char *MsgServiceName(HANDLE hContact,bool bIsUnicode); +extern bool g_bUnicode; + diff --git a/plugins/MirandaG15/src/StdAfx.h b/plugins/MirandaG15/src/StdAfx.h new file mode 100644 index 0000000000..c03f576c95 --- /dev/null +++ b/plugins/MirandaG15/src/StdAfx.h @@ -0,0 +1,53 @@ +#ifndef _STDAFX_H_ +#define _STDAFX_H_ + +#define APP_NAME "MirandaG15" +#define APP_SHORTNAME "MirandaG15" + +/* Common header files */ +#include + +#define _WIN32_WINNT 0x0500 // Needed for waitable timers +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define IDF_ISIDLE 0x1 // idle has become active (if not set, inactive) +#define IDF_SHORT 0x2 // short idle mode +#define IDF_LONG 0x4 // long idle mode +//#define IDF_PRIVACY 0x8 // if set, the information provided shouldn't be given to third parties. +#define IDF_ONFORCE 0x10 + +#define ASSERT assert + +#include "LCDFramework.h" + +#include "Miranda.h" +#include "CEvent.h" + +#include "../resource.h" + +#endif \ No newline at end of file diff --git a/plugins/MirandaG15/src/m_metacontacts.h b/plugins/MirandaG15/src/m_metacontacts.h new file mode 100644 index 0000000000..9f348bd2c6 --- /dev/null +++ b/plugins/MirandaG15/src/m_metacontacts.h @@ -0,0 +1,166 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright © 2004 Universite Louis PASTEUR, STRASBOURG. +Copyright © 2004 Scott Ellis (www.scottellis.com.au mail@scottellis.com.au) + +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; either version 2 +of the License, or (at your option) any later version. + +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef M_METACONTACTS_H__ +#define M_METACONTACTS_H__ 1 + +#ifndef MIID_METACONTACTS +#define MIID_METACONTACTS {0xc0325019, 0xc1a7, 0x40f5, { 0x83, 0x65, 0x4f, 0x46, 0xbe, 0x21, 0x86, 0x3e}} +#endif + +//get the handle for a contact's parent metacontact +//wParam=(HANDLE)hSubContact +//lParam=0 +//returns a handle to the parent metacontact, or null if this contact is not a subcontact +#define MS_MC_GETMETACONTACT "MetaContacts/GetMeta" + +//gets the handle for the default contact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns a handle to the default contact, or null on failure +#define MS_MC_GETDEFAULTCONTACT "MetaContacts/GetDefault" + +//gets the contact number for the default contact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns a DWORD contact number, or -1 on failure +#define MS_MC_GETDEFAULTCONTACTNUM "MetaContacts/GetDefaultNum" + +//gets the handle for the 'most online' contact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns a handle to the 'most online' contact +#define MS_MC_GETMOSTONLINECONTACT "MetaContacts/GetMostOnline" + +//gets the number of subcontacts for a metacontact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns a DWORD representing the number of subcontacts for the given metacontact +#define MS_MC_GETNUMCONTACTS "MetaContacts/GetNumContacts" + +//gets the handle of a subcontact, using the subcontact's number +//wParam=(HANDLE)hMetaContact +//lParam=(DWORD)contact number +//returns a handle to the specified subcontact +#define MS_MC_GETSUBCONTACT "MetaContacts/GetSubContact" + +//sets the default contact, using the subcontact's contact number +//wParam=(HANDLE)hMetaContact +//lParam=(DWORD)contact number +//returns 0 on success +#define MS_MC_SETDEFAULTCONTACTNUM "MetaContacts/SetDefault" + +//sets the default contact, using the subcontact's handle +//wParam=(HANDLE)hMetaContact +//lParam=(HANDLE)hSubcontact +//returns 0 on success +#define MS_MC_SETDEFAULTCONTACT "MetaContacts/SetDefaultByHandle" + +//forces the metacontact to send using a specific subcontact, using the subcontact's contact number +//wParam=(HANDLE)hMetaContact +//lParam=(DWORD)contact number +//returns 0 on success +#define MS_MC_FORCESENDCONTACTNUM "MetaContacts/ForceSendContact" + +//forces the metacontact to send using a specific subcontact, using the subcontact's handle +//wParam=(HANDLE)hMetaContact +//lParam=(HANDLE)hSubcontact +//returns 0 on success (will fail if 'force default' is in effect) +#define MS_MC_FORCESENDCONTACT "MetaContacts/ForceSendContactByHandle" + +//'unforces' the metacontact to send using a specific subcontact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns 0 on success (will fail if 'force default' is in effect) +#define MS_MC_UNFORCESENDCONTACT "MetaContacts/UnforceSendContact" + +//'forces' or 'unforces' (i.e. toggles) the metacontact to send using it's default contact +// overrides (and clears) 'force send' above, and will even force use of offline contacts +// will send ME_MC_FORCESEND or ME_MC_UNFORCESEND event +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns 1(true) or 0(false) representing new state of 'force default' +#define MS_MC_FORCEDEFAULT "MetaContacts/ForceSendDefault" + +// method to get state of 'force' for a metacontact +// wParam=(HANDLE)hMetaContact +// lParam= (DWORD)&contact_number or NULL +// +// if lparam supplied, the contact_number of the contatct 'in force' will be copied to the address it points to, +// or if none is in force, the value (DWORD)-1 will be copied +// (v0.8.0.8+ returns 1 if 'force default' is true with *lParam == default contact number, else returns 0 with *lParam as above) +#define MS_MC_GETFORCESTATE "MetaContacts/GetForceState" + +// fired when a metacontact's default contact changes (fired upon creation of metacontact also, when default is initially set) +// wParam=(HANDLE)hMetaContact +// lParam=(HANDLE)hDefaultContact +#define ME_MC_DEFAULTTCHANGED "MetaContacts/DefaultChanged" + +// fired when a metacontact's subcontacts change (fired upon creation of metacontact, when contacts are added or removed, and when +// contacts are reordered) - a signal to re-read metacontact data +// wParam=(HANDLE)hMetaContact +// lParam=0 +#define ME_MC_SUBCONTACTSCHANGED "MetaContacts/SubcontactsChanged" + +// fired when a metacontact is forced to send using a specific subcontact +// wParam=(HANDLE)hMetaContact +// lParam=(HANDLE)hForceContact +#define ME_MC_FORCESEND "MetaContacts/ForceSend" + +// fired when a metacontact is 'unforced' to send using a specific subcontact +// wParam=(HANDLE)hMetaContact +// lParam=0 +#define ME_MC_UNFORCESEND "MetaContacts/UnforceSend" + +// method to get protocol name - used to be sure you're dealing with a "real" metacontacts plugin :) +// wParam=lParam=0 +#define MS_MC_GETPROTOCOLNAME "MetaContacts/GetProtoName" + + +// added 0.9.5.0 (22/3/05) +// wParam=(HANDLE)hContact +// lParam=0 +// convert a given contact into a metacontact +#define MS_MC_CONVERTTOMETA "MetaContacts/ConvertToMetacontact" + +// added 0.9.5.0 (22/3/05) +// wParam=(HANDLE)hContact +// lParam=(HANDLE)hMeta +// add an existing contact to a metacontact +#define MS_MC_ADDTOMETA "MetaContacts/AddToMetacontact" + +// added 0.9.5.0 (22/3/05) +// wParam=0 +// lParam=(HANDLE)hContact +// remove a contact from a metacontact +#define MS_MC_REMOVEFROMMETA "MetaContacts/RemoveFromMetacontact" + + +// added 0.9.13.2 (6/10/05) +// wParam=(BOOL)disable +// lParam=0 +// enable/disable the 'hidden group hack' - for clists that support subcontact hiding using 'IsSubcontact' setting +// should be called once in the clist 'onmodulesloaded' event handler (which, since it's loaded after the db, will be called +// before the metacontact onmodulesloaded handler where the subcontact hiding is usually done) +#define MS_MC_DISABLEHIDDENGROUP "MetaContacts/DisableHiddenGroup" + +#endif diff --git a/plugins/MirandaG15/todo.txt b/plugins/MirandaG15/todo.txt new file mode 100644 index 0000000000..cde4eb5ade --- /dev/null +++ b/plugins/MirandaG15/todo.txt @@ -0,0 +1,14 @@ +MAYBE: +================= +metacontacts: +- eventuell chat für metakontakte öffnen..?! + +hidden contacts bei gruppen-membercounter ignorieren + +FIX: +================ +irc disconnected message fehlt? + +FEATURE: +================ +status message anzeige? -- cgit v1.2.3