From ae30cd958593fae5c4d385045f5ba669b9dd4b50 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 18 Jun 2015 18:29:39 +0000 Subject: protocol platform-independent code moved back to mir_app git-svn-id: http://svn.miranda-ng.org/main/trunk@14247 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- src/mir_app/mir_app.vcxproj | 4 +- src/mir_app/mir_app.vcxproj.filters | 13960 ---------------------------------- src/mir_app/src/mir_app.def | 104 + src/mir_app/src/mir_app64.def | 130 + src/mir_app/src/miranda.h | 3 +- src/mir_app/src/proto_accs.cpp | 453 ++ src/mir_app/src/proto_chains.cpp | 253 + src/mir_app/src/proto_internal.cpp | 304 + src/mir_app/src/proto_opts.cpp | 1062 +++ src/mir_app/src/proto_order.cpp | 231 + src/mir_app/src/proto_ui.cpp | 169 + src/mir_app/src/proto_utils.cpp | 407 + src/mir_app/src/protoaccs.cpp | 453 -- src/mir_app/src/protochains.cpp | 253 - src/mir_app/src/protocolorder.cpp | 231 - src/mir_app/src/protocols.cpp | 29 +- src/mir_app/src/protodir.cpp | 243 - src/mir_app/src/protoint.cpp | 304 - src/mir_app/src/protoopts.cpp | 1062 --- 19 files changed, 3144 insertions(+), 16511 deletions(-) create mode 100644 src/mir_app/src/mir_app64.def create mode 100644 src/mir_app/src/proto_accs.cpp create mode 100644 src/mir_app/src/proto_chains.cpp create mode 100644 src/mir_app/src/proto_internal.cpp create mode 100644 src/mir_app/src/proto_opts.cpp create mode 100644 src/mir_app/src/proto_order.cpp create mode 100644 src/mir_app/src/proto_ui.cpp create mode 100644 src/mir_app/src/proto_utils.cpp delete mode 100644 src/mir_app/src/protoaccs.cpp delete mode 100644 src/mir_app/src/protochains.cpp delete mode 100644 src/mir_app/src/protocolorder.cpp delete mode 100644 src/mir_app/src/protodir.cpp delete mode 100644 src/mir_app/src/protoint.cpp delete mode 100644 src/mir_app/src/protoopts.cpp (limited to 'src/mir_app') diff --git a/src/mir_app/mir_app.vcxproj b/src/mir_app/mir_app.vcxproj index 4894f75418..12e2066a69 100644 --- a/src/mir_app/mir_app.vcxproj +++ b/src/mir_app/mir_app.vcxproj @@ -31,7 +31,9 @@ MIR_APP_EXPORTS;NDEBUG;%(PreprocessorDefinitions) - src/mir_app.def + src/mir_app.def + src/mir_app64.def + /ignore:4197 %(AdditionalOptions) type=%27win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27*%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;type=%27win32%27 name=%27Microsoft.Windows.Gdiplus%27 version=%271.0.0.0%27 processorArchitecture=%27amd64%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies) diff --git a/src/mir_app/mir_app.vcxproj.filters b/src/mir_app/mir_app.vcxproj.filters index 009c1ff27f..de5ad9f66c 100644 --- a/src/mir_app/mir_app.vcxproj.filters +++ b/src/mir_app/mir_app.vcxproj.filters @@ -1,13964 +1,4 @@  - - - Source Files - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source Files - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - - - - - - - - - - - - - - - - - - - - - - - Resource Files - - - - Resource Files - - - - - - Source Files - - \ No newline at end of file diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def index a6a49fd7be..fbbeedf608 100644 --- a/src/mir_app/src/mir_app.def +++ b/src/mir_app/src/mir_app.def @@ -24,3 +24,107 @@ IcoLib_RemoveIconByHandle @21 IcoLib_Release @22 IcoLib_AddRef @23 Skin_GetIconName @24 +??0CProtoIntDlgBase@@QAE@ABV0@@Z @25 NONAME +??0CProtoIntDlgBase@@QAE@PAUPROTO_INTERFACE@@H_N@Z @26 NONAME +??0PROTO_INTERFACE@@QAE@ABU0@@Z @27 NONAME +??0PROTO_INTERFACE@@QAE@XZ @28 NONAME +??1CProtoIntDlgBase@@UAE@XZ @29 NONAME +??4CProtoIntDlgBase@@QAEAAV0@ABV0@@Z @30 NONAME +??4PROTO_INTERFACE@@QAEAAU0@ABU0@@Z @31 NONAME +??_7CProtoIntDlgBase@@6B@ @32 NONAME +??_7PROTO_INTERFACE@@6B@ @33 NONAME +?AddToList@PROTO_INTERFACE@@UAAIHPAUPROTOSEARCHRESULT@@@Z @34 NONAME +?AddToListByEvent@PROTO_INTERFACE@@UAAIHHI@Z @35 NONAME +?AuthDeny@PROTO_INTERFACE@@UAAHIPB_W@Z @36 NONAME +?AuthRecv@PROTO_INTERFACE@@UAAHIPAUPROTORECVEVENT@@@Z @37 NONAME +?AuthRequest@PROTO_INTERFACE@@UAAHIPB_W@Z @38 NONAME +?Authorize@PROTO_INTERFACE@@UAAHI@Z @39 NONAME +?CreateExtendedSearchUI@PROTO_INTERFACE@@UAAPAUHWND__@@PAU2@@Z @40 NONAME +?CreateLink@CProtoIntDlgBase@@QAEXAAVCCtrlData@@PADEK@Z @41 NONAME +?CreateLink@CProtoIntDlgBase@@QAEXAAVCCtrlData@@PBDPA_W@Z @42 NONAME +?DlgProc@CProtoIntDlgBase@@MAEHIIJ@Z @43 NONAME +?FileAllow@PROTO_INTERFACE@@UAAPAXIPAXPB_W@Z @44 NONAME +?FileCancel@PROTO_INTERFACE@@UAAHIPAX@Z @45 NONAME +?FileDeny@PROTO_INTERFACE@@UAAHIPAXPB_W@Z @46 NONAME +?FileResume@PROTO_INTERFACE@@UAAHPAXPAHPAPB_W@Z @47 NONAME +?GetAwayMsg@PROTO_INTERFACE@@UAAPAXI@Z @48 NONAME +?GetCaps@PROTO_INTERFACE@@UAAKHI@Z @49 NONAME +?GetInfo@PROTO_INTERFACE@@UAAHIH@Z @50 NONAME +?GetProtoInterface@CProtoIntDlgBase@@QAEPAUPROTO_INTERFACE@@XZ @51 NONAME +?OnEvent@PROTO_INTERFACE@@UAAHW4PROTOEVENTTYPE@@IJ@Z @52 NONAME +?OnProtoActivate@CProtoIntDlgBase@@MAEXIJ@Z @53 NONAME +?OnProtoCheckOnline@CProtoIntDlgBase@@MAEXIJ@Z @54 NONAME +?OnProtoRefresh@CProtoIntDlgBase@@MAEXIJ@Z @55 NONAME +?ProtoBroadcastAck@PROTO_INTERFACE@@QAEHIHHPAXJ@Z @56 NONAME +?RecvAwayMsg@PROTO_INTERFACE@@UAAHIHPAUPROTORECVEVENT@@@Z @57 NONAME +?RecvContacts@PROTO_INTERFACE@@UAAHIPAUPROTORECVEVENT@@@Z @58 NONAME +?RecvFile@PROTO_INTERFACE@@UAAHIPAUPROTORECVFILET@@@Z @59 NONAME +?RecvMsg@PROTO_INTERFACE@@UAAHIPAUPROTORECVEVENT@@@Z @60 NONAME +?RecvUrl@PROTO_INTERFACE@@UAAHIPAUPROTORECVEVENT@@@Z @61 NONAME +?SearchAdvanced@PROTO_INTERFACE@@UAAPAUHWND__@@PAU2@@Z @62 NONAME +?SearchBasic@PROTO_INTERFACE@@UAAPAXPB_W@Z @63 NONAME +?SearchByEmail@PROTO_INTERFACE@@UAAPAXPB_W@Z @64 NONAME +?SearchByName@PROTO_INTERFACE@@UAAPAXPB_W00@Z @65 NONAME +?SendContacts@PROTO_INTERFACE@@UAAHIHHPAI@Z @66 NONAME +?SendFile@PROTO_INTERFACE@@UAAPAXIPB_WPAPA_W@Z @67 NONAME +?SendMsg@PROTO_INTERFACE@@UAAHIHPBD@Z @68 NONAME +?SendUrl@PROTO_INTERFACE@@UAAHIHPBD@Z @69 NONAME +?SetApparentMode@PROTO_INTERFACE@@UAAHIH@Z @70 NONAME +?SetAwayMsg@PROTO_INTERFACE@@UAAHHPB_W@Z @71 NONAME +?SetStatus@PROTO_INTERFACE@@UAAHH@Z @72 NONAME +?SetStatusText@CProtoIntDlgBase@@QAEXPB_W@Z @73 NONAME +?UpdateProtoTitle@CProtoIntDlgBase@@AAEXPB_W@Z @74 NONAME +?UpdateStatusBar@CProtoIntDlgBase@@AAEXXZ @75 NONAME +?UserIsTyping@PROTO_INTERFACE@@UAAHIH@Z @76 NONAME +?WindowSubscribe@PROTO_INTERFACE@@QAEXPAUHWND__@@@Z @77 NONAME +?WindowUnsubscribe@PROTO_INTERFACE@@QAEXPAUHWND__@@@Z @78 NONAME +?debugLogA@PROTO_INTERFACE@@QAAXPBDZZ @79 NONAME +?debugLogW@PROTO_INTERFACE@@QAAXPB_WZZ @80 NONAME +?delSetting@PROTO_INTERFACE@@QAEHIPBD@Z @81 NONAME +?delSetting@PROTO_INTERFACE@@QAEHPBD@Z @82 NONAME +?getBool@PROTO_INTERFACE@@QAE_NIPBD_N@Z @83 NONAME +?getBool@PROTO_INTERFACE@@QAE_NPBD_N@Z @84 NONAME +?getByte@PROTO_INTERFACE@@QAEHIPBDE@Z @85 NONAME +?getByte@PROTO_INTERFACE@@QAEHPBDE@Z @86 NONAME +?getDword@PROTO_INTERFACE@@QAEKIPBDK@Z @87 NONAME +?getDword@PROTO_INTERFACE@@QAEKPBDK@Z @88 NONAME +?getString@PROTO_INTERFACE@@QAEHIPBDPAUDBVARIANT@@@Z @89 NONAME +?getString@PROTO_INTERFACE@@QAEHPBDPAUDBVARIANT@@@Z @90 NONAME +?getStringA@PROTO_INTERFACE@@QAEPADIPBD@Z @91 NONAME +?getStringA@PROTO_INTERFACE@@QAEPADPBD@Z @92 NONAME +?getWString@PROTO_INTERFACE@@QAEHIPBDPAUDBVARIANT@@@Z @93 NONAME +?getWString@PROTO_INTERFACE@@QAEHPBDPAUDBVARIANT@@@Z @94 NONAME +?getWStringA@PROTO_INTERFACE@@QAEPA_WIPBD@Z @95 NONAME +?getWStringA@PROTO_INTERFACE@@QAEPA_WPBD@Z @96 NONAME +?getWord@PROTO_INTERFACE@@QAEHIPBDG@Z @97 NONAME +?getWord@PROTO_INTERFACE@@QAEHPBDG@Z @98 NONAME +?isChatRoom@PROTO_INTERFACE@@QAE_NI@Z @99 NONAME +?setByte@PROTO_INTERFACE@@QAEXIPBDE@Z @100 NONAME +?setByte@PROTO_INTERFACE@@QAEXPBDE@Z @101 NONAME +?setDword@PROTO_INTERFACE@@QAEXIPBDK@Z @102 NONAME +?setDword@PROTO_INTERFACE@@QAEXPBDK@Z @103 NONAME +?setString@PROTO_INTERFACE@@QAEXIPBD0@Z @104 NONAME +?setString@PROTO_INTERFACE@@QAEXPBD0@Z @105 NONAME +?setWString@PROTO_INTERFACE@@QAEXIPBDPB_W@Z @106 NONAME +?setWString@PROTO_INTERFACE@@QAEXPBDPB_W@Z @107 NONAME +?setWord@PROTO_INTERFACE@@QAEXIPBDG@Z @108 NONAME +?setWord@PROTO_INTERFACE@@QAEXPBDG@Z @109 NONAME +GetPluginLangByInstance @110 +ProtoBroadcastAck @111 +ProtoConstructor @112 +ProtoCreateHookableEvent @113 +ProtoCreateService @114 +ProtoCreateServiceParam @115 +ProtoDestructor @116 +ProtoForkThread @117 +ProtoForkThreadEx @118 +ProtoGetAvatarExtension @119 +ProtoGetAvatarFileFormat @120 +ProtoGetAvatarFormat @121 +ProtoGetBufferFormat @122 +ProtoHookEvent @123 +ProtoLogA @124 +ProtoLogW @125 +ProtoWindowAdd @126 +ProtoWindowRemove @127 +Proto_IsProtocolLoaded @128 diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def new file mode 100644 index 0000000000..d0ef1f280d --- /dev/null +++ b/src/mir_app/src/mir_app64.def @@ -0,0 +1,130 @@ +EXPORTS + +CallContactService @1 +CallProtoService @2 +RecalculateTime @3 +Skin_LoadProtoIcon @4 +Skin_LoadIcon @5 +Button_FreeIcon_IcoLib @6 +Button_SetIcon_IcoLib @7 +Skin_GetIconHandle @8 +IcoLib_AddIcon @9 +IcoLib_GetIcon @10 +IcoLib_GetIconByHandle @11 +IcoLib_GetIconHandle @12 +IcoLib_IsManaged @13 +IcoLib_ReleaseIcon @14 +Window_FreeIcon_IcoLib @15 +Window_SetIcon_IcoLib @16 +Window_SetProtoIcon_IcoLib @17 +ProtoServiceExists @18 +mir_main @19 +IcoLib_RemoveIcon @20 +IcoLib_RemoveIconByHandle @21 +IcoLib_Release @22 +IcoLib_AddRef @23 +Skin_GetIconName @24 +??0CProtoIntDlgBase@@QEAA@AEBV0@@Z @25 NONAME +??0CProtoIntDlgBase@@QEAA@PEAUPROTO_INTERFACE@@H_N@Z @26 NONAME +??0PROTO_INTERFACE@@QEAA@AEBU0@@Z @27 NONAME +??0PROTO_INTERFACE@@QEAA@XZ @28 NONAME +??1CProtoIntDlgBase@@UEAA@XZ @29 NONAME +??4CProtoIntDlgBase@@QEAAAEAV0@AEBV0@@Z @30 NONAME +??4PROTO_INTERFACE@@QEAAAEAU0@AEBU0@@Z @31 NONAME +??_7CProtoIntDlgBase@@6B@ @32 NONAME +??_7PROTO_INTERFACE@@6B@ @33 NONAME +?AddToList@PROTO_INTERFACE@@UEAAIHPEAUPROTOSEARCHRESULT@@@Z @34 NONAME +?AddToListByEvent@PROTO_INTERFACE@@UEAAIHHI@Z @35 NONAME +?AuthDeny@PROTO_INTERFACE@@UEAAHIPEB_W@Z @36 NONAME +?AuthRecv@PROTO_INTERFACE@@UEAAHIPEAUPROTORECVEVENT@@@Z @37 NONAME +?AuthRequest@PROTO_INTERFACE@@UEAAHIPEB_W@Z @38 NONAME +?Authorize@PROTO_INTERFACE@@UEAAHI@Z @39 NONAME +?CreateExtendedSearchUI@PROTO_INTERFACE@@UEAAPEAUHWND__@@PEAU2@@Z @40 NONAME +?CreateLink@CProtoIntDlgBase@@QEAAXAEAVCCtrlData@@PEADEK@Z @41 NONAME +?CreateLink@CProtoIntDlgBase@@QEAAXAEAVCCtrlData@@PEBDPEA_W@Z @42 NONAME +?DlgProc@CProtoIntDlgBase@@MEAA_JI_K_J@Z @43 NONAME +?FileAllow@PROTO_INTERFACE@@UEAAPEAXIPEAXPEB_W@Z @44 NONAME +?FileCancel@PROTO_INTERFACE@@UEAAHIPEAX@Z @45 NONAME +?FileDeny@PROTO_INTERFACE@@UEAAHIPEAXPEB_W@Z @46 NONAME +?FileResume@PROTO_INTERFACE@@UEAAHPEAXPEAHPEAPEB_W@Z @47 NONAME +?GetAwayMsg@PROTO_INTERFACE@@UEAAPEAXI@Z @48 NONAME +?GetCaps@PROTO_INTERFACE@@UEAA_KHI@Z @49 NONAME +?GetInfo@PROTO_INTERFACE@@UEAAHIH@Z @50 NONAME +?GetProtoInterface@CProtoIntDlgBase@@QEAAPEAUPROTO_INTERFACE@@XZ @51 NONAME +?OnEvent@PROTO_INTERFACE@@UEAAHW4PROTOEVENTTYPE@@_K_J@Z @52 NONAME +?OnProtoActivate@CProtoIntDlgBase@@MEAAX_K_J@Z @53 NONAME +?OnProtoCheckOnline@CProtoIntDlgBase@@MEAAX_K_J@Z @54 NONAME +?OnProtoRefresh@CProtoIntDlgBase@@MEAAX_K_J@Z @55 NONAME +?ProtoBroadcastAck@PROTO_INTERFACE@@QEAA_JIHHPEAX_J@Z @56 NONAME +?RecvAwayMsg@PROTO_INTERFACE@@UEAAHIHPEAUPROTORECVEVENT@@@Z @57 NONAME +?RecvContacts@PROTO_INTERFACE@@UEAAHIPEAUPROTORECVEVENT@@@Z @58 NONAME +?RecvFile@PROTO_INTERFACE@@UEAAHIPEAUPROTORECVFILET@@@Z @59 NONAME +?RecvMsg@PROTO_INTERFACE@@UEAAHIPEAUPROTORECVEVENT@@@Z @60 NONAME +?RecvUrl@PROTO_INTERFACE@@UEAAHIPEAUPROTORECVEVENT@@@Z @61 NONAME +?SearchAdvanced@PROTO_INTERFACE@@UEAAPEAUHWND__@@PEAU2@@Z @62 NONAME +?SearchBasic@PROTO_INTERFACE@@UEAAPEAXPEB_W@Z @63 NONAME +?SearchByEmail@PROTO_INTERFACE@@UEAAPEAXPEB_W@Z @64 NONAME +?SearchByName@PROTO_INTERFACE@@UEAAPEAXPEB_W00@Z @65 NONAME +?SendContacts@PROTO_INTERFACE@@UEAAHIHHPEAI@Z @66 NONAME +?SendFile@PROTO_INTERFACE@@UEAAPEAXIPEB_WPEAPEA_W@Z @67 NONAME +?SendMsg@PROTO_INTERFACE@@UEAAHIHPEBD@Z @68 NONAME +?SendUrl@PROTO_INTERFACE@@UEAAHIHPEBD@Z @69 NONAME +?SetApparentMode@PROTO_INTERFACE@@UEAAHIH@Z @70 NONAME +?SetAwayMsg@PROTO_INTERFACE@@UEAAHHPEB_W@Z @71 NONAME +?SetStatus@PROTO_INTERFACE@@UEAAHH@Z @72 NONAME +?SetStatusText@CProtoIntDlgBase@@QEAAXPEB_W@Z @73 NONAME +?UpdateProtoTitle@CProtoIntDlgBase@@AEAAXPEB_W@Z @74 NONAME +?UpdateStatusBar@CProtoIntDlgBase@@AEAAXXZ @75 NONAME +?UserIsTyping@PROTO_INTERFACE@@UEAAHIH@Z @76 NONAME +?WindowSubscribe@PROTO_INTERFACE@@QEAAXPEAUHWND__@@@Z @77 NONAME +?WindowUnsubscribe@PROTO_INTERFACE@@QEAAXPEAUHWND__@@@Z @78 NONAME +?debugLogA@PROTO_INTERFACE@@QEAAXPEBDZZ @79 NONAME +?debugLogW@PROTO_INTERFACE@@QEAAXPEB_WZZ @80 NONAME +?delSetting@PROTO_INTERFACE@@QEAA_JIPEBD@Z @81 NONAME +?delSetting@PROTO_INTERFACE@@QEAA_JPEBD@Z @82 NONAME +?getBool@PROTO_INTERFACE@@QEAA_NIPEBD_N@Z @83 NONAME +?getBool@PROTO_INTERFACE@@QEAA_NPEBD_N@Z @84 NONAME +?getByte@PROTO_INTERFACE@@QEAAHIPEBDE@Z @85 NONAME +?getByte@PROTO_INTERFACE@@QEAAHPEBDE@Z @86 NONAME +?getDword@PROTO_INTERFACE@@QEAAKIPEBDK@Z @87 NONAME +?getDword@PROTO_INTERFACE@@QEAAKPEBDK@Z @88 NONAME +?getString@PROTO_INTERFACE@@QEAA_JIPEBDPEAUDBVARIANT@@@Z @89 NONAME +?getString@PROTO_INTERFACE@@QEAA_JPEBDPEAUDBVARIANT@@@Z @90 NONAME +?getStringA@PROTO_INTERFACE@@QEAAPEADIPEBD@Z @91 NONAME +?getStringA@PROTO_INTERFACE@@QEAAPEADPEBD@Z @92 NONAME +?getWString@PROTO_INTERFACE@@QEAA_JIPEBDPEAUDBVARIANT@@@Z @93 NONAME +?getWString@PROTO_INTERFACE@@QEAA_JPEBDPEAUDBVARIANT@@@Z @94 NONAME +?getWStringA@PROTO_INTERFACE@@QEAAPEA_WIPEBD@Z @95 NONAME +?getWStringA@PROTO_INTERFACE@@QEAAPEA_WPEBD@Z @96 NONAME +?getWord@PROTO_INTERFACE@@QEAAHIPEBDG@Z @97 NONAME +?getWord@PROTO_INTERFACE@@QEAAHPEBDG@Z @98 NONAME +?isChatRoom@PROTO_INTERFACE@@QEAA_NI@Z @99 NONAME +?setByte@PROTO_INTERFACE@@QEAAXIPEBDE@Z @100 NONAME +?setByte@PROTO_INTERFACE@@QEAAXPEBDE@Z @101 NONAME +?setDword@PROTO_INTERFACE@@QEAAXIPEBDK@Z @102 NONAME +?setDword@PROTO_INTERFACE@@QEAAXPEBDK@Z @103 NONAME +?setString@PROTO_INTERFACE@@QEAAXIPEBD0@Z @104 NONAME +?setString@PROTO_INTERFACE@@QEAAXPEBD0@Z @105 NONAME +?setWString@PROTO_INTERFACE@@QEAAXIPEBDPEB_W@Z @106 NONAME +?setWString@PROTO_INTERFACE@@QEAAXPEBDPEB_W@Z @107 NONAME +?setWord@PROTO_INTERFACE@@QEAAXIPEBDG@Z @108 NONAME +?setWord@PROTO_INTERFACE@@QEAAXPEBDG@Z @109 NONAME +GetPluginLangByInstance @110 +ProtoBroadcastAck @111 +ProtoConstructor @112 +ProtoCreateHookableEvent @113 +ProtoCreateService @114 +ProtoCreateServiceParam @115 +ProtoDestructor @116 +ProtoForkThread @117 +ProtoForkThreadEx @118 +ProtoGetAvatarExtension @119 +ProtoGetAvatarFileFormat @120 +ProtoGetAvatarFormat @121 +ProtoGetBufferFormat @122 +ProtoHookEvent @123 +ProtoLogA @124 +ProtoLogW @125 +ProtoWindowAdd @126 +ProtoWindowRemove @127 +Proto_IsProtocolLoaded @128 diff --git a/src/mir_app/src/miranda.h b/src/mir_app/src/miranda.h index 174a79d2ca..ecd60c2211 100644 --- a/src/mir_app/src/miranda.h +++ b/src/mir_app/src/miranda.h @@ -143,6 +143,7 @@ void KillModuleMenus(int hLangpack); #define OFFSET_NAME 800 extern LIST accounts; +extern LIST protos; INT_PTR ProtoCallService(LPCSTR szModule, const char *szService, WPARAM wParam, LPARAM lParam); @@ -182,6 +183,4 @@ extern "C" MIR_CORE_DLL(int) Langpack_MarkPluginLoaded(PLUGININFOEX* pInfo); MIR_CORE_DLL(int) GetSubscribersCount(HANDLE hHook); MIR_CORE_DLL(void) db_setCurrent(MIDatabase* _db); - - MIR_CORE_DLL(PROTOCOLDESCRIPTOR*) Proto_RegisterModule(PROTOCOLDESCRIPTOR *pd); }; diff --git a/src/mir_app/src/proto_accs.cpp b/src/mir_app/src/proto_accs.cpp new file mode 100644 index 0000000000..6aa601dfbf --- /dev/null +++ b/src/mir_app/src/proto_accs.cpp @@ -0,0 +1,453 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org), +Copyright (c) 2000-12 Miranda IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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. +*/ + +#include "stdafx.h" + +#include "clc.h" + +bool CheckProtocolOrder(void); +void BuildProtoMenus(); + +HICON Proto_GetIcon(PROTO_INTERFACE *ppro, int iconIndex); + +static BOOL bModuleInitialized = FALSE; +static HANDLE hHooks[4]; + +static int CompareAccounts(const PROTOACCOUNT* p1, const PROTOACCOUNT* p2) +{ + return mir_strcmp(p1->szModuleName, p2->szModuleName); +} + +LIST accounts(10, CompareAccounts); + +///////////////////////////////////////////////////////////////////////////////////////// + +static int EnumDbModules(const char *szModuleName, DWORD, LPARAM) +{ + DBVARIANT dbv; + if (!db_get_s(NULL, szModuleName, "AM_BaseProto", &dbv)) { + if (!Proto_GetAccount(szModuleName)) { + PROTOACCOUNT *pa = (PROTOACCOUNT*)mir_calloc(sizeof(PROTOACCOUNT)); + pa->cbSize = sizeof(*pa); + pa->szModuleName = mir_strdup(szModuleName); + pa->szProtoName = mir_strdup(dbv.pszVal); + pa->tszAccountName = mir_a2t(szModuleName); + pa->bIsVisible = TRUE; + pa->bIsEnabled = FALSE; + pa->iOrder = accounts.getCount(); + accounts.insert(pa); + } + db_free(&dbv); + } + return 0; +} + +void LoadDbAccounts(void) +{ + DBVARIANT dbv; + int ver = db_get_dw(NULL, "Protocols", "PrVer", -1); + int count = db_get_dw(NULL, "Protocols", "ProtoCount", 0); + + for (int i = 0; i < count; i++) { + char buf[10]; + _itoa(i, buf, 10); + if (db_get_s(NULL, "Protocols", buf, &dbv)) + continue; + + PROTOACCOUNT *pa = (PROTOACCOUNT*)mir_calloc(sizeof(PROTOACCOUNT)); + if (pa == NULL) { + db_free(&dbv); + continue; + } + pa->cbSize = sizeof(*pa); + pa->szModuleName = mir_strdup(dbv.pszVal); + db_free(&dbv); + + _itoa(OFFSET_VISIBLE + i, buf, 10); + pa->bIsVisible = db_get_dw(NULL, "Protocols", buf, 1) != 0; + + _itoa(OFFSET_PROTOPOS + i, buf, 10); + pa->iOrder = db_get_dw(NULL, "Protocols", buf, 1); + + if (ver >= 4) { + db_free(&dbv); + _itoa(OFFSET_NAME + i, buf, 10); + if (!db_get_ts(NULL, "Protocols", buf, &dbv)) { + pa->tszAccountName = mir_tstrdup(dbv.ptszVal); + db_free(&dbv); + } + + _itoa(OFFSET_ENABLED + i, buf, 10); + pa->bIsEnabled = db_get_dw(NULL, "Protocols", buf, 1) != 0; + + if (!db_get_s(NULL, pa->szModuleName, "AM_BaseProto", &dbv)) { + pa->szProtoName = mir_strdup(dbv.pszVal); + db_free(&dbv); + } + } + else pa->bIsEnabled = true; + + if (!pa->szProtoName) { + pa->szProtoName = mir_strdup(pa->szModuleName); + db_set_s(NULL, pa->szModuleName, "AM_BaseProto", pa->szProtoName); + } + + if (!pa->tszAccountName) + pa->tszAccountName = mir_a2t(pa->szModuleName); + + accounts.insert(pa); + } + + if (CheckProtocolOrder()) + WriteDbAccounts(); + + int anum = accounts.getCount(); + CallService(MS_DB_MODULES_ENUM, 0, (LPARAM)EnumDbModules); + if (anum != accounts.getCount()) + WriteDbAccounts(); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + int arrlen; + char **pszSettingName; +} +enumDB_ProtoProcParam; + +static int enumDB_ProtoProc(const char* szSetting, LPARAM lParam) +{ + if (szSetting) { + enumDB_ProtoProcParam* p = (enumDB_ProtoProcParam*)lParam; + + p->arrlen++; + p->pszSettingName = (char**)mir_realloc(p->pszSettingName, p->arrlen*sizeof(char*)); + p->pszSettingName[p->arrlen - 1] = mir_strdup(szSetting); + } + return 0; +} + +void WriteDbAccounts() +{ + // enum all old settings to delete + enumDB_ProtoProcParam param = { 0, NULL }; + + DBCONTACTENUMSETTINGS dbces; + dbces.pfnEnumProc = enumDB_ProtoProc; + dbces.szModule = "Protocols"; + dbces.ofsSettings = 0; + dbces.lParam = (LPARAM)¶m; + CallService(MS_DB_CONTACT_ENUMSETTINGS, 0, (LPARAM)&dbces); + + // delete all settings + if (param.arrlen) { + for (int i = 0; i < param.arrlen; i++) { + db_unset(0, "Protocols", param.pszSettingName[i]); + mir_free(param.pszSettingName[i]); + } + mir_free(param.pszSettingName); + } + + // write new data + for (int i = 0; i < accounts.getCount(); i++) { + PROTOACCOUNT *pa = accounts[i]; + + char buf[20]; + _itoa(i, buf, 10); + db_set_s(NULL, "Protocols", buf, pa->szModuleName); + + _itoa(OFFSET_PROTOPOS + i, buf, 10); + db_set_dw(NULL, "Protocols", buf, pa->iOrder); + + _itoa(OFFSET_VISIBLE + i, buf, 10); + db_set_dw(NULL, "Protocols", buf, pa->bIsVisible); + + _itoa(OFFSET_ENABLED + i, buf, 10); + db_set_dw(NULL, "Protocols", buf, pa->bIsEnabled); + + _itoa(OFFSET_NAME + i, buf, 10); + db_set_ts(NULL, "Protocols", buf, pa->tszAccountName); + } + + db_unset(0, "Protocols", "ProtoCount"); + db_set_dw(0, "Protocols", "ProtoCount", accounts.getCount()); + db_set_dw(0, "Protocols", "PrVer", 4); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static int OnContactDeleted(WPARAM hContact, LPARAM lParam) +{ + if (hContact) { + PROTOACCOUNT *pa = Proto_GetAccount(hContact); + if (Proto_IsAccountEnabled(pa) && pa->ppro) + pa->ppro->OnEvent(EV_PROTO_ONCONTACTDELETED, hContact, lParam); + } + return 0; +} + +static int OnDbSettingsChanged(WPARAM hContact, LPARAM lParam) +{ + if (hContact) { + PROTOACCOUNT *pa = Proto_GetAccount(hContact); + if (Proto_IsAccountEnabled(pa) && pa->ppro) + pa->ppro->OnEvent(EV_PROTO_DBSETTINGSCHANGED, hContact, lParam); + } + return 0; +} + +static int InitializeStaticAccounts(WPARAM, LPARAM) +{ + int count = 0; + + for (int i = 0; i < accounts.getCount(); i++) { + PROTOACCOUNT *pa = accounts[i]; + if (!pa->ppro || !Proto_IsAccountEnabled(pa)) + continue; + + pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0); + + if (!pa->bOldProto) + count++; + } + + BuildProtoMenus(); + + if (count == 0 && !db_get_b(NULL, "FirstRun", "AccManager", 0)) { + db_set_b(NULL, "FirstRun", "AccManager", 1); + CallService(MS_PROTO_SHOWACCMGR, 0, 0); + } + // This is for pack creators with a profile with predefined accounts + else if (db_get_b(NULL, "FirstRun", "ForceShowAccManager", 0)) { + CallService(MS_PROTO_SHOWACCMGR, 0, 0); + db_unset(NULL, "FirstRun", "ForceShowAccManager"); + } + return 0; +} + +static int UninitializeStaticAccounts(WPARAM, LPARAM) +{ + for (int i = 0; i < accounts.getCount(); i++) { + PROTOACCOUNT *pa = accounts[i]; + if (pa->ppro && Proto_IsAccountEnabled(pa)) + if (pa->ppro->OnEvent(EV_PROTO_ONREADYTOEXIT, 0, 0) != TRUE) + return 1; + } + + for (int i = 0; i < accounts.getCount(); i++) { + PROTOACCOUNT *pa = accounts[i]; + if (pa->ppro && Proto_IsAccountEnabled(pa)) + pa->ppro->OnEvent(EV_PROTO_ONEXIT, 0, 0); + } + + return 0; +} + +int LoadAccountsModule(void) +{ + bModuleInitialized = TRUE; + + for (int i = 0; i < accounts.getCount(); i++) { + PROTOACCOUNT *pa = accounts[i]; + pa->bDynDisabled = !Proto_IsProtocolLoaded(pa->szProtoName); + if (pa->ppro) + continue; + + if (!Proto_IsAccountEnabled(pa)) + continue; + + if (!ActivateAccount(pa)) + pa->bDynDisabled = TRUE; + } + + hHooks[0] = HookEvent(ME_SYSTEM_MODULESLOADED, InitializeStaticAccounts); + hHooks[1] = HookEvent(ME_SYSTEM_PRESHUTDOWN, UninitializeStaticAccounts); + hHooks[2] = HookEvent(ME_DB_CONTACT_DELETED, OnContactDeleted); + hHooks[3] = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, OnDbSettingsChanged); + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static HANDLE CreateProtoServiceEx(const char* szModule, const char* szService, MIRANDASERVICEOBJ pFunc, void* param) +{ + char tmp[100]; + mir_snprintf(tmp, "%s%s", szModule, szService); + return CreateServiceFunctionObj(tmp, pFunc, param); +} + +BOOL ActivateAccount(PROTOACCOUNT *pa) +{ + PROTOCOLDESCRIPTOR* ppd = Proto_IsProtocolLoaded(pa->szProtoName); + if (ppd == NULL) + return FALSE; + + if (ppd->fnInit == NULL) + return FALSE; + + PROTO_INTERFACE *ppi = ppd->fnInit(pa->szModuleName, pa->tszAccountName); + if (ppi == NULL) + return FALSE; + + pa->ppro = ppi; + ppi->m_iDesiredStatus = ppi->m_iStatus = ID_STATUS_OFFLINE; + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +struct DeactivationThreadParam +{ + PROTO_INTERFACE *ppro; + pfnUninitProto fnUninit; + bool bIsDynamic, bErase; +}; + +pfnUninitProto GetProtocolDestructor(char *szProto); + +static int DeactivationThread(DeactivationThreadParam* param) +{ + PROTO_INTERFACE *p = (PROTO_INTERFACE*)param->ppro; + p->SetStatus(ID_STATUS_OFFLINE); + + char *szModuleName = NEWSTR_ALLOCA(p->m_szModuleName); + + if (param->bIsDynamic) { + while (p->OnEvent(EV_PROTO_ONREADYTOEXIT, 0, 0) != TRUE) + SleepEx(100, TRUE); + + p->OnEvent(EV_PROTO_ONEXIT, 0, 0); + } + + KillObjectThreads(p); // waits for them before terminating + KillObjectEventHooks(p); // untie an object from the outside world + + if (param->bErase) + p->OnEvent(EV_PROTO_ONERASE, 0, 0); + + if (param->fnUninit) + param->fnUninit(p); + + KillObjectServices(p); + + if (param->bErase) + EraseAccount(szModuleName); + + delete param; + return 0; +} + +void DeactivateAccount(PROTOACCOUNT *pa, bool bIsDynamic, bool bErase) +{ + if (pa->ppro == NULL) { + if (bErase) + EraseAccount(pa->szModuleName); + return; + } + + if (pa->hwndAccMgrUI) { + DestroyWindow(pa->hwndAccMgrUI); + pa->hwndAccMgrUI = NULL; + pa->bAccMgrUIChanged = FALSE; + } + + DeactivationThreadParam *param = new DeactivationThreadParam; + param->ppro = pa->ppro; + param->fnUninit = GetProtocolDestructor(pa->szProtoName); + param->bIsDynamic = bIsDynamic; + param->bErase = bErase; + pa->ppro = NULL; + if (bIsDynamic) + mir_forkthread((pThreadFunc)DeactivationThread, param); + else + DeactivationThread(param); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void EraseAccount(const char* pszModuleName) +{ + // remove protocol contacts first + for (MCONTACT hContact = db_find_first(pszModuleName); hContact != NULL;) { + MCONTACT hNext = db_find_next(hContact, pszModuleName); + CallService(MS_DB_CONTACT_DELETE, hContact, 0); + hContact = hNext; + } + + // remove all protocol settings + CallService(MS_DB_MODULE_DELETE, 0, (LPARAM)pszModuleName); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void UnloadAccount(PROTOACCOUNT *pa, bool bIsDynamic, bool bErase) +{ + DeactivateAccount(pa, bIsDynamic, bErase); + + mir_free(pa->tszAccountName); + mir_free(pa->szProtoName); + // szModuleName should be freed only on a program's exit. + // otherwise many plugins dependand on static protocol names will crash! + // do NOT fix this 'leak', please + if (!bIsDynamic) { + mir_free(pa->szModuleName); + mir_free(pa); + } +} + +void UnloadAccountsModule() +{ + if (!bModuleInitialized) return; + + for (int i = accounts.getCount() - 1; i >= 0; i--) { + PROTOACCOUNT *pa = accounts[i]; + UnloadAccount(pa, false, false); + accounts.remove(i); + } + accounts.destroy(); + + for (int i = 0; i < SIZEOF(hHooks); i++) + UnhookEvent(hHooks[i]); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void BuildProtoMenus() +{ + for (int i = 0; i < accounts.getCount(); i++) { + PROTOACCOUNT *pa = accounts[i]; + if (cli.pfnGetProtocolVisibility(pa->szModuleName) == 0) + continue; + + if (pa->ppro) + pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0); + } +} + +void RebuildProtoMenus() +{ + RebuildMenuOrder(); + BuildProtoMenus(); +} diff --git a/src/mir_app/src/proto_chains.cpp b/src/mir_app/src/proto_chains.cpp new file mode 100644 index 0000000000..e7f4348fe0 --- /dev/null +++ b/src/mir_app/src/proto_chains.cpp @@ -0,0 +1,253 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org), +Copyright (c) 2000-12 Miranda IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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. +*/ + +#include "stdafx.h" +#include + +extern LIST filters; + +static int GetProtocolP(MCONTACT hContact, char *szBuf, int cbLen) +{ + if (currDb == NULL) + return 1; + + DBCachedContact *cc = currDb->m_cache->GetCachedContact(hContact); + if (cc && cc->szProto != NULL) { + strncpy(szBuf, cc->szProto, cbLen); + szBuf[cbLen - 1] = 0; + return 0; + } + + DBVARIANT dbv; + dbv.type = DBVT_ASCIIZ; + dbv.pszVal = szBuf; + dbv.cchVal = cbLen; + + int res = currDb->GetContactSettingStatic(hContact, "Protocol", "p", &dbv); + if (res == 0) { + if (cc == NULL) + cc = currDb->m_cache->AddContactToCache(hContact); + + cc->szProto = currDb->m_cache->GetCachedSetting(NULL, szBuf, 0, (int)mir_strlen(szBuf)); + } + return res; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_APP_DLL(INT_PTR) CallContactService(MCONTACT hContact, const char *szProtoService, WPARAM wParam, LPARAM lParam) +{ + INT_PTR ret; + CCSDATA ccs = { hContact, szProtoService, wParam, lParam }; + + for (int i = 0; i < filters.getCount(); i++) { + if ((ret = CallProtoServiceInt(hContact, filters[i]->szName, szProtoService, i + 1, (LPARAM)&ccs)) != CALLSERVICE_NOTFOUND) { + //chain was started, exit + return ret; + } + } + + char szProto[40]; + if (GetProtocolP((MCONTACT)hContact, szProto, sizeof(szProto))) + return 1; + + PROTOACCOUNT *pa = Proto_GetAccount(szProto); + if (pa == NULL || pa->ppro == NULL) + return 1; + + if (pa->bOldProto) + ret = CallProtoServiceInt(hContact, szProto, szProtoService, (WPARAM)(-1), (LPARAM)&ccs); + else + ret = CallProtoServiceInt(hContact, szProto, szProtoService, wParam, lParam); + if (ret == CALLSERVICE_NOTFOUND) + ret = 1; + + return ret; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +INT_PTR Proto_CallContactService(WPARAM wParam, LPARAM lParam) +{ + CCSDATA *ccs = (CCSDATA*)lParam; + INT_PTR ret; + + if (wParam == (WPARAM)(-1)) + return 1; + + for (int i = wParam; i < filters.getCount(); i++) { + if ((ret = CallProtoServiceInt(NULL, filters[i]->szName, ccs->szProtoService, i + 1, lParam)) != CALLSERVICE_NOTFOUND) { + //chain was started, exit + return ret; + } + } + + char szProto[40]; + if (GetProtocolP((MCONTACT)ccs->hContact, szProto, sizeof(szProto))) + return 1; + + PROTOACCOUNT *pa = Proto_GetAccount(szProto); + if (pa == NULL || pa->ppro == NULL) + return 1; + + if (pa->bOldProto) + ret = CallProtoServiceInt(ccs->hContact, szProto, ccs->szProtoService, (WPARAM)(-1), (LPARAM)ccs); + else + ret = CallProtoServiceInt(ccs->hContact, szProto, ccs->szProtoService, ccs->wParam, ccs->lParam); + if (ret == CALLSERVICE_NOTFOUND) + ret = 1; + + return ret; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static INT_PTR Proto_RecvChain(WPARAM wParam, LPARAM lParam) +{ + CCSDATA *ccs = (CCSDATA*)lParam; + INT_PTR ret; + + if (wParam == (WPARAM)(-1)) return 1; //shouldn't happen - sanity check + if (wParam == 0) { //begin processing by finding end of chain + if (GetCurrentThreadId() != hMainThreadId) // restart this function in the main thread + return CallServiceSync(MS_PROTO_CHAINRECV, wParam, lParam); + + wParam = filters.getCount(); + } + else wParam--; + + for (int i = wParam - 1; i >= 0; i--) + if ((ret = CallProtoServiceInt(NULL, filters[i]->szName, ccs->szProtoService, i + 1, lParam)) != CALLSERVICE_NOTFOUND) + //chain was started, exit + return ret; + + //end of chain, call network protocol again + char szProto[40]; + if (GetProtocolP((MCONTACT)ccs->hContact, szProto, sizeof(szProto))) + return 1; + + PROTOACCOUNT *pa = Proto_GetAccount(szProto); + if (pa == NULL || pa->ppro == NULL) + return 1; + + if (pa->bOldProto) + ret = CallProtoServiceInt(ccs->hContact, szProto, ccs->szProtoService, (WPARAM)(-1), (LPARAM)ccs); + else + ret = CallProtoServiceInt(ccs->hContact, szProto, ccs->szProtoService, ccs->wParam, ccs->lParam); + if (ret == CALLSERVICE_NOTFOUND) + ret = 1; + + return ret; +} + +PROTOACCOUNT* __fastcall Proto_GetAccount(MCONTACT hContact) +{ + if (hContact == NULL) + return NULL; + + char szProto[40]; + if (GetProtocolP((MCONTACT)hContact, szProto, sizeof(szProto))) + return NULL; + + return Proto_GetAccount(szProto); +} + +static INT_PTR Proto_GetContactBaseProto(WPARAM wParam, LPARAM) +{ + PROTOACCOUNT *pa = Proto_GetAccount(wParam); + return (INT_PTR)(Proto_IsAccountEnabled(pa) ? pa->szModuleName : NULL); +} + +static INT_PTR Proto_GetContactBaseAccount(WPARAM wParam, LPARAM) +{ + PROTOACCOUNT *pa = Proto_GetAccount(wParam); + return (INT_PTR)(pa ? pa->szModuleName : NULL); +} + +static INT_PTR Proto_IsProtoOnContact(WPARAM wParam, LPARAM lParam) +{ + char *szProto = (char*)lParam; + if (szProto == NULL) + return 0; + + char szContactProto[40]; + if (!GetProtocolP(wParam, szContactProto, sizeof(szContactProto))) + if (!_stricmp(szProto, szContactProto)) + return -1; + + for (int i = 0; i < filters.getCount(); i++) + if (!mir_strcmp(szProto, filters[i]->szName)) + return i + 1; + + return 0; +} + +static INT_PTR Proto_AddToContact(WPARAM wParam, LPARAM lParam) +{ + char *szProto = (char*)lParam; + PROTOCOLDESCRIPTOR *pd = Proto_IsProtocolLoaded(szProto); + if (pd == NULL) { + PROTOACCOUNT *pa = Proto_GetAccount(szProto); + if (pa) { + db_set_s(wParam, "Protocol", "p", szProto); + return 0; + } + return 1; + } + + if (pd->type == PROTOTYPE_PROTOCOL || pd->type == PROTOTYPE_VIRTUAL) + db_set_s(wParam, "Protocol", "p", szProto); + + return 0; +} + +static INT_PTR Proto_RemoveFromContact(WPARAM wParam, LPARAM lParam) +{ + switch (Proto_IsProtoOnContact(wParam, lParam)) { + case 0: + return 1; + case -1: + db_unset(wParam, "Protocol", "p"); + } + + return 0; +} + +int LoadProtoChains(void) +{ + if (!db_get_b(NULL, "Compatibility", "Filters", 0)) { + CallService(MS_DB_MODULE_DELETE, 0, (LPARAM)"_Filters"); + db_set_b(NULL, "Compatibility", "Filters", 1); + } + + CreateServiceFunction(MS_PROTO_CALLCONTACTSERVICE, Proto_CallContactService); + CreateServiceFunction(MS_PROTO_CHAINSEND, Proto_CallContactService); + CreateServiceFunction(MS_PROTO_CHAINRECV, Proto_RecvChain); + CreateServiceFunction(MS_PROTO_GETCONTACTBASEPROTO, Proto_GetContactBaseProto); + CreateServiceFunction(MS_PROTO_GETCONTACTBASEACCOUNT, Proto_GetContactBaseAccount); + CreateServiceFunction(MS_PROTO_ISPROTOONCONTACT, Proto_IsProtoOnContact); + CreateServiceFunction(MS_PROTO_ADDTOCONTACT, Proto_AddToContact); + CreateServiceFunction(MS_PROTO_REMOVEFROMCONTACT, Proto_RemoveFromContact); + return 0; +} diff --git a/src/mir_app/src/proto_internal.cpp b/src/mir_app/src/proto_internal.cpp new file mode 100644 index 0000000000..c440c5c22d --- /dev/null +++ b/src/mir_app/src/proto_internal.cpp @@ -0,0 +1,304 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org), +Copyright (c) 2000-12 Miranda IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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. +*/ + +#include "stdafx.h" + +char** __fastcall Proto_FilesMatrixA(TCHAR **files); + +void FreeFilesMatrix(TCHAR ***files) +{ + if (*files == NULL) + return; + + // Free each filename in the pointer array + TCHAR **pFile = *files; + while (*pFile != NULL) { + mir_free(*pFile); + *pFile = NULL; + pFile++; + } + + // Free the array itself + mir_free(*files); + *files = NULL; +} + +struct DEFAULT_PROTO_INTERFACE : public PROTO_INTERFACE +{ + MCONTACT __cdecl AddToList(int flags, PROTOSEARCHRESULT *psr) + { + return (MCONTACT)ProtoCallService(m_szModuleName, PS_ADDTOLIST, flags, (LPARAM)psr); + } + + MCONTACT __cdecl AddToListByEvent(int flags, int iContact, MEVENT hDbEvent) + { + return (MCONTACT)ProtoCallService(m_szModuleName, PS_ADDTOLISTBYEVENT, MAKELONG(flags, iContact), hDbEvent); + } + + int __cdecl Authorize(MEVENT hDbEvent) + { + return (int)ProtoCallService(m_szModuleName, PS_AUTHALLOW, (WPARAM)hDbEvent, 0); + } + + int __cdecl AuthDeny(MEVENT hDbEvent, const TCHAR *szReason) + { + if (m_iVersion > 1) + return (int)ProtoCallService(m_szModuleName, PS_AUTHDENY, hDbEvent, (LPARAM)szReason); + + return (int)ProtoCallService(m_szModuleName, PS_AUTHDENY, hDbEvent, _T2A(szReason)); + } + + int __cdecl AuthRecv(MCONTACT hContact, PROTORECVEVENT *evt) + { + CCSDATA ccs = { hContact, PSR_AUTH, 0, (LPARAM)evt }; + return (int)ProtoCallService(m_szModuleName, PSR_AUTH, 0, (LPARAM)&ccs); + } + + int __cdecl AuthRequest(MCONTACT hContact, const TCHAR *szMessage) + { + CCSDATA ccs = { hContact, PSS_AUTHREQUEST, 0, (LPARAM)szMessage }; + if (m_iVersion > 1) + return (int)ProtoCallService(m_szModuleName, PSS_AUTHREQUEST, 0, (LPARAM)&ccs); + + ccs.lParam = (LPARAM)mir_t2a(szMessage); + int res = (int)ProtoCallService(m_szModuleName, PSS_AUTHREQUEST, 0, (LPARAM)&ccs); + mir_free((char*)ccs.lParam); + return res; + } + + HANDLE __cdecl FileAllow(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szPath) + { + CCSDATA ccs = { hContact, PSS_FILEALLOW, (WPARAM)hTransfer, (LPARAM)szPath }; + if (m_iVersion > 1) + return (HANDLE)ProtoCallService(m_szModuleName, PSS_FILEALLOW, 0, (LPARAM)&ccs); + + ccs.lParam = (LPARAM)mir_t2a(szPath); + HANDLE res = (HANDLE)ProtoCallService(m_szModuleName, PSS_FILEALLOW, 0, (LPARAM)&ccs); + mir_free((char*)ccs.lParam); + return res; + } + + int __cdecl FileCancel(MCONTACT hContact, HANDLE hTransfer) + { + CCSDATA ccs = { hContact, PSS_FILECANCEL, (WPARAM)hTransfer, 0 }; + return (int)ProtoCallService(m_szModuleName, PSS_FILECANCEL, 0, (LPARAM)&ccs); + } + + int __cdecl FileDeny(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szReason) + { + CCSDATA ccs = { hContact, PSS_FILEDENY, (WPARAM)hTransfer, (LPARAM)szReason }; + if (m_iVersion > 1) + return (int)ProtoCallService(m_szModuleName, PSS_FILEDENY, 0, (LPARAM)&ccs); + + ccs.lParam = (LPARAM)mir_t2a(szReason); + int res = (int)ProtoCallService(m_szModuleName, PSS_FILEDENY, 0, (LPARAM)&ccs); + mir_free((char*)ccs.lParam); + return res; + } + + int __cdecl FileResume(HANDLE hTransfer, int* action, const TCHAR** szFilename) + { + PROTOFILERESUME pfr = { *action, *szFilename }; + if (m_iVersion > 1) + return (int)ProtoCallService(m_szModuleName, PS_FILERESUME, (WPARAM)hTransfer, (LPARAM)&pfr); + + pfr.szFilename = (TCHAR*)mir_t2a(pfr.szFilename); + int res = (int)ProtoCallService(m_szModuleName, PS_FILERESUME, (WPARAM)hTransfer, (LPARAM)&pfr); + mir_free((TCHAR*)*szFilename); + *action = pfr.action; *szFilename = (TCHAR*)pfr.szFilename; + + return res; + } + + DWORD_PTR __cdecl GetCaps(int type, MCONTACT hContact) + { + return (DWORD_PTR)ProtoCallService(m_szModuleName, PS_GETCAPS, type, hContact); + } + + HICON __cdecl GetIcon(int iconIndex) + { + return (HICON)ProtoCallService(m_szModuleName, PS_LOADICON, iconIndex, 0); + } + + int __cdecl GetInfo(MCONTACT hContact, int flags) + { + CCSDATA ccs = { hContact, PSS_GETINFO, flags, 0 }; + return ProtoCallService(m_szModuleName, PSS_GETINFO, 0, (LPARAM)&ccs); + } + + HANDLE __cdecl SearchBasic(const TCHAR* id) + { + if (m_iVersion > 1) + return (HANDLE)ProtoCallService(m_szModuleName, PS_BASICSEARCH, 0, (LPARAM)id); + + return (HANDLE)ProtoCallService(m_szModuleName, PS_BASICSEARCH, 0, _T2A(id)); + } + + HANDLE __cdecl SearchByEmail(const TCHAR* email) + { + if (m_iVersion > 1) + return (HANDLE)ProtoCallService(m_szModuleName, PS_SEARCHBYEMAIL, 0, (LPARAM)email); + return (HANDLE)ProtoCallService(m_szModuleName, PS_SEARCHBYEMAIL, 0, _T2A(email)); + } + + HANDLE __cdecl SearchByName(const TCHAR* nick, const TCHAR* firstName, const TCHAR* lastName) + { + PROTOSEARCHBYNAME psn; + psn.pszNick = (TCHAR*)mir_t2a(nick); + psn.pszFirstName = (TCHAR*)mir_t2a(firstName); + psn.pszLastName = (TCHAR*)mir_t2a(lastName); + HANDLE res = (HANDLE)ProtoCallService(m_szModuleName, PS_SEARCHBYNAME, 0, (LPARAM)&psn); + mir_free(psn.pszNick); + mir_free(psn.pszFirstName); + mir_free(psn.pszLastName); + return res; + + } + + HWND __cdecl SearchAdvanced(HWND owner) + { + return (HWND)ProtoCallService(m_szModuleName, PS_SEARCHBYADVANCED, 0, (LPARAM)owner); + } + + HWND __cdecl CreateExtendedSearchUI(HWND owner) + { + return (HWND)ProtoCallService(m_szModuleName, PS_CREATEADVSEARCHUI, 0, (LPARAM)owner); + } + + int __cdecl RecvContacts(MCONTACT hContact, PROTORECVEVENT* evt) + { + CCSDATA ccs = { hContact, PSR_CONTACTS, 0, (LPARAM)evt }; + return (int)ProtoCallService(m_szModuleName, PSR_CONTACTS, 0, (LPARAM)&ccs); + } + + int __cdecl RecvFile(MCONTACT hContact, PROTORECVFILET* evt) + { + CCSDATA ccs = { hContact, PSR_FILE, 0, (LPARAM)evt }; + return ProtoCallService(m_szModuleName, PSR_FILE, 0, (LPARAM)&ccs); + } + + int __cdecl RecvMsg(MCONTACT hContact, PROTORECVEVENT* evt) + { + CCSDATA ccs = { hContact, PSR_MESSAGE, 0, (LPARAM)evt }; + return (int)ProtoCallService(m_szModuleName, PSR_MESSAGE, 0, (LPARAM)&ccs); + } + + int __cdecl RecvUrl(MCONTACT hContact, PROTORECVEVENT* evt) + { + CCSDATA ccs = { hContact, PSR_URL, 0, (LPARAM)evt }; + return (int)ProtoCallService(m_szModuleName, PSR_URL, 0, (LPARAM)&ccs); + } + + int __cdecl SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList) + { + CCSDATA ccs = { hContact, PSS_CONTACTS, MAKEWPARAM(flags, nContacts), (LPARAM)hContactsList }; + return (int)ProtoCallService(m_szModuleName, PSS_CONTACTS, 0, (LPARAM)&ccs); + } + + HANDLE __cdecl SendFile(MCONTACT hContact, const TCHAR* szDescription, TCHAR** ppszFiles) + { + CCSDATA ccs = { hContact, PSS_FILE, (WPARAM)szDescription, (LPARAM)ppszFiles }; + + if (m_iVersion > 1) + return (HANDLE)ProtoCallService(m_szModuleName, PSS_FILE, 0, (LPARAM)&ccs); + + ccs.wParam = (WPARAM)mir_t2a(szDescription); + ccs.lParam = (LPARAM)Proto_FilesMatrixA(ppszFiles); + HANDLE res = (HANDLE)ProtoCallService(m_szModuleName, PSS_FILE, 0, (LPARAM)&ccs); + if (res == 0) FreeFilesMatrix((TCHAR***)&ccs.lParam); + mir_free((char*)ccs.wParam); + return res; + } + + int __cdecl SendMsg(MCONTACT hContact, const char* msg) + { + CCSDATA ccs = { hContact, PSS_MESSAGE, 0, (LPARAM)msg }; + return (int)ProtoCallService(m_szModuleName, PSS_MESSAGE, 0, (LPARAM)&ccs); + } + + int __cdecl SendUrl(MCONTACT hContact, int flags, const char* url) + { + CCSDATA ccs = { hContact, PSS_URL, flags, (LPARAM)url }; + return (int)ProtoCallService(m_szModuleName, PSS_URL, 0, (LPARAM)&ccs); + } + + int __cdecl SetApparentMode(MCONTACT hContact, int mode) + { + CCSDATA ccs = { hContact, PSS_SETAPPARENTMODE, mode, 0 }; + return (int)ProtoCallService(m_szModuleName, PSS_SETAPPARENTMODE, 0, (LPARAM)&ccs); + } + + int __cdecl SetStatus(int iNewStatus) + { + return (int)ProtoCallService(m_szModuleName, PS_SETSTATUS, iNewStatus, 0); + } + + HANDLE __cdecl GetAwayMsg(MCONTACT hContact) + { + CCSDATA ccs = { hContact, PSS_GETAWAYMSG, 0, 0 }; + return (HANDLE)ProtoCallService(m_szModuleName, PSS_GETAWAYMSG, 0, (LPARAM)&ccs); + } + + int __cdecl RecvAwayMsg(MCONTACT hContact, int statusMode, PROTORECVEVENT* evt) + { + CCSDATA ccs = { hContact, PSR_AWAYMSG, statusMode, (LPARAM)evt }; + return (int)ProtoCallService(m_szModuleName, PSR_AWAYMSG, 0, (LPARAM)&ccs); + } + + int __cdecl SetAwayMsg(int iStatus, const TCHAR *msg) + { + if (m_iVersion > 1) + return (int)ProtoCallService(m_szModuleName, PS_SETAWAYMSG, iStatus, (LPARAM)msg); + return (int)ProtoCallService(m_szModuleName, PS_SETAWAYMSG, iStatus, _T2A(msg)); + } + + int __cdecl UserIsTyping(MCONTACT hContact, int type) + { + CCSDATA ccs = { hContact, PSS_USERISTYPING, hContact, type }; + return ProtoCallService(m_szModuleName, PSS_USERISTYPING, 0, (LPARAM)&ccs); + } + + int __cdecl OnEvent(PROTOEVENTTYPE, WPARAM, LPARAM) + { + return 1; + } +}; + +// creates the default protocol container for compatibility with the old plugins + +PROTO_INTERFACE* AddDefaultAccount(const char *szProtoName) +{ + PROTO_INTERFACE* ppi = new DEFAULT_PROTO_INTERFACE; + ppi->m_szModuleName = mir_strdup(szProtoName); + ppi->m_tszUserName = mir_a2t(szProtoName); + return ppi; +} + +int FreeDefaultAccount(PROTO_INTERFACE* ppi) +{ + mir_free(ppi->m_szModuleName); + mir_free(ppi->m_tszUserName); + delete ppi; + return 0; +} diff --git a/src/mir_app/src/proto_opts.cpp b/src/mir_app/src/proto_opts.cpp new file mode 100644 index 0000000000..6d042b30cc --- /dev/null +++ b/src/mir_app/src/proto_opts.cpp @@ -0,0 +1,1062 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org), +Copyright (c) 2000-12 Miranda IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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. +*/ + +#include "stdafx.h" + +#define LBN_MY_CHECK 0x1000 +#define LBN_MY_RENAME 0x1001 + +#define WM_MY_REFRESH (WM_USER+0x1000) +#define WM_MY_RENAME (WM_USER+0x1001) + +bool CheckProtocolOrder(void); + +#define errMsg \ +TranslateT("WARNING! The account is going to be deleted. It means that all its \ +settings, contacts and histories will be also erased.\n\n\ +Are you absolutely sure?") + +#define upgradeMsg \ +TranslateT("Your account was successfully upgraded. \ +To activate it, restart of Miranda is needed.\n\n\ +If you want to restart Miranda now, press Yes, if you want to upgrade another account, press No") +// is upgradeMsg in use in any place? +#define legacyMsg \ +TranslateT("This account uses legacy protocol plugin. \ +Use Miranda NG options dialogs to change its preferences.") + +#define welcomeMsg \ +TranslateT("Welcome to Miranda NG's account manager!\n\ +Here you can set up your IM accounts.\n\n\ +Select an account from the list on the left to see the available options. \ +Alternatively, just click on the Plus sign underneath the list to set up a new IM account.") + +static HWND hAccMgr = NULL; + +extern HANDLE hAccListChanged; + +int UnloadPlugin(TCHAR* buf, int bufLen); + +PROTOACCOUNT* Proto_CreateAccount(const char *szModuleName, const char *szBaseProto, const TCHAR *tszAccountName) +{ + PROTOACCOUNT *pa = (PROTOACCOUNT*)mir_calloc(sizeof(PROTOACCOUNT)); + if (pa == NULL) + return NULL; + + pa->cbSize = sizeof(PROTOACCOUNT); + pa->bIsEnabled = pa->bIsVisible = true; + pa->iOrder = accounts.getCount(); + pa->szProtoName = mir_strdup(szBaseProto); + + // if the internal name is empty, generate new one + if (mir_strlen(szModuleName) == 0) { + char buf[100]; + int count = 1; + while (true) { + mir_snprintf(buf, "%s_%d", szBaseProto, count++); + if (ptrA(db_get_sa(NULL, buf, "AM_BaseProto")) == NULL) + break; + } + pa->szModuleName = mir_strdup(buf); + } + else pa->szModuleName = mir_strdup(szModuleName); + + pa->tszAccountName = mir_tstrdup(tszAccountName); + + db_set_s(NULL, pa->szModuleName, "AM_BaseProto", szBaseProto); + accounts.insert(pa); + + if (ActivateAccount(pa)) { + pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0); + if (!db_get_b(NULL, "CList", "MoveProtoMenus", true)) + pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0); + } + + return pa; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Account edit form +// Gets PROTOACCOUNT* as a parameter, or NULL to edit a new one + +struct AccFormDlgParam +{ + int action; + PROTOACCOUNT *pa; +}; + +static bool FindAccountByName(const char *szModuleName) +{ + if (!mir_strlen(szModuleName)) + return false; + + for (int i = 0; i < accounts.getCount(); i++) + if (_stricmp(szModuleName, accounts[i]->szModuleName) == 0) + return true; + + return false; +} + +static bool OnCreateAccount(HWND hwndDlg) +{ + AccFormDlgParam* param = (AccFormDlgParam*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + PROTOACCOUNT *pa = param->pa; + + TCHAR tszAccName[256]; + GetDlgItemText(hwndDlg, IDC_ACCNAME, tszAccName, SIZEOF(tszAccName)); + rtrimt(tszAccName); + if (tszAccName[0] == 0) { + MessageBox(hwndDlg, TranslateT("Account name must be filled."), TranslateT("Account error"), MB_ICONERROR | MB_OK); + return false; + } + + if (param->action == PRAC_ADDED) { + char buf[200]; + GetDlgItemTextA(hwndDlg, IDC_ACCINTERNALNAME, buf, SIZEOF(buf)); + if (FindAccountByName(rtrim(buf))) { + MessageBox(hwndDlg, TranslateT("Account name has to be unique. Please enter unique name."), TranslateT("Account error"), MB_ICONERROR | MB_OK); + return false; + } + } + + if (param->action == PRAC_UPGRADED) { + BOOL oldProto = pa->bOldProto; + TCHAR szPlugin[MAX_PATH]; + mir_sntprintf(szPlugin, SIZEOF(szPlugin), _T("%s.dll"), _A2T(pa->szProtoName)); + int idx = accounts.getIndex(pa); + UnloadAccount(pa, false, false); + accounts.remove(idx); + if (oldProto && UnloadPlugin(szPlugin, SIZEOF(szPlugin))) { + TCHAR szNewName[MAX_PATH]; + mir_sntprintf(szNewName, SIZEOF(szNewName), _T("%s~"), szPlugin); + MoveFile(szPlugin, szNewName); + } + param->action = PRAC_ADDED; + } + + if (param->action == PRAC_ADDED) { + char buf[200]; + GetDlgItemTextA(hwndDlg, IDC_PROTOTYPECOMBO, buf, SIZEOF(buf)); + char *szBaseProto = NEWSTR_ALLOCA(buf); + + GetDlgItemTextA(hwndDlg, IDC_ACCINTERNALNAME, buf, SIZEOF(buf)); + rtrim(buf); + + pa = Proto_CreateAccount(buf, szBaseProto, tszAccName); + } + else replaceStrT(pa->tszAccountName, tszAccName); + + WriteDbAccounts(); + NotifyEventHooks(hAccListChanged, param->action, (LPARAM)pa); + + SendMessage(GetParent(hwndDlg), WM_MY_REFRESH, 0, 0); + return true; +} + +static INT_PTR CALLBACK AccFormDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + { + PROTOCOLDESCRIPTOR **proto; + int protoCount, i, cnt = 0; + CallService(MS_PROTO_ENUMPROTOS, (WPARAM)&protoCount, (LPARAM)&proto); + for (i = 0; i < protoCount; i++) { + PROTOCOLDESCRIPTOR* pd = proto[i]; + if (pd->type == PROTOTYPE_PROTOCOL && pd->cbSize == sizeof(*pd)) { + SendDlgItemMessageA(hwndDlg, IDC_PROTOTYPECOMBO, CB_ADDSTRING, 0, (LPARAM)proto[i]->szName); + ++cnt; + } + } + SendDlgItemMessage(hwndDlg, IDC_PROTOTYPECOMBO, CB_SETCURSEL, 0, 0); + EnableWindow(GetDlgItem(hwndDlg, IDOK), cnt != 0); + + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); + AccFormDlgParam* param = (AccFormDlgParam*)lParam; + + if (param->action == PRAC_ADDED) // new account + SetWindowText(hwndDlg, TranslateT("Create new account")); + else { + TCHAR str[200]; + if (param->action == PRAC_CHANGED) { // update + EnableWindow(GetDlgItem(hwndDlg, IDC_PROTOTYPECOMBO), FALSE); + mir_sntprintf(str, SIZEOF(str), _T("%s: %s"), TranslateT("Editing account"), param->pa->tszAccountName); + } + else mir_sntprintf(str, SIZEOF(str), _T("%s: %s"), TranslateT("Upgrading account"), param->pa->tszAccountName); + + SetWindowText(hwndDlg, str); + SetDlgItemText(hwndDlg, IDC_ACCNAME, param->pa->tszAccountName); + SetDlgItemTextA(hwndDlg, IDC_ACCINTERNALNAME, param->pa->szModuleName); + SendDlgItemMessageA(hwndDlg, IDC_PROTOTYPECOMBO, CB_SELECTSTRING, -1, (LPARAM)param->pa->szProtoName); + + EnableWindow(GetDlgItem(hwndDlg, IDC_ACCINTERNALNAME), FALSE); + } + SendDlgItemMessage(hwndDlg, IDC_ACCINTERNALNAME, EM_LIMITTEXT, 40, 0); + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + if (OnCreateAccount(hwndDlg)) + EndDialog(hwndDlg, TRUE); + break; + + case IDCANCEL: + EndDialog(hwndDlg, FALSE); + break; + } + } + + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Accounts manager + +struct TAccMgrData +{ + HFONT hfntTitle, hfntText; + int titleHeight, textHeight; + int selectedHeight, normalHeight; + int iSelected; +}; + +struct TAccListData +{ + int iItem; + RECT rcCheck; + HWND hwndEdit; +}; + +static void sttClickButton(HWND hwndDlg, int idcButton) +{ + if (IsWindowEnabled(GetDlgItem(hwndDlg, idcButton))) + PostMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(idcButton, BN_CLICKED), (LPARAM)GetDlgItem(hwndDlg, idcButton)); +} + +static LRESULT CALLBACK sttEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_KEYDOWN: + switch (wParam) { + case VK_RETURN: + DestroyWindow(hwnd); + return 0; + + case VK_ESCAPE: + SetWindowLongPtr(hwnd, GWLP_WNDPROC, GetWindowLongPtr(hwnd, GWLP_USERDATA)); + DestroyWindow(hwnd); + return 0; + } + break; + + case WM_GETDLGCODE: + if (wParam == VK_RETURN || wParam == VK_ESCAPE) + return DLGC_WANTMESSAGE; + break; + + case WM_KILLFOCUS: + int length = GetWindowTextLength(hwnd) + 1; + TCHAR *str = (TCHAR*)mir_alloc(sizeof(TCHAR) * length); + GetWindowText(hwnd, str, length); + SendMessage(GetParent(GetParent(hwnd)), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(GetParent(hwnd), GWL_ID), LBN_MY_RENAME), (LPARAM)str); + DestroyWindow(hwnd); + return 0; + } + return mir_callNextSubclass(hwnd, sttEditSubclassProc, msg, wParam, lParam); +} + +static LRESULT CALLBACK AccListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + struct TAccListData *dat = (struct TAccListData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); + if (!dat) + return DefWindowProc(hwnd, msg, wParam, lParam); + + switch (msg) { + case WM_LBUTTONDOWN: + { + POINT pt = { LOWORD(lParam), HIWORD(lParam) }; + int iItem = LOWORD(SendMessage(hwnd, LB_ITEMFROMPOINT, 0, lParam)); + ListBox_GetItemRect(hwnd, iItem, &dat->rcCheck); + + dat->rcCheck.right = dat->rcCheck.left + g_iIconSX + 4; + dat->rcCheck.bottom = dat->rcCheck.top + g_iIconSY + 4; + if (PtInRect(&dat->rcCheck, pt)) + dat->iItem = iItem; + else + dat->iItem = -1; + } + break; + + case WM_LBUTTONUP: + { + POINT pt = { LOWORD(lParam), HIWORD(lParam) }; + if ((dat->iItem >= 0) && PtInRect(&dat->rcCheck, pt)) + PostMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(hwnd, GWL_ID), LBN_MY_CHECK), (LPARAM)dat->iItem); + dat->iItem = -1; + } + break; + + case WM_CHAR: + if (wParam == ' ') { + int iItem = ListBox_GetCurSel(hwnd); + if (iItem >= 0) + PostMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(hwnd, GWL_ID), LBN_MY_CHECK), (LPARAM)iItem); + return 0; + } + + if (wParam == 10 /* enter */) + return 0; + + break; + + case WM_GETDLGCODE: + if (wParam == VK_RETURN) + return DLGC_WANTMESSAGE; + break; + + case WM_MY_RENAME: + RECT rc; + { + struct TAccMgrData *parentDat = (struct TAccMgrData *)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); + PROTOACCOUNT *pa = (PROTOACCOUNT *)ListBox_GetItemData(hwnd, ListBox_GetCurSel(hwnd)); + if (!pa || pa->bOldProto || pa->bDynDisabled) + return 0; + + ListBox_GetItemRect(hwnd, ListBox_GetCurSel(hwnd), &rc); + rc.left += 2 * g_iIconSX + 4; + rc.bottom = rc.top + max(g_iIconSX, parentDat->titleHeight) + 4 - 1; + ++rc.top; --rc.right; + + dat->hwndEdit = CreateWindow(_T("EDIT"), pa->tszAccountName, WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hwnd, NULL, g_hInst, NULL); + mir_subclassWindow(dat->hwndEdit, sttEditSubclassProc); + SendMessage(dat->hwndEdit, WM_SETFONT, (WPARAM)parentDat->hfntTitle, 0); + SendMessage(dat->hwndEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN | EC_USEFONTINFO, 0); + SendMessage(dat->hwndEdit, EM_SETSEL, 0, -1); + ShowWindow(dat->hwndEdit, SW_SHOW); + } + SetFocus(dat->hwndEdit); + break; + + case WM_KEYDOWN: + switch (wParam) { + case VK_F2: + PostMessage(hwnd, WM_MY_RENAME, 0, 0); + return 0; + + case VK_INSERT: + sttClickButton(GetParent(hwnd), IDC_ADD); + return 0; + + case VK_DELETE: + sttClickButton(GetParent(hwnd), IDC_REMOVE); + return 0; + + case VK_RETURN: + if (GetAsyncKeyState(VK_CONTROL)) + sttClickButton(GetParent(hwnd), IDC_EDIT); + else + sttClickButton(GetParent(hwnd), IDOK); + return 0; + } + break; + } + + return mir_callNextSubclass(hwnd, AccListWndProc, msg, wParam, lParam); +} + +static void sttSubclassAccList(HWND hwnd, BOOL subclass) +{ + if (subclass) { + struct TAccListData *dat = (struct TAccListData *)mir_alloc(sizeof(struct TAccListData)); + dat->iItem = -1; + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)dat); + mir_subclassWindow(hwnd, AccListWndProc); + } + else { + struct TAccListData *dat = (struct TAccListData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); + SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); + mir_free(dat); + } +} + +static void sttSelectItem(struct TAccMgrData *dat, HWND hwndList, int iItem) +{ + if ((dat->iSelected != iItem) && (dat->iSelected >= 0)) + ListBox_SetItemHeight(hwndList, dat->iSelected, dat->normalHeight); + + dat->iSelected = iItem; + ListBox_SetItemHeight(hwndList, dat->iSelected, dat->selectedHeight); + RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); +} + +static void sttUpdateAccountInfo(HWND hwndDlg, struct TAccMgrData *dat) +{ + HWND hwndList = GetDlgItem(hwndDlg, IDC_ACCLIST); + int curSel = ListBox_GetCurSel(hwndList); + if (curSel != LB_ERR) { + PROTOACCOUNT *pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, curSel); + if (pa) { + EnableWindow(GetDlgItem(hwndDlg, IDC_UPGRADE), pa->bOldProto || pa->bDynDisabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), !pa->bOldProto && !pa->bDynDisabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTIONS), pa->ppro != 0); + + if (dat->iSelected >= 0) { + PROTOACCOUNT *pa_old = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, dat->iSelected); + if (pa_old && pa_old != pa && pa_old->hwndAccMgrUI) + ShowWindow(pa_old->hwndAccMgrUI, SW_HIDE); + } + + if (pa->hwndAccMgrUI) { + ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_HIDE); + ShowWindow(pa->hwndAccMgrUI, SW_SHOW); + } + else if (!pa->ppro) { + ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_SHOW); + SetDlgItemText(hwndDlg, IDC_TXT_INFO, TranslateT("Account is disabled. Please activate it to access options.")); + } + else { + HWND hwnd = (HWND)CallProtoService(pa->szModuleName, PS_CREATEACCMGRUI, 0, (LPARAM)hwndDlg); + if (hwnd && (hwnd != (HWND)CALLSERVICE_NOTFOUND)) { + RECT rc; + + ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_HIDE); + + GetWindowRect(GetDlgItem(hwndDlg, IDC_TXT_INFO), &rc); + MapWindowPoints(NULL, hwndDlg, (LPPOINT)&rc, 2); + SetWindowPos(hwnd, hwndList, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); + + pa->hwndAccMgrUI = hwnd; + } + else { + ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_SHOW); + SetDlgItemText(hwndDlg, IDC_TXT_INFO, legacyMsg); + } + } + return; + } + } + + EnableWindow(GetDlgItem(hwndDlg, IDC_UPGRADE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTIONS), FALSE); + + ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_SHOW); + SetDlgItemText(hwndDlg, IDC_TXT_INFO, welcomeMsg); +} + +INT_PTR CALLBACK AccMgrDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + struct TAccMgrData *dat = (struct TAccMgrData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + HWND hwndList = GetDlgItem(hwndDlg, IDC_ACCLIST); + PROTOACCOUNT *pa; + int idx; + PSHNOTIFY pshn; + + switch (message) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + Window_SetIcon_IcoLib(hwndDlg, SKINICON_OTHER_ACCMGR); + + dat = (TAccMgrData *)mir_alloc(sizeof(TAccMgrData)); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); + + Button_SetIcon_IcoLib(hwndDlg, IDC_ADD, SKINICON_OTHER_ADDCONTACT, LPGEN("New account")); + Button_SetIcon_IcoLib(hwndDlg, IDC_EDIT, SKINICON_OTHER_RENAME, LPGEN("Edit")); + Button_SetIcon_IcoLib(hwndDlg, IDC_REMOVE, SKINICON_OTHER_DELETE, LPGEN("Remove account")); + Button_SetIcon_IcoLib(hwndDlg, IDC_OPTIONS, SKINICON_OTHER_OPTIONS, LPGEN("Configure...")); + Button_SetIcon_IcoLib(hwndDlg, IDC_UPGRADE, SKINICON_OTHER_ACCMGR, LPGEN("Upgrade account")); + + EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTIONS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_UPGRADE), FALSE); + { + LOGFONT lf; + GetObject((HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0), sizeof(lf), &lf); + dat->hfntText = CreateFontIndirect(&lf); + + GetObject((HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0), sizeof(lf), &lf); + lf.lfWeight = FW_BOLD; + dat->hfntTitle = CreateFontIndirect(&lf); + + HDC hdc = GetDC(hwndDlg); + HFONT hfnt = (HFONT)SelectObject(hdc, dat->hfntTitle); + + TEXTMETRIC tm; + GetTextMetrics(hdc, &tm); + dat->titleHeight = tm.tmHeight; + SelectObject(hdc, dat->hfntText); + + GetTextMetrics(hdc, &tm); + dat->textHeight = tm.tmHeight; + SelectObject(hdc, hfnt); + ReleaseDC(hwndDlg, hdc); + + dat->normalHeight = 4 + max(dat->titleHeight, g_iIconSY); + dat->selectedHeight = dat->normalHeight + 4 + 2 * dat->textHeight; + } + + SendDlgItemMessage(hwndDlg, IDC_NAME, WM_SETFONT, (WPARAM)dat->hfntTitle, 0); + SendDlgItemMessage(hwndDlg, IDC_TXT_ACCOUNT, WM_SETFONT, (WPARAM)dat->hfntTitle, 0); + SendDlgItemMessage(hwndDlg, IDC_TXT_ADDITIONAL, WM_SETFONT, (WPARAM)dat->hfntTitle, 0); + + dat->iSelected = -1; + sttSubclassAccList(GetDlgItem(hwndDlg, IDC_ACCLIST), TRUE); + SendMessage(hwndDlg, WM_MY_REFRESH, 0, 0); + + Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, "AccMgr", ""); + return TRUE; + + case WM_CTLCOLORSTATIC: + switch (GetDlgCtrlID((HWND)lParam)) { + case IDC_WHITERECT: + case IDC_NAME: + SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); + return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); + } + break; + + case WM_MEASUREITEM: + { + LPMEASUREITEMSTRUCT lps = (LPMEASUREITEMSTRUCT)lParam; + PROTOACCOUNT *acc = (PROTOACCOUNT *)lps->itemData; + + if ((lps->CtlID != IDC_ACCLIST) || !acc) + break; + + lps->itemWidth = 10; + lps->itemHeight = dat->normalHeight; + } + return TRUE; + + case WM_DRAWITEM: + HBRUSH hbrBack; + SIZE sz; + { + int cxIcon = g_iIconSX; + int cyIcon = g_iIconSY; + + LPDRAWITEMSTRUCT lps = (LPDRAWITEMSTRUCT)lParam; + PROTOACCOUNT *acc = (PROTOACCOUNT *)lps->itemData; + if ((lps->CtlID != IDC_ACCLIST) || (lps->itemID == -1) || !acc) + break; + + SetBkMode(lps->hDC, TRANSPARENT); + if (lps->itemState & ODS_SELECTED) { + hbrBack = GetSysColorBrush(COLOR_HIGHLIGHT); + SetTextColor(lps->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); + } + else { + hbrBack = GetSysColorBrush(COLOR_WINDOW); + SetTextColor(lps->hDC, GetSysColor(COLOR_WINDOWTEXT)); + } + FillRect(lps->hDC, &lps->rcItem, hbrBack); + + lps->rcItem.left += 2; + lps->rcItem.top += 2; + lps->rcItem.bottom -= 2; + + int tmp; + if (acc->bOldProto) + tmp = SKINICON_OTHER_ON; + else if (acc->bDynDisabled) + tmp = SKINICON_OTHER_OFF; + else + tmp = acc->bIsEnabled ? SKINICON_OTHER_TICK : SKINICON_OTHER_NOTICK; + + HICON hIcon = Skin_LoadIcon(tmp); + DrawIconEx(lps->hDC, lps->rcItem.left, lps->rcItem.top, hIcon, cxIcon, cyIcon, 0, hbrBack, DI_NORMAL); + IcoLib_ReleaseIcon(hIcon); + + lps->rcItem.left += cxIcon + 2; + + if (acc->ppro) { + hIcon = IcoLib_GetIconByHandle(acc->ppro->m_hProtoIcon); + DrawIconEx(lps->hDC, lps->rcItem.left, lps->rcItem.top, hIcon, cxIcon, cyIcon, 0, hbrBack, DI_NORMAL); + IcoLib_ReleaseIcon(hIcon); + } + lps->rcItem.left += cxIcon + 2; + + int length = SendDlgItemMessage(hwndDlg, IDC_ACCLIST, LB_GETTEXTLEN, lps->itemID, 0); + int size = max(length + 1, 256); + TCHAR *text = (TCHAR *)_alloca(sizeof(TCHAR) * size); + SendDlgItemMessage(hwndDlg, IDC_ACCLIST, LB_GETTEXT, lps->itemID, (LPARAM)text); + + SelectObject(lps->hDC, dat->hfntTitle); + tmp = lps->rcItem.bottom; + lps->rcItem.bottom = lps->rcItem.top + max(cyIcon, dat->titleHeight); + DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS | DT_VCENTER); + lps->rcItem.bottom = tmp; + GetTextExtentPoint32(lps->hDC, text, length, &sz); + lps->rcItem.top += max(cxIcon, sz.cy) + 2; + + if (lps->itemID == (unsigned)dat->iSelected) { + SelectObject(lps->hDC, dat->hfntText); + mir_sntprintf(text, size, _T("%s: %S"), TranslateT("Protocol"), acc->szProtoName); + length = (int)mir_tstrlen(text); + DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS); + GetTextExtentPoint32(lps->hDC, text, length, &sz); + lps->rcItem.top += sz.cy + 2; + + if (acc->ppro && Proto_IsProtocolLoaded(acc->szProtoName)) { + char *szIdName = (char *)acc->ppro->GetCaps(PFLAG_UNIQUEIDTEXT, 0); + TCHAR *tszIdName = szIdName ? mir_a2t(szIdName) : mir_tstrdup(TranslateT("Account ID")); + + CONTACTINFO ci = { 0 }; + ci.cbSize = sizeof(ci); + ci.hContact = NULL; + ci.szProto = acc->szModuleName; + ci.dwFlag = CNF_UNIQUEID | CNF_TCHAR; + if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)& ci)) { + switch (ci.type) { + case CNFT_ASCIIZ: + mir_sntprintf(text, size, _T("%s: %s"), tszIdName, ci.pszVal); + mir_free(ci.pszVal); + break; + case CNFT_DWORD: + mir_sntprintf(text, size, _T("%s: %d"), tszIdName, ci.dVal); + break; + } + } + else mir_sntprintf(text, size, _T("%s: %s"), tszIdName, TranslateT("")); + mir_free(tszIdName); + } + else mir_sntprintf(text, size, TranslateT("Protocol is not loaded.")); + + length = (int)mir_tstrlen(text); + DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS); + GetTextExtentPoint32(lps->hDC, text, length, &sz); + lps->rcItem.top += sz.cy + 2; + } + } + return TRUE; + + case WM_MY_REFRESH: + dat->iSelected = -1; + { + int i = ListBox_GetCurSel(hwndList); + PROTOACCOUNT *acc = (i == LB_ERR) ? NULL : (PROTOACCOUNT *)ListBox_GetItemData(hwndList, i); + + SendMessage(hwndList, LB_RESETCONTENT, 0, 0); + for (i = 0; i < accounts.getCount(); i++) { + PROTOACCOUNT *p = accounts[i]; + PROTOCOLDESCRIPTOR *pd = Proto_IsProtocolLoaded(p->szProtoName); + if (pd != NULL && pd->type != PROTOTYPE_PROTOCOL) + continue; + + int iItem = SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)p->tszAccountName); + SendMessage(hwndList, LB_SETITEMDATA, iItem, (LPARAM)p); + + if (p == acc) + ListBox_SetCurSel(hwndList, iItem); + } + + dat->iSelected = ListBox_GetCurSel(hwndList); // -1 if error = > nothing selected in our case + if (dat->iSelected >= 0) + sttSelectItem(dat, hwndList, dat->iSelected); + else if (acc && acc->hwndAccMgrUI) + ShowWindow(acc->hwndAccMgrUI, SW_HIDE); + } + sttUpdateAccountInfo(hwndDlg, dat); + break; + + case WM_CONTEXTMENU: + if (GetWindowLongPtr((HWND)wParam, GWL_ID) == IDC_ACCLIST) { + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + int iItem = ListBox_GetCurSel(hwndList); + + if (pt.x == -1 && pt.y == -1) { + if (iItem != LB_ERR) { + RECT rc; + ListBox_GetItemRect(hwndList, iItem, &rc); + pt.x = rc.left + g_iIconSX + 4; + pt.y = rc.top + 4 + max(g_iIconSX, dat->titleHeight); + ClientToScreen(hwndList, &pt); + } + } + else { + // menu was activated with mouse = > find item under cursor & set focus to our control. + POINT ptItem = pt; + ScreenToClient(hwndList, &ptItem); + iItem = (short)LOWORD(SendMessage(hwndList, LB_ITEMFROMPOINT, 0, MAKELPARAM(ptItem.x, ptItem.y))); + if (iItem != LB_ERR) { + ListBox_SetCurSel(hwndList, iItem); + sttUpdateAccountInfo(hwndDlg, dat); + sttSelectItem(dat, hwndList, iItem); + SetFocus(hwndList); + } + } + + if (iItem != LB_ERR) { + pa = (PROTOACCOUNT*)ListBox_GetItemData(hwndList, iItem); + HMENU hMenu = CreatePopupMenu(); + if (!pa->bOldProto && !pa->bDynDisabled) + AppendMenu(hMenu, MF_STRING, 1, TranslateT("Rename")); + + AppendMenu(hMenu, MF_STRING, 3, TranslateT("Delete")); + + if (Proto_IsAccountEnabled(pa)) + AppendMenu(hMenu, MF_STRING, 4, TranslateT("Configure")); + + if (pa->bOldProto || pa->bDynDisabled) + AppendMenu(hMenu, MF_STRING, 5, TranslateT("Upgrade")); + + switch (TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) { + case 1: + PostMessage(hwndList, WM_MY_RENAME, 0, 0); + break; + + case 2: + sttClickButton(hwndDlg, IDC_EDIT); + break; + + case 3: + sttClickButton(hwndDlg, IDC_REMOVE); + break; + + case 4: + sttClickButton(hwndDlg, IDC_OPTIONS); + break; + + case 5: + sttClickButton(hwndDlg, IDC_UPGRADE); + break; + } + DestroyMenu(hMenu); + } + } + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_ACCLIST: + switch (HIWORD(wParam)) { + case LBN_SELCHANGE: + sttUpdateAccountInfo(hwndDlg, dat); + sttSelectItem(dat, hwndList, ListBox_GetCurSel(hwndList)); + SetFocus(hwndList); + break; + + case LBN_DBLCLK: + PostMessage(hwndList, WM_MY_RENAME, 0, 0); + break; + + case LBN_MY_CHECK: + pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, lParam); + if (pa) { + if (pa->bOldProto || pa->bDynDisabled) + break; + + pa->bIsEnabled = !pa->bIsEnabled; + if (pa->bIsEnabled) { + if (ActivateAccount(pa)) { + pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0); + if (!db_get_b(NULL, "CList", "MoveProtoMenus", TRUE)) + pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0); + } + } + else { + DWORD dwStatus = CallProtoServiceInt(NULL, pa->szModuleName, PS_GETSTATUS, 0, 0); + if (dwStatus >= ID_STATUS_ONLINE) { + TCHAR buf[200]; + mir_sntprintf(buf, TranslateT("Account %s is being disabled"), pa->tszAccountName); + if (IDNO == ::MessageBox(hwndDlg, + TranslateT("Account is online. Disable account?"), + buf, MB_ICONWARNING | MB_DEFBUTTON2 | MB_YESNO)) { + pa->bIsEnabled = 1; //stay enabled + } + } + + if (!pa->bIsEnabled) + DeactivateAccount(pa, true, false); + } + + WriteDbAccounts(); + NotifyEventHooks(hAccListChanged, PRAC_CHECKED, (LPARAM)pa); + sttUpdateAccountInfo(hwndDlg, dat); + RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); + } + break; + + case LBN_MY_RENAME: + int iItem = ListBox_GetCurSel(hwndList); + pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, iItem); + if (pa) { + mir_free(pa->tszAccountName); + pa->tszAccountName = (TCHAR*)lParam; + WriteDbAccounts(); + NotifyEventHooks(hAccListChanged, PRAC_CHANGED, (LPARAM)pa); + + ListBox_DeleteString(hwndList, iItem); + iItem = ListBox_AddString(hwndList, pa->tszAccountName); + ListBox_SetItemData(hwndList, iItem, (LPARAM)pa); + ListBox_SetCurSel(hwndList, iItem); + + sttSelectItem(dat, hwndList, iItem); + + RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); + } + else mir_free((TCHAR*)lParam); + } + break; + + case IDC_ADD: + { + AccFormDlgParam param = { PRAC_ADDED, NULL }; + if (IDOK == DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_ACCFORM), hwndDlg, AccFormDlgProc, (LPARAM)¶m)) + SendMessage(hwndDlg, WM_MY_REFRESH, 0, 0); + } + break; + + case IDC_EDIT: + idx = ListBox_GetCurSel(hwndList); + if (idx != -1) + PostMessage(hwndList, WM_MY_RENAME, 0, 0); + break; + + case IDC_REMOVE: + idx = ListBox_GetCurSel(hwndList); + if (idx != -1) { + pa = (PROTOACCOUNT*)ListBox_GetItemData(hwndList, idx); + TCHAR buf[200]; + mir_sntprintf(buf, TranslateT("Account %s is being deleted"), pa->tszAccountName); + if (pa->bOldProto) { + MessageBox(hwndDlg, TranslateT("You need to disable plugin to delete this account"), buf, MB_ICONERROR | MB_OK); + break; + } + if (IDYES == MessageBox(hwndDlg, errMsg, buf, MB_ICONWARNING | MB_DEFBUTTON2 | MB_YESNO)) { + // lock controls to avoid changes during remove process + ListBox_SetCurSel(hwndList, -1); + sttUpdateAccountInfo(hwndDlg, dat); + EnableWindow(hwndList, FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); + + ListBox_SetItemData(hwndList, idx, 0); + + accounts.remove(pa); + + CheckProtocolOrder(); + + WriteDbAccounts(); + NotifyEventHooks(hAccListChanged, PRAC_REMOVED, (LPARAM)pa); + + UnloadAccount(pa, true, true); + SendMessage(hwndDlg, WM_MY_REFRESH, 0, 0); + + EnableWindow(hwndList, TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), TRUE); + } + } + break; + + case IDC_OPTIONS: + idx = ListBox_GetCurSel(hwndList); + if (idx != -1) { + pa = (PROTOACCOUNT*)ListBox_GetItemData(hwndList, idx); + if (pa->bOldProto) { + OPENOPTIONSDIALOG ood; + ood.cbSize = sizeof(ood); + ood.pszGroup = "Network"; + ood.pszPage = pa->szModuleName; + ood.pszTab = NULL; + Options_Open(&ood); + } + else OpenAccountOptions(pa); + } + break; + + case IDC_UPGRADE: + idx = ListBox_GetCurSel(hwndList); + if (idx != -1) { + AccFormDlgParam param = { PRAC_UPGRADED, (PROTOACCOUNT*)ListBox_GetItemData(hwndList, idx) }; + DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_ACCFORM), hwndDlg, AccFormDlgProc, (LPARAM)¶m); + } + break; + + case IDC_LNK_NETWORK: + pshn.hdr.idFrom = 0; + pshn.hdr.code = PSN_APPLY; + pshn.hdr.hwndFrom = hwndDlg; + SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&pshn); + { + OPENOPTIONSDIALOG ood = { 0 }; + ood.cbSize = sizeof(ood); + ood.pszPage = "Network"; + Options_Open(&ood); + } + break; + + case IDC_LNK_ADDONS: + CallService(MS_UTILS_OPENURL, OUF_NEWWINDOW, (LPARAM)"http://miranda-ng.org/"); + break; + + case IDOK: + pshn.hdr.idFrom = 0; + pshn.hdr.code = PSN_APPLY; + pshn.hdr.hwndFrom = hwndDlg; + SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&pshn); + DestroyWindow(hwndDlg); + break; + + case IDCANCEL: + pshn.hdr.idFrom = 0; + pshn.hdr.code = PSN_RESET; + pshn.hdr.hwndFrom = hwndDlg; + SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&pshn); + DestroyWindow(hwndDlg); + break; + } + break; + + case PSM_CHANGED: + idx = ListBox_GetCurSel(hwndList); + if (idx != -1) { + pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, idx); + if (pa) { + pa->bAccMgrUIChanged = TRUE; + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->idFrom == 0) { + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + pshn.hdr.idFrom = 0; + pshn.hdr.code = PSN_APPLY; + for (int i = 0; i < accounts.getCount(); i++) { + pa = accounts[i]; + if (pa->hwndAccMgrUI && pa->bAccMgrUIChanged) { + pshn.hdr.hwndFrom = pa->hwndAccMgrUI; + SendMessage(pa->hwndAccMgrUI, WM_NOTIFY, 0, (LPARAM)&pshn); + pa->bAccMgrUIChanged = FALSE; + } + } + return TRUE; + + case PSN_RESET: + pshn.hdr.idFrom = 0; + pshn.hdr.code = PSN_RESET; + for (int i = 0; i < accounts.getCount(); i++) { + pa = accounts[i]; + if (pa->hwndAccMgrUI && pa->bAccMgrUIChanged) { + pshn.hdr.hwndFrom = pa->hwndAccMgrUI; + SendMessage(pa->hwndAccMgrUI, WM_NOTIFY, 0, (LPARAM)&pshn); + pa->bAccMgrUIChanged = FALSE; + } + } + return TRUE; + } + } + break; + + case WM_DESTROY: + for (int i = 0; i < accounts.getCount(); i++) { + pa = accounts[i]; + pa->bAccMgrUIChanged = FALSE; + if (pa->hwndAccMgrUI) { + DestroyWindow(pa->hwndAccMgrUI); + pa->hwndAccMgrUI = NULL; + } + } + + Window_FreeIcon_IcoLib(hwndDlg); + Button_FreeIcon_IcoLib(hwndDlg, IDC_ADD); + Button_FreeIcon_IcoLib(hwndDlg, IDC_EDIT); + Button_FreeIcon_IcoLib(hwndDlg, IDC_REMOVE); + Button_FreeIcon_IcoLib(hwndDlg, IDC_OPTIONS); + Button_FreeIcon_IcoLib(hwndDlg, IDC_UPGRADE); + Utils_SaveWindowPosition(hwndDlg, NULL, "AccMgr", ""); + sttSubclassAccList(GetDlgItem(hwndDlg, IDC_ACCLIST), FALSE); + DeleteObject(dat->hfntTitle); + DeleteObject(dat->hfntText); + mir_free(dat); + hAccMgr = NULL; + break; + } + + return FALSE; +} + +static INT_PTR OptProtosShow(WPARAM, LPARAM) +{ + if (!hAccMgr) + hAccMgr = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_ACCMGR), NULL, AccMgrDlgProc, 0); + + ShowWindow(hAccMgr, SW_RESTORE); + SetForegroundWindow(hAccMgr); + SetActiveWindow(hAccMgr); + return 0; +} + +int OptProtosLoaded(WPARAM, LPARAM) +{ + CLISTMENUITEM mi = { sizeof(mi) }; + mi.icolibItem = Skin_GetIconHandle(SKINICON_OTHER_ACCMGR); + mi.position = 1900000000; + mi.pszName = LPGEN("&Accounts..."); + mi.pszService = MS_PROTO_SHOWACCMGR; + Menu_AddMainMenuItem(&mi); + return 0; +} + +static int OnAccListChanged(WPARAM eventCode, LPARAM lParam) +{ + PROTOACCOUNT *pa = (PROTOACCOUNT*)lParam; + + switch (eventCode) { + case PRAC_CHANGED: + if (pa->ppro) { + mir_free(pa->ppro->m_tszUserName); + pa->ppro->m_tszUserName = mir_tstrdup(pa->tszAccountName); + pa->ppro->OnEvent(EV_PROTO_ONRENAME, 0, lParam); + } + } + + return 0; +} + +static int ShutdownAccMgr(WPARAM, LPARAM) +{ + if (IsWindow(hAccMgr)) + DestroyWindow(hAccMgr); + hAccMgr = NULL; + return 0; +} + +int LoadProtoOptions(void) +{ + CreateServiceFunction(MS_PROTO_SHOWACCMGR, OptProtosShow); + + HookEvent(ME_SYSTEM_MODULESLOADED, OptProtosLoaded); + HookEvent(ME_PROTO_ACCLISTCHANGED, OnAccListChanged); + HookEvent(ME_SYSTEM_PRESHUTDOWN, ShutdownAccMgr); + return 0; +} diff --git a/src/mir_app/src/proto_order.cpp b/src/mir_app/src/proto_order.cpp new file mode 100644 index 0000000000..5f8cc25601 --- /dev/null +++ b/src/mir_app/src/proto_order.cpp @@ -0,0 +1,231 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org), +Copyright (c) 2000-12 Miranda IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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. +*/ + +#include "stdafx.h" +#include "clc.h" + +struct ProtocolData +{ + char *RealName; + int enabled; +}; + +int isProtoSuitable(PROTO_INTERFACE* ppi) +{ + if (ppi == NULL) + return TRUE; + + return ppi->GetCaps(PFLAGNUM_2, 0) & ~ppi->GetCaps(PFLAGNUM_5, 0); +} + +bool CheckProtocolOrder(void) +{ + bool changed = false; + int i, id = 0; + + for (;;) { + // Find account with this id + for (i = 0; i < accounts.getCount(); i++) + if (accounts[i]->iOrder == id) break; + + // Account with id not found + if (i == accounts.getCount()) { + // Check if this is skipped id, if it is decrement all other ids + bool found = false; + for (i = 0; i < accounts.getCount(); i++) { + if (accounts[i]->iOrder < 1000000 && accounts[i]->iOrder > id) { + --accounts[i]->iOrder; + found = true; + } + } + if (found) changed = true; + else break; + } + else id++; + } + + if (id < accounts.getCount()) { + // Remove huge ids + for (i = 0; i < accounts.getCount(); i++) + if (accounts[i]->iOrder >= 1000000) + accounts[i]->iOrder = id++; + + changed = true; + } + + if (id < accounts.getCount()) { + // Remove duplicate ids + for (i = 0; i < accounts.getCount(); i++) { + bool found = false; + for (int j = 0; j < accounts.getCount(); j++) { + if (accounts[j]->iOrder == i) { + if (found) accounts[j]->iOrder = id++; + else found = true; + } + } + } + changed = true; + } + + return changed; +} + +static bool ProtoToInclude(PROTOACCOUNT *pa) +{ + if (!Proto_IsAccountEnabled(pa)) + return false; + + PROTOCOLDESCRIPTOR *pd = Proto_IsProtocolLoaded(pa->szProtoName); + return (pd != NULL && pd->type == PROTOTYPE_PROTOCOL); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +class CProtocolOrderOpts : public CDlgBase +{ + void FillTree() + { + m_order.DeleteAllItems(); + + TVINSERTSTRUCT tvis; + tvis.hParent = NULL; + tvis.hInsertAfter = TVI_LAST; + tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + + for (int i = 0; i < accounts.getCount(); i++) { + int idx = cli.pfnGetAccountIndexByPos(i); + if (idx == -1) + continue; + + PROTOACCOUNT *pa = accounts[idx]; + if (!ProtoToInclude(pa)) + continue; + + ProtocolData *PD = (ProtocolData*)mir_alloc(sizeof(ProtocolData)); + PD->RealName = pa->szModuleName; + PD->enabled = Proto_IsAccountEnabled(pa) && isProtoSuitable(pa->ppro); + + tvis.item.lParam = (LPARAM)PD; + tvis.item.pszText = pa->tszAccountName; + tvis.item.iImage = tvis.item.iSelectedImage = PD->enabled ? pa->bIsVisible : 100; + m_order.InsertItem(&tvis); + } + } + + bool m_bDragging; + HTREEITEM m_hDragItem; + + CCtrlTreeView m_order; + CCtrlButton m_btnReset; + +public: + CProtocolOrderOpts() : + CDlgBase(g_hInst, IDD_OPT_PROTOCOLORDER), + m_order(this, IDC_PROTOCOLORDER), + m_btnReset(this, IDC_RESETPROTOCOLDATA), + m_bDragging(false), + m_hDragItem(NULL) + { + m_btnReset.OnClick = Callback(this, &CProtocolOrderOpts::onReset_Click); + + m_order.SetFlags(MTREE_CHECKBOX | MTREE_DND); + m_order.OnDeleteItem = Callback(this, &CProtocolOrderOpts::onOrder_DeleteItem); + } + + virtual void OnInitDialog() + { + HIMAGELIST himlCheckBoxes = ImageList_Create(g_iIconSX, g_iIconSY, ILC_COLOR32 | ILC_MASK, 2, 2); + ImageList_AddIcon_IconLibLoaded(himlCheckBoxes, SKINICON_OTHER_NOTICK); + ImageList_AddIcon_IconLibLoaded(himlCheckBoxes, SKINICON_OTHER_TICK); + m_order.SetImageList(himlCheckBoxes, TVSIL_NORMAL); + + FillTree(); + } + + virtual void OnApply() + { + int idx = 0; + + TVITEMEX tvi; + tvi.hItem = m_order.GetRoot(); + tvi.mask = TVIF_PARAM | TVIF_HANDLE | TVIF_IMAGE; + while (tvi.hItem != NULL) { + m_order.GetItem(&tvi); + + if (tvi.lParam != 0) { + ProtocolData *ppd = (ProtocolData*)tvi.lParam; + PROTOACCOUNT *pa = Proto_GetAccount(ppd->RealName); + if (pa != NULL) { + while (idx < accounts.getCount() && !ProtoToInclude(accounts[idx])) + idx++; + pa->iOrder = idx++; + if (ppd->enabled) + pa->bIsVisible = tvi.iImage != 0; + } + } + + tvi.hItem = m_order.GetNextSibling(tvi.hItem); + } + + WriteDbAccounts(); + cli.pfnReloadProtoMenus(); + cli.pfnTrayIconIconsChanged(); + cli.pfnClcBroadcast(INTM_RELOADOPTIONS, 0, 0); + cli.pfnClcBroadcast(INTM_INVALIDATE, 0, 0); + } + + virtual void OnDestroy() + { + ImageList_Destroy(m_order.GetImageList(TVSIL_NORMAL)); + } + + void onReset_Click(CCtrlButton*) + { + for (int i = 0; i < accounts.getCount(); i++) + accounts[i]->iOrder = i; + + FillTree(); + NotifyChange(); + } + + void onOrder_DeleteItem(CCtrlTreeView::TEventInfo *env) + { + NMTREEVIEW *pnmtv = env->nmtv; + if (pnmtv) + mir_free((ProtocolData*)pnmtv->itemOld.lParam); + } +}; + +int ProtocolOrderOptInit(WPARAM wParam, LPARAM) +{ + OPTIONSDIALOGPAGE odp = { 0 }; + odp.position = -10000000; + odp.groupPosition = 1000000; + odp.pszTitle = LPGEN("Accounts"); + odp.pszGroup = LPGEN("Contact list"); + odp.pDialog = new CProtocolOrderOpts(); + odp.flags = ODPF_BOLDGROUPS; + Options_AddPage(wParam, &odp); + return 0; +} diff --git a/src/mir_app/src/proto_ui.cpp b/src/mir_app/src/proto_ui.cpp new file mode 100644 index 0000000000..b5cb6483eb --- /dev/null +++ b/src/mir_app/src/proto_ui.cpp @@ -0,0 +1,169 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (C) 2012-15 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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. +*/ + +#include "stdafx.h" + +HINSTANCE ProtoGetInstance(const char *szModuleName) +{ + PROTOACCOUNT *pa = ProtoGetAccount(szModuleName); + if (pa == NULL) + return NULL; + + PROTOCOLDESCRIPTOR *p = Proto_IsProtocolLoaded(pa->szProtoName); + return (p == NULL) ? NULL : GetInstByAddress(p->fnInit); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Base protocol dialog + +CProtoIntDlgBase::CProtoIntDlgBase(PROTO_INTERFACE *proto, int idDialog, bool show_label) + : CDlgBase(::ProtoGetInstance(proto->m_szModuleName), idDialog), + m_proto_interface(proto), + m_show_label(show_label), + m_hwndStatus(NULL) +{} + +void CProtoIntDlgBase::CreateLink(CCtrlData& ctrl, char *szSetting, BYTE type, DWORD iValue) +{ + ctrl.CreateDbLink(m_proto_interface->m_szModuleName, szSetting, type, iValue); +} + +void CProtoIntDlgBase::CreateLink(CCtrlData& ctrl, const char *szSetting, TCHAR *szValue) +{ + ctrl.CreateDbLink(m_proto_interface->m_szModuleName, szSetting, szValue); +} + +void CProtoIntDlgBase::OnProtoRefresh(WPARAM, LPARAM) {} +void CProtoIntDlgBase::OnProtoActivate(WPARAM, LPARAM) {} +void CProtoIntDlgBase::OnProtoCheckOnline(WPARAM, LPARAM) {} + +void CProtoIntDlgBase::SetStatusText(const TCHAR *statusText) +{ + if (m_hwndStatus) + SendMessage(m_hwndStatus, SB_SETTEXT, 0, (LPARAM)statusText); +} + +INT_PTR CProtoIntDlgBase::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) +{ + INT_PTR result; + + switch (msg) { + case WM_INITDIALOG: // call inherited init code first + result = CSuper::DlgProc(msg, wParam, lParam); + m_proto_interface->WindowSubscribe(m_hwnd); + if (m_show_label) { + m_hwndStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE, NULL, m_hwnd, 999); + SetWindowPos(m_hwndStatus, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + UpdateStatusBar(); + UpdateProtoTitle(); + } + return result; + + case WM_DESTROY: + IcoLib_ReleaseIcon((HICON)SendMessage(m_hwnd, WM_SETICON, ICON_BIG, 0)); + IcoLib_ReleaseIcon((HICON)SendMessage(m_hwnd, WM_SETICON, ICON_SMALL, 0)); + m_proto_interface->WindowUnsubscribe(m_hwnd); + break; + + case WM_SETTEXT: + if (m_show_label && IsWindowUnicode(m_hwnd)) { + TCHAR *szTitle = (TCHAR *)lParam; + if (!_tcsstr(szTitle, m_proto_interface->m_tszUserName)) { + UpdateProtoTitle(szTitle); + return TRUE; + } + } + break; + + case WM_SIZE: + if (m_hwndStatus) { + RECT rcStatus; GetWindowRect(m_hwndStatus, &rcStatus); + RECT rcClient; GetClientRect(m_hwnd, &rcClient); + SetWindowPos(m_hwndStatus, NULL, 0, rcClient.bottom - (rcStatus.bottom - rcStatus.top), rcClient.right, (rcStatus.bottom - rcStatus.top), SWP_NOZORDER); + UpdateStatusBar(); + } + break; + + // Protocol events + case WM_PROTO_ACTIVATE: + OnProtoActivate(wParam, lParam); + return m_lresult; + + case WM_PROTO_CHECK_ONLINE: + if (m_hwndStatus) + UpdateStatusBar(); + OnProtoCheckOnline(wParam, lParam); + return m_lresult; + + case WM_PROTO_REFRESH: + OnProtoRefresh(wParam, lParam); + return m_lresult; + } + + return CSuper::DlgProc(msg, wParam, lParam); +} + +void CProtoIntDlgBase::UpdateProtoTitle(const TCHAR *szText) +{ + if (!m_show_label) + return; + + int curLength; + const TCHAR *curText; + + if (szText) { + curText = szText; + curLength = (int)mir_tstrlen(curText); + } + else { + curLength = GetWindowTextLength(m_hwnd) + 1; + TCHAR *tmp = (TCHAR *)_alloca(curLength * sizeof(TCHAR)); + GetWindowText(m_hwnd, tmp, curLength); + curText = tmp; + } + + if (!_tcsstr(curText, m_proto_interface->m_tszUserName)) { + size_t length = curLength + mir_tstrlen(m_proto_interface->m_tszUserName) + 256; + TCHAR *text = (TCHAR *)_alloca(length * sizeof(TCHAR)); + mir_sntprintf(text, length, _T("%s [%s: %s]"), curText, TranslateT("Account"), m_proto_interface->m_tszUserName); + SetWindowText(m_hwnd, text); + } +} + +void CProtoIntDlgBase::UpdateStatusBar() +{ + SIZE sz; + + HDC hdc = GetDC(m_hwndStatus); + HFONT hFntSave = (HFONT)SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)); + GetTextExtentPoint32(hdc, m_proto_interface->m_tszUserName, (int)mir_tstrlen(m_proto_interface->m_tszUserName), &sz); + sz.cx += GetSystemMetrics(SM_CXSMICON) * 3; + SelectObject(hdc, hFntSave); + ReleaseDC(m_hwndStatus, hdc); + + RECT rcStatus; GetWindowRect(m_hwndStatus, &rcStatus); + int parts[] = { rcStatus.right - rcStatus.left - sz.cx, -1 }; + SendMessage(m_hwndStatus, SB_SETPARTS, 2, (LPARAM)parts); + SendMessage(m_hwndStatus, SB_SETICON, 1, (LPARAM)Skin_LoadProtoIcon(m_proto_interface->m_szModuleName, m_proto_interface->m_iStatus)); + SendMessage(m_hwndStatus, SB_SETTEXT, 1, (LPARAM)m_proto_interface->m_tszUserName); +} diff --git a/src/mir_app/src/proto_utils.cpp b/src/mir_app/src/proto_utils.cpp new file mode 100644 index 0000000000..e69cb89891 --- /dev/null +++ b/src/mir_app/src/proto_utils.cpp @@ -0,0 +1,407 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (C) 2012-15 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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. +*/ + +#include "stdafx.h" + +static int CompareProtos(const PROTOCOLDESCRIPTOR *p1, const PROTOCOLDESCRIPTOR *p2) +{ + return strcmp(p1->szName, p2->szName); +} + +LIST protos(10, CompareProtos); + +extern HANDLE hAckEvent; + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_APP_DLL(PROTOCOLDESCRIPTOR*) Proto_IsProtocolLoaded(const char *szProtoName) +{ + if (szProtoName == NULL) + return NULL; + + PROTOCOLDESCRIPTOR tmp; + tmp.szName = (char*)szProtoName; + return protos.find(&tmp); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_APP_DLL(void) ProtoLogA(struct PROTO_INTERFACE *pThis, LPCSTR szFormat, va_list args) +{ + char buf[4096]; + int res = _vsnprintf(buf, sizeof(buf), szFormat, args); + CallService(MS_NETLIB_LOG, (WPARAM)(pThis ? pThis->m_hNetlibUser : NULL), (LPARAM)((res != -1) ? buf : CMStringA().FormatV(szFormat, args))); +} + +MIR_APP_DLL(void) ProtoLogW(struct PROTO_INTERFACE *pThis, LPCWSTR wszFormat, va_list args) +{ + WCHAR buf[4096]; + int res = _vsnwprintf(buf, SIZEOF(buf), wszFormat, args); + CallService(MS_NETLIB_LOGW, (WPARAM)(pThis ? pThis->m_hNetlibUser : NULL), (LPARAM)((res != -1) ? buf : CMStringW().FormatV(wszFormat, args))); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_APP_DLL(INT_PTR) ProtoBroadcastAck(const char *szModule, MCONTACT hContact, int type, int result, HANDLE hProcess, LPARAM lParam) +{ + ACKDATA ack = { sizeof(ACKDATA), szModule, hContact, type, result, hProcess, lParam }; + return NotifyEventHooks(hAckEvent, 0, (LPARAM)&ack); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_APP_DLL(void) ProtoConstructor(PROTO_INTERFACE *pThis, LPCSTR pszModuleName, LPCTSTR ptszUserName) +{ + pThis->m_iVersion = 2; + pThis->m_iStatus = pThis->m_iDesiredStatus = ID_STATUS_OFFLINE; + pThis->m_szModuleName = mir_strdup(pszModuleName); + pThis->m_hProtoIcon = IcoLib_IsManaged(Skin_LoadProtoIcon(pszModuleName, ID_STATUS_ONLINE)); + pThis->m_tszUserName = mir_tstrdup(ptszUserName); + db_set_resident(pThis->m_szModuleName, "Status"); +} + +MIR_APP_DLL(void) ProtoDestructor(PROTO_INTERFACE *pThis) +{ + mir_free(pThis->m_szModuleName); + mir_free(pThis->m_tszUserName); + + WindowList_Destroy(pThis->m_hWindowList); +} + +MIR_APP_DLL(void) ProtoCreateService(PROTO_INTERFACE *pThis, const char* szService, ProtoServiceFunc serviceProc) +{ + char str[MAXMODULELABELLENGTH * 2]; + strncpy_s(str, pThis->m_szModuleName, _TRUNCATE); + strncat_s(str, szService, _TRUNCATE); + ::CreateServiceFunctionObj(str, (MIRANDASERVICEOBJ)*(void**)&serviceProc, pThis); +} + +MIR_APP_DLL(void) ProtoCreateServiceParam(PROTO_INTERFACE *pThis, const char* szService, ProtoServiceFuncParam serviceProc, LPARAM lParam) +{ + char str[MAXMODULELABELLENGTH * 2]; + strncpy_s(str, pThis->m_szModuleName, _TRUNCATE); + strncat_s(str, szService, _TRUNCATE); + ::CreateServiceFunctionObjParam(str, (MIRANDASERVICEOBJPARAM)*(void**)&serviceProc, pThis, lParam); +} + +MIR_APP_DLL(void) ProtoHookEvent(PROTO_INTERFACE *pThis, const char* szEvent, ProtoEventFunc handler) +{ + ::HookEventObj(szEvent, (MIRANDAHOOKOBJ)*(void**)&handler, pThis); +} + +MIR_APP_DLL(HANDLE) ProtoCreateHookableEvent(PROTO_INTERFACE *pThis, const char* szName) +{ + char str[MAXMODULELABELLENGTH * 2]; + strncpy_s(str, pThis->m_szModuleName, _TRUNCATE); + strncat_s(str, szName, _TRUNCATE); + return CreateHookableEvent(str); +} + +MIR_APP_DLL(void) ProtoForkThread(PROTO_INTERFACE *pThis, ProtoThreadFunc pFunc, void *param) +{ + UINT threadID; + CloseHandle((HANDLE)::mir_forkthreadowner((pThreadFuncOwner)*(void**)&pFunc, pThis, param, &threadID)); +} + +MIR_APP_DLL(HANDLE) ProtoForkThreadEx(PROTO_INTERFACE *pThis, ProtoThreadFunc pFunc, void *param, UINT* threadID) +{ + UINT lthreadID; + return (HANDLE)::mir_forkthreadowner((pThreadFuncOwner)*(void**)&pFunc, pThis, param, threadID ? threadID : <hreadID); +} + +MIR_APP_DLL(void) ProtoWindowAdd(PROTO_INTERFACE *pThis, HWND hwnd) +{ + if (pThis->m_hWindowList == NULL) + pThis->m_hWindowList = WindowList_Create(); + + WindowList_Add(pThis->m_hWindowList, hwnd, NULL); +} + +MIR_APP_DLL(void) ProtoWindowRemove(PROTO_INTERFACE *pThis, HWND hwnd) +{ + WindowList_Remove(pThis->m_hWindowList, hwnd); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_APP_DLL(LPCTSTR) ProtoGetAvatarExtension(int format) +{ + if (format == PA_FORMAT_PNG) + return _T(".png"); + if (format == PA_FORMAT_JPEG) + return _T(".jpg"); + if (format == PA_FORMAT_ICON) + return _T(".ico"); + if (format == PA_FORMAT_BMP) + return _T(".bmp"); + if (format == PA_FORMAT_GIF) + return _T(".gif"); + if (format == PA_FORMAT_SWF) + return _T(".swf"); + if (format == PA_FORMAT_XML) + return _T(".xml"); + + return _T(""); +} + +MIR_APP_DLL(int) ProtoGetAvatarFormat(const TCHAR *ptszFileName) +{ + if (ptszFileName == NULL) + return PA_FORMAT_UNKNOWN; + + const TCHAR *ptszExt = _tcsrchr(ptszFileName, '.'); + if (ptszExt == NULL) + return PA_FORMAT_UNKNOWN; + + if (!_tcsicmp(ptszExt, _T(".png"))) + return PA_FORMAT_PNG; + + if (!_tcsicmp(ptszExt, _T(".jpg")) || !_tcsicmp(ptszExt, _T(".jpeg"))) + return PA_FORMAT_JPEG; + + if (!_tcsicmp(ptszExt, _T(".ico"))) + return PA_FORMAT_ICON; + + if (!_tcsicmp(ptszExt, _T(".bmp")) || !_tcsicmp(ptszExt, _T(".rle"))) + return PA_FORMAT_BMP; + + if (!_tcsicmp(ptszExt, _T(".gif"))) + return PA_FORMAT_GIF; + + if (!_tcsicmp(ptszExt, _T(".swf"))) + return PA_FORMAT_SWF; + + if (!_tcsicmp(ptszExt, _T(".xml"))) + return PA_FORMAT_XML; + + return PA_FORMAT_UNKNOWN; +} + +MIR_APP_DLL(int) ProtoGetBufferFormat(const void *pBuffer, const TCHAR **ptszExtension) +{ + if (!memcmp(pBuffer, "\x89PNG", 4)) { + if (ptszExtension) *ptszExtension = _T(".png"); + return PA_FORMAT_PNG; + } + + if (!memcmp(pBuffer, "GIF8", 4)) { + if (ptszExtension) *ptszExtension = _T(".gif"); + return PA_FORMAT_GIF; + } + + if (!memicmp(pBuffer, "szModuleName, p2->szModuleName); -} - -LIST accounts(10, CompareAccounts); - -///////////////////////////////////////////////////////////////////////////////////////// - -static int EnumDbModules(const char *szModuleName, DWORD, LPARAM) -{ - DBVARIANT dbv; - if (!db_get_s(NULL, szModuleName, "AM_BaseProto", &dbv)) { - if (!Proto_GetAccount(szModuleName)) { - PROTOACCOUNT *pa = (PROTOACCOUNT*)mir_calloc(sizeof(PROTOACCOUNT)); - pa->cbSize = sizeof(*pa); - pa->szModuleName = mir_strdup(szModuleName); - pa->szProtoName = mir_strdup(dbv.pszVal); - pa->tszAccountName = mir_a2t(szModuleName); - pa->bIsVisible = TRUE; - pa->bIsEnabled = FALSE; - pa->iOrder = accounts.getCount(); - accounts.insert(pa); - } - db_free(&dbv); - } - return 0; -} - -void LoadDbAccounts(void) -{ - DBVARIANT dbv; - int ver = db_get_dw(NULL, "Protocols", "PrVer", -1); - int count = db_get_dw(NULL, "Protocols", "ProtoCount", 0); - - for (int i = 0; i < count; i++) { - char buf[10]; - _itoa(i, buf, 10); - if (db_get_s(NULL, "Protocols", buf, &dbv)) - continue; - - PROTOACCOUNT *pa = (PROTOACCOUNT*)mir_calloc(sizeof(PROTOACCOUNT)); - if (pa == NULL) { - db_free(&dbv); - continue; - } - pa->cbSize = sizeof(*pa); - pa->szModuleName = mir_strdup(dbv.pszVal); - db_free(&dbv); - - _itoa(OFFSET_VISIBLE + i, buf, 10); - pa->bIsVisible = db_get_dw(NULL, "Protocols", buf, 1) != 0; - - _itoa(OFFSET_PROTOPOS + i, buf, 10); - pa->iOrder = db_get_dw(NULL, "Protocols", buf, 1); - - if (ver >= 4) { - db_free(&dbv); - _itoa(OFFSET_NAME + i, buf, 10); - if (!db_get_ts(NULL, "Protocols", buf, &dbv)) { - pa->tszAccountName = mir_tstrdup(dbv.ptszVal); - db_free(&dbv); - } - - _itoa(OFFSET_ENABLED + i, buf, 10); - pa->bIsEnabled = db_get_dw(NULL, "Protocols", buf, 1) != 0; - - if (!db_get_s(NULL, pa->szModuleName, "AM_BaseProto", &dbv)) { - pa->szProtoName = mir_strdup(dbv.pszVal); - db_free(&dbv); - } - } - else pa->bIsEnabled = true; - - if (!pa->szProtoName) { - pa->szProtoName = mir_strdup(pa->szModuleName); - db_set_s(NULL, pa->szModuleName, "AM_BaseProto", pa->szProtoName); - } - - if (!pa->tszAccountName) - pa->tszAccountName = mir_a2t(pa->szModuleName); - - accounts.insert(pa); - } - - if (CheckProtocolOrder()) - WriteDbAccounts(); - - int anum = accounts.getCount(); - CallService(MS_DB_MODULES_ENUM, 0, (LPARAM)EnumDbModules); - if (anum != accounts.getCount()) - WriteDbAccounts(); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - int arrlen; - char **pszSettingName; -} -enumDB_ProtoProcParam; - -static int enumDB_ProtoProc(const char* szSetting, LPARAM lParam) -{ - if (szSetting) { - enumDB_ProtoProcParam* p = (enumDB_ProtoProcParam*)lParam; - - p->arrlen++; - p->pszSettingName = (char**)mir_realloc(p->pszSettingName, p->arrlen*sizeof(char*)); - p->pszSettingName[p->arrlen - 1] = mir_strdup(szSetting); - } - return 0; -} - -void WriteDbAccounts() -{ - // enum all old settings to delete - enumDB_ProtoProcParam param = { 0, NULL }; - - DBCONTACTENUMSETTINGS dbces; - dbces.pfnEnumProc = enumDB_ProtoProc; - dbces.szModule = "Protocols"; - dbces.ofsSettings = 0; - dbces.lParam = (LPARAM)¶m; - CallService(MS_DB_CONTACT_ENUMSETTINGS, 0, (LPARAM)&dbces); - - // delete all settings - if (param.arrlen) { - for (int i = 0; i < param.arrlen; i++) { - db_unset(0, "Protocols", param.pszSettingName[i]); - mir_free(param.pszSettingName[i]); - } - mir_free(param.pszSettingName); - } - - // write new data - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - - char buf[20]; - _itoa(i, buf, 10); - db_set_s(NULL, "Protocols", buf, pa->szModuleName); - - _itoa(OFFSET_PROTOPOS + i, buf, 10); - db_set_dw(NULL, "Protocols", buf, pa->iOrder); - - _itoa(OFFSET_VISIBLE + i, buf, 10); - db_set_dw(NULL, "Protocols", buf, pa->bIsVisible); - - _itoa(OFFSET_ENABLED + i, buf, 10); - db_set_dw(NULL, "Protocols", buf, pa->bIsEnabled); - - _itoa(OFFSET_NAME + i, buf, 10); - db_set_ts(NULL, "Protocols", buf, pa->tszAccountName); - } - - db_unset(0, "Protocols", "ProtoCount"); - db_set_dw(0, "Protocols", "ProtoCount", accounts.getCount()); - db_set_dw(0, "Protocols", "PrVer", 4); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static int OnContactDeleted(WPARAM hContact, LPARAM lParam) -{ - if (hContact) { - PROTOACCOUNT *pa = Proto_GetAccount(hContact); - if (Proto_IsAccountEnabled(pa) && pa->ppro) - pa->ppro->OnEvent(EV_PROTO_ONCONTACTDELETED, hContact, lParam); - } - return 0; -} - -static int OnDbSettingsChanged(WPARAM hContact, LPARAM lParam) -{ - if (hContact) { - PROTOACCOUNT *pa = Proto_GetAccount(hContact); - if (Proto_IsAccountEnabled(pa) && pa->ppro) - pa->ppro->OnEvent(EV_PROTO_DBSETTINGSCHANGED, hContact, lParam); - } - return 0; -} - -static int InitializeStaticAccounts(WPARAM, LPARAM) -{ - int count = 0; - - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - if (!pa->ppro || !Proto_IsAccountEnabled(pa)) - continue; - - pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0); - - if (!pa->bOldProto) - count++; - } - - BuildProtoMenus(); - - if (count == 0 && !db_get_b(NULL, "FirstRun", "AccManager", 0)) { - db_set_b(NULL, "FirstRun", "AccManager", 1); - CallService(MS_PROTO_SHOWACCMGR, 0, 0); - } - // This is for pack creators with a profile with predefined accounts - else if (db_get_b(NULL, "FirstRun", "ForceShowAccManager", 0)) { - CallService(MS_PROTO_SHOWACCMGR, 0, 0); - db_unset(NULL, "FirstRun", "ForceShowAccManager"); - } - return 0; -} - -static int UninitializeStaticAccounts(WPARAM, LPARAM) -{ - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - if (pa->ppro && Proto_IsAccountEnabled(pa)) - if (pa->ppro->OnEvent(EV_PROTO_ONREADYTOEXIT, 0, 0) != TRUE) - return 1; - } - - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - if (pa->ppro && Proto_IsAccountEnabled(pa)) - pa->ppro->OnEvent(EV_PROTO_ONEXIT, 0, 0); - } - - return 0; -} - -int LoadAccountsModule(void) -{ - bModuleInitialized = TRUE; - - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - pa->bDynDisabled = !Proto_IsProtocolLoaded(pa->szProtoName); - if (pa->ppro) - continue; - - if (!Proto_IsAccountEnabled(pa)) - continue; - - if (!ActivateAccount(pa)) - pa->bDynDisabled = TRUE; - } - - hHooks[0] = HookEvent(ME_SYSTEM_MODULESLOADED, InitializeStaticAccounts); - hHooks[1] = HookEvent(ME_SYSTEM_PRESHUTDOWN, UninitializeStaticAccounts); - hHooks[2] = HookEvent(ME_DB_CONTACT_DELETED, OnContactDeleted); - hHooks[3] = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, OnDbSettingsChanged); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static HANDLE CreateProtoServiceEx(const char* szModule, const char* szService, MIRANDASERVICEOBJ pFunc, void* param) -{ - char tmp[100]; - mir_snprintf(tmp, "%s%s", szModule, szService); - return CreateServiceFunctionObj(tmp, pFunc, param); -} - -BOOL ActivateAccount(PROTOACCOUNT *pa) -{ - PROTOCOLDESCRIPTOR* ppd = Proto_IsProtocolLoaded(pa->szProtoName); - if (ppd == NULL) - return FALSE; - - if (ppd->fnInit == NULL) - return FALSE; - - PROTO_INTERFACE *ppi = ppd->fnInit(pa->szModuleName, pa->tszAccountName); - if (ppi == NULL) - return FALSE; - - pa->ppro = ppi; - ppi->m_iDesiredStatus = ppi->m_iStatus = ID_STATUS_OFFLINE; - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -struct DeactivationThreadParam -{ - PROTO_INTERFACE *ppro; - pfnUninitProto fnUninit; - bool bIsDynamic, bErase; -}; - -pfnUninitProto GetProtocolDestructor(char *szProto); - -static int DeactivationThread(DeactivationThreadParam* param) -{ - PROTO_INTERFACE *p = (PROTO_INTERFACE*)param->ppro; - p->SetStatus(ID_STATUS_OFFLINE); - - char *szModuleName = NEWSTR_ALLOCA(p->m_szModuleName); - - if (param->bIsDynamic) { - while (p->OnEvent(EV_PROTO_ONREADYTOEXIT, 0, 0) != TRUE) - SleepEx(100, TRUE); - - p->OnEvent(EV_PROTO_ONEXIT, 0, 0); - } - - KillObjectThreads(p); // waits for them before terminating - KillObjectEventHooks(p); // untie an object from the outside world - - if (param->bErase) - p->OnEvent(EV_PROTO_ONERASE, 0, 0); - - if (param->fnUninit) - param->fnUninit(p); - - KillObjectServices(p); - - if (param->bErase) - EraseAccount(szModuleName); - - delete param; - return 0; -} - -void DeactivateAccount(PROTOACCOUNT *pa, bool bIsDynamic, bool bErase) -{ - if (pa->ppro == NULL) { - if (bErase) - EraseAccount(pa->szModuleName); - return; - } - - if (pa->hwndAccMgrUI) { - DestroyWindow(pa->hwndAccMgrUI); - pa->hwndAccMgrUI = NULL; - pa->bAccMgrUIChanged = FALSE; - } - - DeactivationThreadParam *param = new DeactivationThreadParam; - param->ppro = pa->ppro; - param->fnUninit = GetProtocolDestructor(pa->szProtoName); - param->bIsDynamic = bIsDynamic; - param->bErase = bErase; - pa->ppro = NULL; - if (bIsDynamic) - mir_forkthread((pThreadFunc)DeactivationThread, param); - else - DeactivationThread(param); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void EraseAccount(const char* pszModuleName) -{ - // remove protocol contacts first - for (MCONTACT hContact = db_find_first(pszModuleName); hContact != NULL;) { - MCONTACT hNext = db_find_next(hContact, pszModuleName); - CallService(MS_DB_CONTACT_DELETE, hContact, 0); - hContact = hNext; - } - - // remove all protocol settings - CallService(MS_DB_MODULE_DELETE, 0, (LPARAM)pszModuleName); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void UnloadAccount(PROTOACCOUNT *pa, bool bIsDynamic, bool bErase) -{ - DeactivateAccount(pa, bIsDynamic, bErase); - - mir_free(pa->tszAccountName); - mir_free(pa->szProtoName); - // szModuleName should be freed only on a program's exit. - // otherwise many plugins dependand on static protocol names will crash! - // do NOT fix this 'leak', please - if (!bIsDynamic) { - mir_free(pa->szModuleName); - mir_free(pa); - } -} - -void UnloadAccountsModule() -{ - if (!bModuleInitialized) return; - - for (int i = accounts.getCount() - 1; i >= 0; i--) { - PROTOACCOUNT *pa = accounts[i]; - UnloadAccount(pa, false, false); - accounts.remove(i); - } - accounts.destroy(); - - for (int i = 0; i < SIZEOF(hHooks); i++) - UnhookEvent(hHooks[i]); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void BuildProtoMenus() -{ - for (int i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *pa = accounts[i]; - if (cli.pfnGetProtocolVisibility(pa->szModuleName) == 0) - continue; - - if (pa->ppro) - pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0); - } -} - -void RebuildProtoMenus() -{ - RebuildMenuOrder(); - BuildProtoMenus(); -} diff --git a/src/mir_app/src/protochains.cpp b/src/mir_app/src/protochains.cpp deleted file mode 100644 index e7f4348fe0..0000000000 --- a/src/mir_app/src/protochains.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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. -*/ - -#include "stdafx.h" -#include - -extern LIST filters; - -static int GetProtocolP(MCONTACT hContact, char *szBuf, int cbLen) -{ - if (currDb == NULL) - return 1; - - DBCachedContact *cc = currDb->m_cache->GetCachedContact(hContact); - if (cc && cc->szProto != NULL) { - strncpy(szBuf, cc->szProto, cbLen); - szBuf[cbLen - 1] = 0; - return 0; - } - - DBVARIANT dbv; - dbv.type = DBVT_ASCIIZ; - dbv.pszVal = szBuf; - dbv.cchVal = cbLen; - - int res = currDb->GetContactSettingStatic(hContact, "Protocol", "p", &dbv); - if (res == 0) { - if (cc == NULL) - cc = currDb->m_cache->AddContactToCache(hContact); - - cc->szProto = currDb->m_cache->GetCachedSetting(NULL, szBuf, 0, (int)mir_strlen(szBuf)); - } - return res; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -MIR_APP_DLL(INT_PTR) CallContactService(MCONTACT hContact, const char *szProtoService, WPARAM wParam, LPARAM lParam) -{ - INT_PTR ret; - CCSDATA ccs = { hContact, szProtoService, wParam, lParam }; - - for (int i = 0; i < filters.getCount(); i++) { - if ((ret = CallProtoServiceInt(hContact, filters[i]->szName, szProtoService, i + 1, (LPARAM)&ccs)) != CALLSERVICE_NOTFOUND) { - //chain was started, exit - return ret; - } - } - - char szProto[40]; - if (GetProtocolP((MCONTACT)hContact, szProto, sizeof(szProto))) - return 1; - - PROTOACCOUNT *pa = Proto_GetAccount(szProto); - if (pa == NULL || pa->ppro == NULL) - return 1; - - if (pa->bOldProto) - ret = CallProtoServiceInt(hContact, szProto, szProtoService, (WPARAM)(-1), (LPARAM)&ccs); - else - ret = CallProtoServiceInt(hContact, szProto, szProtoService, wParam, lParam); - if (ret == CALLSERVICE_NOTFOUND) - ret = 1; - - return ret; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -INT_PTR Proto_CallContactService(WPARAM wParam, LPARAM lParam) -{ - CCSDATA *ccs = (CCSDATA*)lParam; - INT_PTR ret; - - if (wParam == (WPARAM)(-1)) - return 1; - - for (int i = wParam; i < filters.getCount(); i++) { - if ((ret = CallProtoServiceInt(NULL, filters[i]->szName, ccs->szProtoService, i + 1, lParam)) != CALLSERVICE_NOTFOUND) { - //chain was started, exit - return ret; - } - } - - char szProto[40]; - if (GetProtocolP((MCONTACT)ccs->hContact, szProto, sizeof(szProto))) - return 1; - - PROTOACCOUNT *pa = Proto_GetAccount(szProto); - if (pa == NULL || pa->ppro == NULL) - return 1; - - if (pa->bOldProto) - ret = CallProtoServiceInt(ccs->hContact, szProto, ccs->szProtoService, (WPARAM)(-1), (LPARAM)ccs); - else - ret = CallProtoServiceInt(ccs->hContact, szProto, ccs->szProtoService, ccs->wParam, ccs->lParam); - if (ret == CALLSERVICE_NOTFOUND) - ret = 1; - - return ret; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR Proto_RecvChain(WPARAM wParam, LPARAM lParam) -{ - CCSDATA *ccs = (CCSDATA*)lParam; - INT_PTR ret; - - if (wParam == (WPARAM)(-1)) return 1; //shouldn't happen - sanity check - if (wParam == 0) { //begin processing by finding end of chain - if (GetCurrentThreadId() != hMainThreadId) // restart this function in the main thread - return CallServiceSync(MS_PROTO_CHAINRECV, wParam, lParam); - - wParam = filters.getCount(); - } - else wParam--; - - for (int i = wParam - 1; i >= 0; i--) - if ((ret = CallProtoServiceInt(NULL, filters[i]->szName, ccs->szProtoService, i + 1, lParam)) != CALLSERVICE_NOTFOUND) - //chain was started, exit - return ret; - - //end of chain, call network protocol again - char szProto[40]; - if (GetProtocolP((MCONTACT)ccs->hContact, szProto, sizeof(szProto))) - return 1; - - PROTOACCOUNT *pa = Proto_GetAccount(szProto); - if (pa == NULL || pa->ppro == NULL) - return 1; - - if (pa->bOldProto) - ret = CallProtoServiceInt(ccs->hContact, szProto, ccs->szProtoService, (WPARAM)(-1), (LPARAM)ccs); - else - ret = CallProtoServiceInt(ccs->hContact, szProto, ccs->szProtoService, ccs->wParam, ccs->lParam); - if (ret == CALLSERVICE_NOTFOUND) - ret = 1; - - return ret; -} - -PROTOACCOUNT* __fastcall Proto_GetAccount(MCONTACT hContact) -{ - if (hContact == NULL) - return NULL; - - char szProto[40]; - if (GetProtocolP((MCONTACT)hContact, szProto, sizeof(szProto))) - return NULL; - - return Proto_GetAccount(szProto); -} - -static INT_PTR Proto_GetContactBaseProto(WPARAM wParam, LPARAM) -{ - PROTOACCOUNT *pa = Proto_GetAccount(wParam); - return (INT_PTR)(Proto_IsAccountEnabled(pa) ? pa->szModuleName : NULL); -} - -static INT_PTR Proto_GetContactBaseAccount(WPARAM wParam, LPARAM) -{ - PROTOACCOUNT *pa = Proto_GetAccount(wParam); - return (INT_PTR)(pa ? pa->szModuleName : NULL); -} - -static INT_PTR Proto_IsProtoOnContact(WPARAM wParam, LPARAM lParam) -{ - char *szProto = (char*)lParam; - if (szProto == NULL) - return 0; - - char szContactProto[40]; - if (!GetProtocolP(wParam, szContactProto, sizeof(szContactProto))) - if (!_stricmp(szProto, szContactProto)) - return -1; - - for (int i = 0; i < filters.getCount(); i++) - if (!mir_strcmp(szProto, filters[i]->szName)) - return i + 1; - - return 0; -} - -static INT_PTR Proto_AddToContact(WPARAM wParam, LPARAM lParam) -{ - char *szProto = (char*)lParam; - PROTOCOLDESCRIPTOR *pd = Proto_IsProtocolLoaded(szProto); - if (pd == NULL) { - PROTOACCOUNT *pa = Proto_GetAccount(szProto); - if (pa) { - db_set_s(wParam, "Protocol", "p", szProto); - return 0; - } - return 1; - } - - if (pd->type == PROTOTYPE_PROTOCOL || pd->type == PROTOTYPE_VIRTUAL) - db_set_s(wParam, "Protocol", "p", szProto); - - return 0; -} - -static INT_PTR Proto_RemoveFromContact(WPARAM wParam, LPARAM lParam) -{ - switch (Proto_IsProtoOnContact(wParam, lParam)) { - case 0: - return 1; - case -1: - db_unset(wParam, "Protocol", "p"); - } - - return 0; -} - -int LoadProtoChains(void) -{ - if (!db_get_b(NULL, "Compatibility", "Filters", 0)) { - CallService(MS_DB_MODULE_DELETE, 0, (LPARAM)"_Filters"); - db_set_b(NULL, "Compatibility", "Filters", 1); - } - - CreateServiceFunction(MS_PROTO_CALLCONTACTSERVICE, Proto_CallContactService); - CreateServiceFunction(MS_PROTO_CHAINSEND, Proto_CallContactService); - CreateServiceFunction(MS_PROTO_CHAINRECV, Proto_RecvChain); - CreateServiceFunction(MS_PROTO_GETCONTACTBASEPROTO, Proto_GetContactBaseProto); - CreateServiceFunction(MS_PROTO_GETCONTACTBASEACCOUNT, Proto_GetContactBaseAccount); - CreateServiceFunction(MS_PROTO_ISPROTOONCONTACT, Proto_IsProtoOnContact); - CreateServiceFunction(MS_PROTO_ADDTOCONTACT, Proto_AddToContact); - CreateServiceFunction(MS_PROTO_REMOVEFROMCONTACT, Proto_RemoveFromContact); - return 0; -} diff --git a/src/mir_app/src/protocolorder.cpp b/src/mir_app/src/protocolorder.cpp deleted file mode 100644 index 5f8cc25601..0000000000 --- a/src/mir_app/src/protocolorder.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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. -*/ - -#include "stdafx.h" -#include "clc.h" - -struct ProtocolData -{ - char *RealName; - int enabled; -}; - -int isProtoSuitable(PROTO_INTERFACE* ppi) -{ - if (ppi == NULL) - return TRUE; - - return ppi->GetCaps(PFLAGNUM_2, 0) & ~ppi->GetCaps(PFLAGNUM_5, 0); -} - -bool CheckProtocolOrder(void) -{ - bool changed = false; - int i, id = 0; - - for (;;) { - // Find account with this id - for (i = 0; i < accounts.getCount(); i++) - if (accounts[i]->iOrder == id) break; - - // Account with id not found - if (i == accounts.getCount()) { - // Check if this is skipped id, if it is decrement all other ids - bool found = false; - for (i = 0; i < accounts.getCount(); i++) { - if (accounts[i]->iOrder < 1000000 && accounts[i]->iOrder > id) { - --accounts[i]->iOrder; - found = true; - } - } - if (found) changed = true; - else break; - } - else id++; - } - - if (id < accounts.getCount()) { - // Remove huge ids - for (i = 0; i < accounts.getCount(); i++) - if (accounts[i]->iOrder >= 1000000) - accounts[i]->iOrder = id++; - - changed = true; - } - - if (id < accounts.getCount()) { - // Remove duplicate ids - for (i = 0; i < accounts.getCount(); i++) { - bool found = false; - for (int j = 0; j < accounts.getCount(); j++) { - if (accounts[j]->iOrder == i) { - if (found) accounts[j]->iOrder = id++; - else found = true; - } - } - } - changed = true; - } - - return changed; -} - -static bool ProtoToInclude(PROTOACCOUNT *pa) -{ - if (!Proto_IsAccountEnabled(pa)) - return false; - - PROTOCOLDESCRIPTOR *pd = Proto_IsProtocolLoaded(pa->szProtoName); - return (pd != NULL && pd->type == PROTOTYPE_PROTOCOL); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -class CProtocolOrderOpts : public CDlgBase -{ - void FillTree() - { - m_order.DeleteAllItems(); - - TVINSERTSTRUCT tvis; - tvis.hParent = NULL; - tvis.hInsertAfter = TVI_LAST; - tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; - - for (int i = 0; i < accounts.getCount(); i++) { - int idx = cli.pfnGetAccountIndexByPos(i); - if (idx == -1) - continue; - - PROTOACCOUNT *pa = accounts[idx]; - if (!ProtoToInclude(pa)) - continue; - - ProtocolData *PD = (ProtocolData*)mir_alloc(sizeof(ProtocolData)); - PD->RealName = pa->szModuleName; - PD->enabled = Proto_IsAccountEnabled(pa) && isProtoSuitable(pa->ppro); - - tvis.item.lParam = (LPARAM)PD; - tvis.item.pszText = pa->tszAccountName; - tvis.item.iImage = tvis.item.iSelectedImage = PD->enabled ? pa->bIsVisible : 100; - m_order.InsertItem(&tvis); - } - } - - bool m_bDragging; - HTREEITEM m_hDragItem; - - CCtrlTreeView m_order; - CCtrlButton m_btnReset; - -public: - CProtocolOrderOpts() : - CDlgBase(g_hInst, IDD_OPT_PROTOCOLORDER), - m_order(this, IDC_PROTOCOLORDER), - m_btnReset(this, IDC_RESETPROTOCOLDATA), - m_bDragging(false), - m_hDragItem(NULL) - { - m_btnReset.OnClick = Callback(this, &CProtocolOrderOpts::onReset_Click); - - m_order.SetFlags(MTREE_CHECKBOX | MTREE_DND); - m_order.OnDeleteItem = Callback(this, &CProtocolOrderOpts::onOrder_DeleteItem); - } - - virtual void OnInitDialog() - { - HIMAGELIST himlCheckBoxes = ImageList_Create(g_iIconSX, g_iIconSY, ILC_COLOR32 | ILC_MASK, 2, 2); - ImageList_AddIcon_IconLibLoaded(himlCheckBoxes, SKINICON_OTHER_NOTICK); - ImageList_AddIcon_IconLibLoaded(himlCheckBoxes, SKINICON_OTHER_TICK); - m_order.SetImageList(himlCheckBoxes, TVSIL_NORMAL); - - FillTree(); - } - - virtual void OnApply() - { - int idx = 0; - - TVITEMEX tvi; - tvi.hItem = m_order.GetRoot(); - tvi.mask = TVIF_PARAM | TVIF_HANDLE | TVIF_IMAGE; - while (tvi.hItem != NULL) { - m_order.GetItem(&tvi); - - if (tvi.lParam != 0) { - ProtocolData *ppd = (ProtocolData*)tvi.lParam; - PROTOACCOUNT *pa = Proto_GetAccount(ppd->RealName); - if (pa != NULL) { - while (idx < accounts.getCount() && !ProtoToInclude(accounts[idx])) - idx++; - pa->iOrder = idx++; - if (ppd->enabled) - pa->bIsVisible = tvi.iImage != 0; - } - } - - tvi.hItem = m_order.GetNextSibling(tvi.hItem); - } - - WriteDbAccounts(); - cli.pfnReloadProtoMenus(); - cli.pfnTrayIconIconsChanged(); - cli.pfnClcBroadcast(INTM_RELOADOPTIONS, 0, 0); - cli.pfnClcBroadcast(INTM_INVALIDATE, 0, 0); - } - - virtual void OnDestroy() - { - ImageList_Destroy(m_order.GetImageList(TVSIL_NORMAL)); - } - - void onReset_Click(CCtrlButton*) - { - for (int i = 0; i < accounts.getCount(); i++) - accounts[i]->iOrder = i; - - FillTree(); - NotifyChange(); - } - - void onOrder_DeleteItem(CCtrlTreeView::TEventInfo *env) - { - NMTREEVIEW *pnmtv = env->nmtv; - if (pnmtv) - mir_free((ProtocolData*)pnmtv->itemOld.lParam); - } -}; - -int ProtocolOrderOptInit(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - odp.position = -10000000; - odp.groupPosition = 1000000; - odp.pszTitle = LPGEN("Accounts"); - odp.pszGroup = LPGEN("Contact list"); - odp.pDialog = new CProtocolOrderOpts(); - odp.flags = ODPF_BOLDGROUPS; - Options_AddPage(wParam, &odp); - return 0; -} diff --git a/src/mir_app/src/protocols.cpp b/src/mir_app/src/protocols.cpp index dca0f5bed1..8620c9ae50 100644 --- a/src/mir_app/src/protocols.cpp +++ b/src/mir_app/src/protocols.cpp @@ -27,6 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. int LoadProtoChains(void); int LoadProtoOptions(void); +HANDLE hAckEvent; HANDLE hAccListChanged; static HANDLE hTypeEvent; static BOOL bModuleInitialized = FALSE; @@ -111,10 +112,14 @@ static INT_PTR srvProto_RegisterModule(WPARAM, LPARAM lParam) if (pd->cbSize != sizeof(PROTOCOLDESCRIPTOR) && pd->cbSize != PROTOCOLDESCRIPTOR_V3_SIZE) return 1; - PROTOCOLDESCRIPTOR *p = Proto_RegisterModule(pd); - if (p == NULL) + PROTOCOLDESCRIPTOR *p = (PROTOCOLDESCRIPTOR*)mir_calloc(sizeof(PROTOCOLDESCRIPTOR)); + if (!p) return 2; + memcpy(p, pd, pd->cbSize); + p->szName = mir_strdup(pd->szName); + protos.insert(p); + if (p->fnInit == NULL && (p->type == PROTOTYPE_PROTOCOL || p->type == PROTOTYPE_VIRTUAL)) { // let's create a new container PROTO_INTERFACE* ppi = AddDefaultAccount(pd->szName); @@ -364,6 +369,13 @@ static INT_PTR Proto_BroadcastAck(WPARAM, LPARAM lParam) return ProtoBroadcastAck(ack->szModule, ack->hContact, ack->type, ack->result, ack->hProcess, ack->lParam); } +static INT_PTR Proto_EnumProtocols(WPARAM wParam, LPARAM lParam) +{ + *(int*)wParam = protos.getCount(); + *(PROTOCOLDESCRIPTOR***)lParam = protos.getArray(); + return 0; +} + ///////////////////////////////////////////////////////////////////////////////////////// MIR_APP_DLL(int) ProtoServiceExists(const char *szModule, const char *szService) @@ -474,7 +486,9 @@ int LoadProtocolsModule(void) hTypeEvent = CreateHookableEvent(ME_PROTO_CONTACTISTYPING); hAccListChanged = CreateHookableEvent(ME_PROTO_ACCLISTCHANGED); + hAckEvent = CreateHookableEvent(ME_PROTO_ACK); + CreateServiceFunction(MS_PROTO_ENUMPROTOS, Proto_EnumProtocols); CreateServiceFunction(MS_PROTO_BROADCASTACK, Proto_BroadcastAck); CreateServiceFunction(MS_PROTO_ISPROTOCOLLOADED, srvProto_IsLoaded); CreateServiceFunction(MS_PROTO_REGISTERMODULE, srvProto_RegisterModule); @@ -499,6 +513,17 @@ void UnloadProtocolsModule() { if (!bModuleInitialized) return; + for (int i = 0; i < protos.getCount(); i++) { + mir_free(protos[i]->szName); + mir_free(protos[i]); + } + protos.destroy(); + + if (hAckEvent) { + DestroyHookableEvent(hAckEvent); + hAckEvent = NULL; + } + if (hAccListChanged) { DestroyHookableEvent(hAccListChanged); hAccListChanged = NULL; diff --git a/src/mir_app/src/protodir.cpp b/src/mir_app/src/protodir.cpp deleted file mode 100644 index dbeac1afee..0000000000 --- a/src/mir_app/src/protodir.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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. -*/ - -#include "stdafx.h" - -#if 0 - -extern HANDLE hCacheHeap; - -/* - - the id cache has id/proto against hContact to lookup ID's fast to resolve to hContact, - the protoBaseCache has hContact's sorted, so can lookup hContact->proto fast, these two caches - share the same data, they're indexes, each entry might not have an "id" set. - - There is a small cache which maintains a protocol list - -*/ - -/* - - The information we need to cache is not readily available, data has to be gathered at startup - when a new contact is created/deleted, when a new proto registers and so on. - - The information we get at startup includes walking the contact chain and reading Protocol/p which - will give us the protocol the contact is on, all this info is stored in contactEntry's within - protoCache ONLY - contactCache is EMPTY at this point. - - We can not fetch the id of the contact because this information is only in SOME protocol plugins, - this is a problem but we'll hook all proto registrations and ask each proto if it supports the - returning this ID name, if not - it won't even use our id <-> contact look so no biggie! - -*/ - -typedef struct { - char * proto; // within proto cache - char * id; // optional - HANDLE hContact; -} contactEntry; - -typedef struct { - mir_cs csLock; - SortedList contactCache; // index for id/proto -> hContact - SortedList protoCache; // index for hContact -> proto/id - SortedList protoNameCache; // index of protocol names -} contactDir; - -static contactDir condir; - -// compare's id/proto and return's hContact's -int contactCacheCompare(void * a, void * b) -{ - contactEntry * x = (contactEntry *) a; - contactEntry * y = (contactEntry *) b; - int rc=0; - // same protocol? - rc = mir_strcmp(x->proto, y->proto); - if ( rc == 0 ) { - // same id? id's might be missing - if ( x->id && y->id ) rc = mir_strcmp(x->id, y->id); - } - return rc; -} - -// compares hContact's and returns associated data -int protoCacheCompare(void * a, void * b) -{ - contactEntry * x = (contactEntry *) a; - contactEntry * y = (contactEntry *) b; - if ( x->hContact < y->hContact ) return -1; - if ( x->hContact > y->hContact ) return 1; - return 0; -} - -// keeps a list of protocol names -int protoNameCacheCompare(void * a, void * b) -{ - return mir_strcmp( (char *)a, (char*)b ); -} - -// cache the protocol string so that its not allocated per contact but shared -char * contactDir_Proto_Add(contactDir * cd, char * proto) -{ - int index = 0 ; - char * szCache = 0; - mir_cslock lck(cd->csLock); - if ( List_GetIndex(&cd->protoNameCache, proto, &index) ) szCache = cd->protoNameCache.items[index]; - else { - szCache = HeapAlloc(hCacheHeap, HEAP_NO_SERIALIZE, mir_strlen(proto)+1); - mir_strcpy(szCache, proto); - List_Insert(&cd->protoNameCache, szCache, index); - } - return szCache; -} - -// thread safe -char * contactDir_Proto_Get(contactDir * cd, HANDLE hContact) -{ - char * szCache = 0; - int index = 0; - contactEntry e; - e.hContact=hContact; - e.proto=""; - e.id=""; - mir_cslock lck(cd->csLock); - if ( List_GetIndex(&cd->protoCache, &e, &index) ) { - contactEntry * p = cd->protoCache.items[index]; - szCache = p->proto; - } - return szCache; -} - -// thread tolerant, if updating id dont pass proto, if updating proto dont pass id -void contactDir_Contact_Add(contactDir * cd, HANDLE hContact, char * proto, char * id) -{ - // if a contact is gonna exist anywhere it's going to be in the ->protoCache which has a key of hContact - // if id is not null then the contact should be indexed via the ->contactCache instead - if ( id == NULL ) { - int index = 0; - contactEntry e; - e.hContact=hContact; - e.proto = proto; - e.id = ""; - mir_cslock lck(cd->csLock); - if ( List_GetIndex(&cd->protoCache, &e, &index) ) { - contactEntry * p = cd->protoCache.items[index]; - // this hContact is in the cache, protcol changing? - p->proto = contactDir_Proto_Add(cd, proto); // just replace the old pointer - } else { - contactEntry * p = 0; - // this hContact isn't in the cache, add it - p = HeapAlloc(hCacheHeap, HEAP_NO_SERIALIZE, sizeof(contactEntry)); - p->proto = contactDir_Proto_Add(cd, proto); - p->id = 0; - p->hContact = hContact; - // add it - List_Insert(&cd->protoCache, p, index); - } - } else { - // this contact HAS to be in ->protoCache since it was added during startup - // need to find the contactEntry* that should already exist for it - } //if -} - -// only expected to be called at startup. -void contactDir_Proto_Walk(contactDir * cd) -{ - HANDLE hContact; - char buf[128]; - DBCONTACTGETSETTING gsProto; - DBVARIANT dbvProto; - // setup the read structure - gsProto.szModule="Protocol"; - gsProto.szSetting="p"; - gsProto.pValue = &dbvProto; - // this might not work - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while ( hContact ) { - // and how we'll get the reset - dbvProto.type=DBVT_ASCIIZ; - dbvProto.pszVal = (char *) &buf; - dbvProto.cchVal = SIZEOF(buf); - // figure out what hContact/Protocol/p is - if ( CallService(MS_DB_CONTACT_GETSETTINGSTATIC,(WPARAM)hContact, (LPARAM)&gsProto) == 0 ) { - contactDir_Contact_Add(cd, hContact, buf, NULL); - } - // find next - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); - } -} - -// ctor/dtor - -void contactDir_Init(contactDir * cd) -{ - cd->contactCache.increment=50; - cd->contactCache.sortFunc=contactCacheCompare; - cd->protoCache.increment=50; - cd->protoCache.sortFunc=protoCacheCompare; - cd->protoNameCache.increment=5; - cd->protoNameCache.sortFunc=protoNameCacheCompare; - // build a list of all hContact's and what proto's they are on - contactDir_Proto_Walk(cd); -} - -void contactDir_Deinit(contactDir * cd) -{ - List_Destroy(&cd->contactCache); - List_Destroy(&cd->protoCache); - List_Destroy(&cd->protoNameCache); -} - -static int contactDirGetProto(WPARAM wParam, LPARAM lParam) -{ - return (int) contactDir_Proto_Get(&condir,(HANDLE)wParam); -} - -#endif - -void InitContactDir(void) -{ - return; - //contactDir_Init(&condir); - //CreateServiceFunction(MS_PROTODIR_PROTOFROMCONTACT, contactDirGetProto); -} - -void UninitContactDir(void) -{ - return; -#if 0 - { - int j; - for ( j = 0; j< condir.protoCache.realCount; j++) { - char buf[128]; - contactEntry * p = condir.protoCache.items[j]; - mir_snprintf(buf,SIZEOF(buf)," [%s] %s @ %x \n", p->proto, p->id ? p->id : "", p->hContact); - OutputDebugString(buf); - } - } - contactDir_Deinit(&condir); -#endif -} diff --git a/src/mir_app/src/protoint.cpp b/src/mir_app/src/protoint.cpp deleted file mode 100644 index c440c5c22d..0000000000 --- a/src/mir_app/src/protoint.cpp +++ /dev/null @@ -1,304 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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. -*/ - -#include "stdafx.h" - -char** __fastcall Proto_FilesMatrixA(TCHAR **files); - -void FreeFilesMatrix(TCHAR ***files) -{ - if (*files == NULL) - return; - - // Free each filename in the pointer array - TCHAR **pFile = *files; - while (*pFile != NULL) { - mir_free(*pFile); - *pFile = NULL; - pFile++; - } - - // Free the array itself - mir_free(*files); - *files = NULL; -} - -struct DEFAULT_PROTO_INTERFACE : public PROTO_INTERFACE -{ - MCONTACT __cdecl AddToList(int flags, PROTOSEARCHRESULT *psr) - { - return (MCONTACT)ProtoCallService(m_szModuleName, PS_ADDTOLIST, flags, (LPARAM)psr); - } - - MCONTACT __cdecl AddToListByEvent(int flags, int iContact, MEVENT hDbEvent) - { - return (MCONTACT)ProtoCallService(m_szModuleName, PS_ADDTOLISTBYEVENT, MAKELONG(flags, iContact), hDbEvent); - } - - int __cdecl Authorize(MEVENT hDbEvent) - { - return (int)ProtoCallService(m_szModuleName, PS_AUTHALLOW, (WPARAM)hDbEvent, 0); - } - - int __cdecl AuthDeny(MEVENT hDbEvent, const TCHAR *szReason) - { - if (m_iVersion > 1) - return (int)ProtoCallService(m_szModuleName, PS_AUTHDENY, hDbEvent, (LPARAM)szReason); - - return (int)ProtoCallService(m_szModuleName, PS_AUTHDENY, hDbEvent, _T2A(szReason)); - } - - int __cdecl AuthRecv(MCONTACT hContact, PROTORECVEVENT *evt) - { - CCSDATA ccs = { hContact, PSR_AUTH, 0, (LPARAM)evt }; - return (int)ProtoCallService(m_szModuleName, PSR_AUTH, 0, (LPARAM)&ccs); - } - - int __cdecl AuthRequest(MCONTACT hContact, const TCHAR *szMessage) - { - CCSDATA ccs = { hContact, PSS_AUTHREQUEST, 0, (LPARAM)szMessage }; - if (m_iVersion > 1) - return (int)ProtoCallService(m_szModuleName, PSS_AUTHREQUEST, 0, (LPARAM)&ccs); - - ccs.lParam = (LPARAM)mir_t2a(szMessage); - int res = (int)ProtoCallService(m_szModuleName, PSS_AUTHREQUEST, 0, (LPARAM)&ccs); - mir_free((char*)ccs.lParam); - return res; - } - - HANDLE __cdecl FileAllow(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szPath) - { - CCSDATA ccs = { hContact, PSS_FILEALLOW, (WPARAM)hTransfer, (LPARAM)szPath }; - if (m_iVersion > 1) - return (HANDLE)ProtoCallService(m_szModuleName, PSS_FILEALLOW, 0, (LPARAM)&ccs); - - ccs.lParam = (LPARAM)mir_t2a(szPath); - HANDLE res = (HANDLE)ProtoCallService(m_szModuleName, PSS_FILEALLOW, 0, (LPARAM)&ccs); - mir_free((char*)ccs.lParam); - return res; - } - - int __cdecl FileCancel(MCONTACT hContact, HANDLE hTransfer) - { - CCSDATA ccs = { hContact, PSS_FILECANCEL, (WPARAM)hTransfer, 0 }; - return (int)ProtoCallService(m_szModuleName, PSS_FILECANCEL, 0, (LPARAM)&ccs); - } - - int __cdecl FileDeny(MCONTACT hContact, HANDLE hTransfer, const TCHAR* szReason) - { - CCSDATA ccs = { hContact, PSS_FILEDENY, (WPARAM)hTransfer, (LPARAM)szReason }; - if (m_iVersion > 1) - return (int)ProtoCallService(m_szModuleName, PSS_FILEDENY, 0, (LPARAM)&ccs); - - ccs.lParam = (LPARAM)mir_t2a(szReason); - int res = (int)ProtoCallService(m_szModuleName, PSS_FILEDENY, 0, (LPARAM)&ccs); - mir_free((char*)ccs.lParam); - return res; - } - - int __cdecl FileResume(HANDLE hTransfer, int* action, const TCHAR** szFilename) - { - PROTOFILERESUME pfr = { *action, *szFilename }; - if (m_iVersion > 1) - return (int)ProtoCallService(m_szModuleName, PS_FILERESUME, (WPARAM)hTransfer, (LPARAM)&pfr); - - pfr.szFilename = (TCHAR*)mir_t2a(pfr.szFilename); - int res = (int)ProtoCallService(m_szModuleName, PS_FILERESUME, (WPARAM)hTransfer, (LPARAM)&pfr); - mir_free((TCHAR*)*szFilename); - *action = pfr.action; *szFilename = (TCHAR*)pfr.szFilename; - - return res; - } - - DWORD_PTR __cdecl GetCaps(int type, MCONTACT hContact) - { - return (DWORD_PTR)ProtoCallService(m_szModuleName, PS_GETCAPS, type, hContact); - } - - HICON __cdecl GetIcon(int iconIndex) - { - return (HICON)ProtoCallService(m_szModuleName, PS_LOADICON, iconIndex, 0); - } - - int __cdecl GetInfo(MCONTACT hContact, int flags) - { - CCSDATA ccs = { hContact, PSS_GETINFO, flags, 0 }; - return ProtoCallService(m_szModuleName, PSS_GETINFO, 0, (LPARAM)&ccs); - } - - HANDLE __cdecl SearchBasic(const TCHAR* id) - { - if (m_iVersion > 1) - return (HANDLE)ProtoCallService(m_szModuleName, PS_BASICSEARCH, 0, (LPARAM)id); - - return (HANDLE)ProtoCallService(m_szModuleName, PS_BASICSEARCH, 0, _T2A(id)); - } - - HANDLE __cdecl SearchByEmail(const TCHAR* email) - { - if (m_iVersion > 1) - return (HANDLE)ProtoCallService(m_szModuleName, PS_SEARCHBYEMAIL, 0, (LPARAM)email); - return (HANDLE)ProtoCallService(m_szModuleName, PS_SEARCHBYEMAIL, 0, _T2A(email)); - } - - HANDLE __cdecl SearchByName(const TCHAR* nick, const TCHAR* firstName, const TCHAR* lastName) - { - PROTOSEARCHBYNAME psn; - psn.pszNick = (TCHAR*)mir_t2a(nick); - psn.pszFirstName = (TCHAR*)mir_t2a(firstName); - psn.pszLastName = (TCHAR*)mir_t2a(lastName); - HANDLE res = (HANDLE)ProtoCallService(m_szModuleName, PS_SEARCHBYNAME, 0, (LPARAM)&psn); - mir_free(psn.pszNick); - mir_free(psn.pszFirstName); - mir_free(psn.pszLastName); - return res; - - } - - HWND __cdecl SearchAdvanced(HWND owner) - { - return (HWND)ProtoCallService(m_szModuleName, PS_SEARCHBYADVANCED, 0, (LPARAM)owner); - } - - HWND __cdecl CreateExtendedSearchUI(HWND owner) - { - return (HWND)ProtoCallService(m_szModuleName, PS_CREATEADVSEARCHUI, 0, (LPARAM)owner); - } - - int __cdecl RecvContacts(MCONTACT hContact, PROTORECVEVENT* evt) - { - CCSDATA ccs = { hContact, PSR_CONTACTS, 0, (LPARAM)evt }; - return (int)ProtoCallService(m_szModuleName, PSR_CONTACTS, 0, (LPARAM)&ccs); - } - - int __cdecl RecvFile(MCONTACT hContact, PROTORECVFILET* evt) - { - CCSDATA ccs = { hContact, PSR_FILE, 0, (LPARAM)evt }; - return ProtoCallService(m_szModuleName, PSR_FILE, 0, (LPARAM)&ccs); - } - - int __cdecl RecvMsg(MCONTACT hContact, PROTORECVEVENT* evt) - { - CCSDATA ccs = { hContact, PSR_MESSAGE, 0, (LPARAM)evt }; - return (int)ProtoCallService(m_szModuleName, PSR_MESSAGE, 0, (LPARAM)&ccs); - } - - int __cdecl RecvUrl(MCONTACT hContact, PROTORECVEVENT* evt) - { - CCSDATA ccs = { hContact, PSR_URL, 0, (LPARAM)evt }; - return (int)ProtoCallService(m_szModuleName, PSR_URL, 0, (LPARAM)&ccs); - } - - int __cdecl SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList) - { - CCSDATA ccs = { hContact, PSS_CONTACTS, MAKEWPARAM(flags, nContacts), (LPARAM)hContactsList }; - return (int)ProtoCallService(m_szModuleName, PSS_CONTACTS, 0, (LPARAM)&ccs); - } - - HANDLE __cdecl SendFile(MCONTACT hContact, const TCHAR* szDescription, TCHAR** ppszFiles) - { - CCSDATA ccs = { hContact, PSS_FILE, (WPARAM)szDescription, (LPARAM)ppszFiles }; - - if (m_iVersion > 1) - return (HANDLE)ProtoCallService(m_szModuleName, PSS_FILE, 0, (LPARAM)&ccs); - - ccs.wParam = (WPARAM)mir_t2a(szDescription); - ccs.lParam = (LPARAM)Proto_FilesMatrixA(ppszFiles); - HANDLE res = (HANDLE)ProtoCallService(m_szModuleName, PSS_FILE, 0, (LPARAM)&ccs); - if (res == 0) FreeFilesMatrix((TCHAR***)&ccs.lParam); - mir_free((char*)ccs.wParam); - return res; - } - - int __cdecl SendMsg(MCONTACT hContact, const char* msg) - { - CCSDATA ccs = { hContact, PSS_MESSAGE, 0, (LPARAM)msg }; - return (int)ProtoCallService(m_szModuleName, PSS_MESSAGE, 0, (LPARAM)&ccs); - } - - int __cdecl SendUrl(MCONTACT hContact, int flags, const char* url) - { - CCSDATA ccs = { hContact, PSS_URL, flags, (LPARAM)url }; - return (int)ProtoCallService(m_szModuleName, PSS_URL, 0, (LPARAM)&ccs); - } - - int __cdecl SetApparentMode(MCONTACT hContact, int mode) - { - CCSDATA ccs = { hContact, PSS_SETAPPARENTMODE, mode, 0 }; - return (int)ProtoCallService(m_szModuleName, PSS_SETAPPARENTMODE, 0, (LPARAM)&ccs); - } - - int __cdecl SetStatus(int iNewStatus) - { - return (int)ProtoCallService(m_szModuleName, PS_SETSTATUS, iNewStatus, 0); - } - - HANDLE __cdecl GetAwayMsg(MCONTACT hContact) - { - CCSDATA ccs = { hContact, PSS_GETAWAYMSG, 0, 0 }; - return (HANDLE)ProtoCallService(m_szModuleName, PSS_GETAWAYMSG, 0, (LPARAM)&ccs); - } - - int __cdecl RecvAwayMsg(MCONTACT hContact, int statusMode, PROTORECVEVENT* evt) - { - CCSDATA ccs = { hContact, PSR_AWAYMSG, statusMode, (LPARAM)evt }; - return (int)ProtoCallService(m_szModuleName, PSR_AWAYMSG, 0, (LPARAM)&ccs); - } - - int __cdecl SetAwayMsg(int iStatus, const TCHAR *msg) - { - if (m_iVersion > 1) - return (int)ProtoCallService(m_szModuleName, PS_SETAWAYMSG, iStatus, (LPARAM)msg); - return (int)ProtoCallService(m_szModuleName, PS_SETAWAYMSG, iStatus, _T2A(msg)); - } - - int __cdecl UserIsTyping(MCONTACT hContact, int type) - { - CCSDATA ccs = { hContact, PSS_USERISTYPING, hContact, type }; - return ProtoCallService(m_szModuleName, PSS_USERISTYPING, 0, (LPARAM)&ccs); - } - - int __cdecl OnEvent(PROTOEVENTTYPE, WPARAM, LPARAM) - { - return 1; - } -}; - -// creates the default protocol container for compatibility with the old plugins - -PROTO_INTERFACE* AddDefaultAccount(const char *szProtoName) -{ - PROTO_INTERFACE* ppi = new DEFAULT_PROTO_INTERFACE; - ppi->m_szModuleName = mir_strdup(szProtoName); - ppi->m_tszUserName = mir_a2t(szProtoName); - return ppi; -} - -int FreeDefaultAccount(PROTO_INTERFACE* ppi) -{ - mir_free(ppi->m_szModuleName); - mir_free(ppi->m_tszUserName); - delete ppi; - return 0; -} diff --git a/src/mir_app/src/protoopts.cpp b/src/mir_app/src/protoopts.cpp deleted file mode 100644 index 6d042b30cc..0000000000 --- a/src/mir_app/src/protoopts.cpp +++ /dev/null @@ -1,1062 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -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. -*/ - -#include "stdafx.h" - -#define LBN_MY_CHECK 0x1000 -#define LBN_MY_RENAME 0x1001 - -#define WM_MY_REFRESH (WM_USER+0x1000) -#define WM_MY_RENAME (WM_USER+0x1001) - -bool CheckProtocolOrder(void); - -#define errMsg \ -TranslateT("WARNING! The account is going to be deleted. It means that all its \ -settings, contacts and histories will be also erased.\n\n\ -Are you absolutely sure?") - -#define upgradeMsg \ -TranslateT("Your account was successfully upgraded. \ -To activate it, restart of Miranda is needed.\n\n\ -If you want to restart Miranda now, press Yes, if you want to upgrade another account, press No") -// is upgradeMsg in use in any place? -#define legacyMsg \ -TranslateT("This account uses legacy protocol plugin. \ -Use Miranda NG options dialogs to change its preferences.") - -#define welcomeMsg \ -TranslateT("Welcome to Miranda NG's account manager!\n\ -Here you can set up your IM accounts.\n\n\ -Select an account from the list on the left to see the available options. \ -Alternatively, just click on the Plus sign underneath the list to set up a new IM account.") - -static HWND hAccMgr = NULL; - -extern HANDLE hAccListChanged; - -int UnloadPlugin(TCHAR* buf, int bufLen); - -PROTOACCOUNT* Proto_CreateAccount(const char *szModuleName, const char *szBaseProto, const TCHAR *tszAccountName) -{ - PROTOACCOUNT *pa = (PROTOACCOUNT*)mir_calloc(sizeof(PROTOACCOUNT)); - if (pa == NULL) - return NULL; - - pa->cbSize = sizeof(PROTOACCOUNT); - pa->bIsEnabled = pa->bIsVisible = true; - pa->iOrder = accounts.getCount(); - pa->szProtoName = mir_strdup(szBaseProto); - - // if the internal name is empty, generate new one - if (mir_strlen(szModuleName) == 0) { - char buf[100]; - int count = 1; - while (true) { - mir_snprintf(buf, "%s_%d", szBaseProto, count++); - if (ptrA(db_get_sa(NULL, buf, "AM_BaseProto")) == NULL) - break; - } - pa->szModuleName = mir_strdup(buf); - } - else pa->szModuleName = mir_strdup(szModuleName); - - pa->tszAccountName = mir_tstrdup(tszAccountName); - - db_set_s(NULL, pa->szModuleName, "AM_BaseProto", szBaseProto); - accounts.insert(pa); - - if (ActivateAccount(pa)) { - pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0); - if (!db_get_b(NULL, "CList", "MoveProtoMenus", true)) - pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0); - } - - return pa; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Account edit form -// Gets PROTOACCOUNT* as a parameter, or NULL to edit a new one - -struct AccFormDlgParam -{ - int action; - PROTOACCOUNT *pa; -}; - -static bool FindAccountByName(const char *szModuleName) -{ - if (!mir_strlen(szModuleName)) - return false; - - for (int i = 0; i < accounts.getCount(); i++) - if (_stricmp(szModuleName, accounts[i]->szModuleName) == 0) - return true; - - return false; -} - -static bool OnCreateAccount(HWND hwndDlg) -{ - AccFormDlgParam* param = (AccFormDlgParam*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - PROTOACCOUNT *pa = param->pa; - - TCHAR tszAccName[256]; - GetDlgItemText(hwndDlg, IDC_ACCNAME, tszAccName, SIZEOF(tszAccName)); - rtrimt(tszAccName); - if (tszAccName[0] == 0) { - MessageBox(hwndDlg, TranslateT("Account name must be filled."), TranslateT("Account error"), MB_ICONERROR | MB_OK); - return false; - } - - if (param->action == PRAC_ADDED) { - char buf[200]; - GetDlgItemTextA(hwndDlg, IDC_ACCINTERNALNAME, buf, SIZEOF(buf)); - if (FindAccountByName(rtrim(buf))) { - MessageBox(hwndDlg, TranslateT("Account name has to be unique. Please enter unique name."), TranslateT("Account error"), MB_ICONERROR | MB_OK); - return false; - } - } - - if (param->action == PRAC_UPGRADED) { - BOOL oldProto = pa->bOldProto; - TCHAR szPlugin[MAX_PATH]; - mir_sntprintf(szPlugin, SIZEOF(szPlugin), _T("%s.dll"), _A2T(pa->szProtoName)); - int idx = accounts.getIndex(pa); - UnloadAccount(pa, false, false); - accounts.remove(idx); - if (oldProto && UnloadPlugin(szPlugin, SIZEOF(szPlugin))) { - TCHAR szNewName[MAX_PATH]; - mir_sntprintf(szNewName, SIZEOF(szNewName), _T("%s~"), szPlugin); - MoveFile(szPlugin, szNewName); - } - param->action = PRAC_ADDED; - } - - if (param->action == PRAC_ADDED) { - char buf[200]; - GetDlgItemTextA(hwndDlg, IDC_PROTOTYPECOMBO, buf, SIZEOF(buf)); - char *szBaseProto = NEWSTR_ALLOCA(buf); - - GetDlgItemTextA(hwndDlg, IDC_ACCINTERNALNAME, buf, SIZEOF(buf)); - rtrim(buf); - - pa = Proto_CreateAccount(buf, szBaseProto, tszAccName); - } - else replaceStrT(pa->tszAccountName, tszAccName); - - WriteDbAccounts(); - NotifyEventHooks(hAccListChanged, param->action, (LPARAM)pa); - - SendMessage(GetParent(hwndDlg), WM_MY_REFRESH, 0, 0); - return true; -} - -static INT_PTR CALLBACK AccFormDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - { - PROTOCOLDESCRIPTOR **proto; - int protoCount, i, cnt = 0; - CallService(MS_PROTO_ENUMPROTOS, (WPARAM)&protoCount, (LPARAM)&proto); - for (i = 0; i < protoCount; i++) { - PROTOCOLDESCRIPTOR* pd = proto[i]; - if (pd->type == PROTOTYPE_PROTOCOL && pd->cbSize == sizeof(*pd)) { - SendDlgItemMessageA(hwndDlg, IDC_PROTOTYPECOMBO, CB_ADDSTRING, 0, (LPARAM)proto[i]->szName); - ++cnt; - } - } - SendDlgItemMessage(hwndDlg, IDC_PROTOTYPECOMBO, CB_SETCURSEL, 0, 0); - EnableWindow(GetDlgItem(hwndDlg, IDOK), cnt != 0); - - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); - AccFormDlgParam* param = (AccFormDlgParam*)lParam; - - if (param->action == PRAC_ADDED) // new account - SetWindowText(hwndDlg, TranslateT("Create new account")); - else { - TCHAR str[200]; - if (param->action == PRAC_CHANGED) { // update - EnableWindow(GetDlgItem(hwndDlg, IDC_PROTOTYPECOMBO), FALSE); - mir_sntprintf(str, SIZEOF(str), _T("%s: %s"), TranslateT("Editing account"), param->pa->tszAccountName); - } - else mir_sntprintf(str, SIZEOF(str), _T("%s: %s"), TranslateT("Upgrading account"), param->pa->tszAccountName); - - SetWindowText(hwndDlg, str); - SetDlgItemText(hwndDlg, IDC_ACCNAME, param->pa->tszAccountName); - SetDlgItemTextA(hwndDlg, IDC_ACCINTERNALNAME, param->pa->szModuleName); - SendDlgItemMessageA(hwndDlg, IDC_PROTOTYPECOMBO, CB_SELECTSTRING, -1, (LPARAM)param->pa->szProtoName); - - EnableWindow(GetDlgItem(hwndDlg, IDC_ACCINTERNALNAME), FALSE); - } - SendDlgItemMessage(hwndDlg, IDC_ACCINTERNALNAME, EM_LIMITTEXT, 40, 0); - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - if (OnCreateAccount(hwndDlg)) - EndDialog(hwndDlg, TRUE); - break; - - case IDCANCEL: - EndDialog(hwndDlg, FALSE); - break; - } - } - - return FALSE; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Accounts manager - -struct TAccMgrData -{ - HFONT hfntTitle, hfntText; - int titleHeight, textHeight; - int selectedHeight, normalHeight; - int iSelected; -}; - -struct TAccListData -{ - int iItem; - RECT rcCheck; - HWND hwndEdit; -}; - -static void sttClickButton(HWND hwndDlg, int idcButton) -{ - if (IsWindowEnabled(GetDlgItem(hwndDlg, idcButton))) - PostMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(idcButton, BN_CLICKED), (LPARAM)GetDlgItem(hwndDlg, idcButton)); -} - -static LRESULT CALLBACK sttEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_KEYDOWN: - switch (wParam) { - case VK_RETURN: - DestroyWindow(hwnd); - return 0; - - case VK_ESCAPE: - SetWindowLongPtr(hwnd, GWLP_WNDPROC, GetWindowLongPtr(hwnd, GWLP_USERDATA)); - DestroyWindow(hwnd); - return 0; - } - break; - - case WM_GETDLGCODE: - if (wParam == VK_RETURN || wParam == VK_ESCAPE) - return DLGC_WANTMESSAGE; - break; - - case WM_KILLFOCUS: - int length = GetWindowTextLength(hwnd) + 1; - TCHAR *str = (TCHAR*)mir_alloc(sizeof(TCHAR) * length); - GetWindowText(hwnd, str, length); - SendMessage(GetParent(GetParent(hwnd)), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(GetParent(hwnd), GWL_ID), LBN_MY_RENAME), (LPARAM)str); - DestroyWindow(hwnd); - return 0; - } - return mir_callNextSubclass(hwnd, sttEditSubclassProc, msg, wParam, lParam); -} - -static LRESULT CALLBACK AccListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - struct TAccListData *dat = (struct TAccListData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); - if (!dat) - return DefWindowProc(hwnd, msg, wParam, lParam); - - switch (msg) { - case WM_LBUTTONDOWN: - { - POINT pt = { LOWORD(lParam), HIWORD(lParam) }; - int iItem = LOWORD(SendMessage(hwnd, LB_ITEMFROMPOINT, 0, lParam)); - ListBox_GetItemRect(hwnd, iItem, &dat->rcCheck); - - dat->rcCheck.right = dat->rcCheck.left + g_iIconSX + 4; - dat->rcCheck.bottom = dat->rcCheck.top + g_iIconSY + 4; - if (PtInRect(&dat->rcCheck, pt)) - dat->iItem = iItem; - else - dat->iItem = -1; - } - break; - - case WM_LBUTTONUP: - { - POINT pt = { LOWORD(lParam), HIWORD(lParam) }; - if ((dat->iItem >= 0) && PtInRect(&dat->rcCheck, pt)) - PostMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(hwnd, GWL_ID), LBN_MY_CHECK), (LPARAM)dat->iItem); - dat->iItem = -1; - } - break; - - case WM_CHAR: - if (wParam == ' ') { - int iItem = ListBox_GetCurSel(hwnd); - if (iItem >= 0) - PostMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(hwnd, GWL_ID), LBN_MY_CHECK), (LPARAM)iItem); - return 0; - } - - if (wParam == 10 /* enter */) - return 0; - - break; - - case WM_GETDLGCODE: - if (wParam == VK_RETURN) - return DLGC_WANTMESSAGE; - break; - - case WM_MY_RENAME: - RECT rc; - { - struct TAccMgrData *parentDat = (struct TAccMgrData *)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); - PROTOACCOUNT *pa = (PROTOACCOUNT *)ListBox_GetItemData(hwnd, ListBox_GetCurSel(hwnd)); - if (!pa || pa->bOldProto || pa->bDynDisabled) - return 0; - - ListBox_GetItemRect(hwnd, ListBox_GetCurSel(hwnd), &rc); - rc.left += 2 * g_iIconSX + 4; - rc.bottom = rc.top + max(g_iIconSX, parentDat->titleHeight) + 4 - 1; - ++rc.top; --rc.right; - - dat->hwndEdit = CreateWindow(_T("EDIT"), pa->tszAccountName, WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hwnd, NULL, g_hInst, NULL); - mir_subclassWindow(dat->hwndEdit, sttEditSubclassProc); - SendMessage(dat->hwndEdit, WM_SETFONT, (WPARAM)parentDat->hfntTitle, 0); - SendMessage(dat->hwndEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN | EC_USEFONTINFO, 0); - SendMessage(dat->hwndEdit, EM_SETSEL, 0, -1); - ShowWindow(dat->hwndEdit, SW_SHOW); - } - SetFocus(dat->hwndEdit); - break; - - case WM_KEYDOWN: - switch (wParam) { - case VK_F2: - PostMessage(hwnd, WM_MY_RENAME, 0, 0); - return 0; - - case VK_INSERT: - sttClickButton(GetParent(hwnd), IDC_ADD); - return 0; - - case VK_DELETE: - sttClickButton(GetParent(hwnd), IDC_REMOVE); - return 0; - - case VK_RETURN: - if (GetAsyncKeyState(VK_CONTROL)) - sttClickButton(GetParent(hwnd), IDC_EDIT); - else - sttClickButton(GetParent(hwnd), IDOK); - return 0; - } - break; - } - - return mir_callNextSubclass(hwnd, AccListWndProc, msg, wParam, lParam); -} - -static void sttSubclassAccList(HWND hwnd, BOOL subclass) -{ - if (subclass) { - struct TAccListData *dat = (struct TAccListData *)mir_alloc(sizeof(struct TAccListData)); - dat->iItem = -1; - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)dat); - mir_subclassWindow(hwnd, AccListWndProc); - } - else { - struct TAccListData *dat = (struct TAccListData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); - SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); - mir_free(dat); - } -} - -static void sttSelectItem(struct TAccMgrData *dat, HWND hwndList, int iItem) -{ - if ((dat->iSelected != iItem) && (dat->iSelected >= 0)) - ListBox_SetItemHeight(hwndList, dat->iSelected, dat->normalHeight); - - dat->iSelected = iItem; - ListBox_SetItemHeight(hwndList, dat->iSelected, dat->selectedHeight); - RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); -} - -static void sttUpdateAccountInfo(HWND hwndDlg, struct TAccMgrData *dat) -{ - HWND hwndList = GetDlgItem(hwndDlg, IDC_ACCLIST); - int curSel = ListBox_GetCurSel(hwndList); - if (curSel != LB_ERR) { - PROTOACCOUNT *pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, curSel); - if (pa) { - EnableWindow(GetDlgItem(hwndDlg, IDC_UPGRADE), pa->bOldProto || pa->bDynDisabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), !pa->bOldProto && !pa->bDynDisabled); - EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_OPTIONS), pa->ppro != 0); - - if (dat->iSelected >= 0) { - PROTOACCOUNT *pa_old = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, dat->iSelected); - if (pa_old && pa_old != pa && pa_old->hwndAccMgrUI) - ShowWindow(pa_old->hwndAccMgrUI, SW_HIDE); - } - - if (pa->hwndAccMgrUI) { - ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_HIDE); - ShowWindow(pa->hwndAccMgrUI, SW_SHOW); - } - else if (!pa->ppro) { - ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_SHOW); - SetDlgItemText(hwndDlg, IDC_TXT_INFO, TranslateT("Account is disabled. Please activate it to access options.")); - } - else { - HWND hwnd = (HWND)CallProtoService(pa->szModuleName, PS_CREATEACCMGRUI, 0, (LPARAM)hwndDlg); - if (hwnd && (hwnd != (HWND)CALLSERVICE_NOTFOUND)) { - RECT rc; - - ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_HIDE); - - GetWindowRect(GetDlgItem(hwndDlg, IDC_TXT_INFO), &rc); - MapWindowPoints(NULL, hwndDlg, (LPPOINT)&rc, 2); - SetWindowPos(hwnd, hwndList, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); - - pa->hwndAccMgrUI = hwnd; - } - else { - ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_SHOW); - SetDlgItemText(hwndDlg, IDC_TXT_INFO, legacyMsg); - } - } - return; - } - } - - EnableWindow(GetDlgItem(hwndDlg, IDC_UPGRADE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_OPTIONS), FALSE); - - ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_SHOW); - SetDlgItemText(hwndDlg, IDC_TXT_INFO, welcomeMsg); -} - -INT_PTR CALLBACK AccMgrDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - struct TAccMgrData *dat = (struct TAccMgrData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - HWND hwndList = GetDlgItem(hwndDlg, IDC_ACCLIST); - PROTOACCOUNT *pa; - int idx; - PSHNOTIFY pshn; - - switch (message) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - Window_SetIcon_IcoLib(hwndDlg, SKINICON_OTHER_ACCMGR); - - dat = (TAccMgrData *)mir_alloc(sizeof(TAccMgrData)); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); - - Button_SetIcon_IcoLib(hwndDlg, IDC_ADD, SKINICON_OTHER_ADDCONTACT, LPGEN("New account")); - Button_SetIcon_IcoLib(hwndDlg, IDC_EDIT, SKINICON_OTHER_RENAME, LPGEN("Edit")); - Button_SetIcon_IcoLib(hwndDlg, IDC_REMOVE, SKINICON_OTHER_DELETE, LPGEN("Remove account")); - Button_SetIcon_IcoLib(hwndDlg, IDC_OPTIONS, SKINICON_OTHER_OPTIONS, LPGEN("Configure...")); - Button_SetIcon_IcoLib(hwndDlg, IDC_UPGRADE, SKINICON_OTHER_ACCMGR, LPGEN("Upgrade account")); - - EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_OPTIONS), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_UPGRADE), FALSE); - { - LOGFONT lf; - GetObject((HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0), sizeof(lf), &lf); - dat->hfntText = CreateFontIndirect(&lf); - - GetObject((HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0), sizeof(lf), &lf); - lf.lfWeight = FW_BOLD; - dat->hfntTitle = CreateFontIndirect(&lf); - - HDC hdc = GetDC(hwndDlg); - HFONT hfnt = (HFONT)SelectObject(hdc, dat->hfntTitle); - - TEXTMETRIC tm; - GetTextMetrics(hdc, &tm); - dat->titleHeight = tm.tmHeight; - SelectObject(hdc, dat->hfntText); - - GetTextMetrics(hdc, &tm); - dat->textHeight = tm.tmHeight; - SelectObject(hdc, hfnt); - ReleaseDC(hwndDlg, hdc); - - dat->normalHeight = 4 + max(dat->titleHeight, g_iIconSY); - dat->selectedHeight = dat->normalHeight + 4 + 2 * dat->textHeight; - } - - SendDlgItemMessage(hwndDlg, IDC_NAME, WM_SETFONT, (WPARAM)dat->hfntTitle, 0); - SendDlgItemMessage(hwndDlg, IDC_TXT_ACCOUNT, WM_SETFONT, (WPARAM)dat->hfntTitle, 0); - SendDlgItemMessage(hwndDlg, IDC_TXT_ADDITIONAL, WM_SETFONT, (WPARAM)dat->hfntTitle, 0); - - dat->iSelected = -1; - sttSubclassAccList(GetDlgItem(hwndDlg, IDC_ACCLIST), TRUE); - SendMessage(hwndDlg, WM_MY_REFRESH, 0, 0); - - Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, "AccMgr", ""); - return TRUE; - - case WM_CTLCOLORSTATIC: - switch (GetDlgCtrlID((HWND)lParam)) { - case IDC_WHITERECT: - case IDC_NAME: - SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); - return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); - } - break; - - case WM_MEASUREITEM: - { - LPMEASUREITEMSTRUCT lps = (LPMEASUREITEMSTRUCT)lParam; - PROTOACCOUNT *acc = (PROTOACCOUNT *)lps->itemData; - - if ((lps->CtlID != IDC_ACCLIST) || !acc) - break; - - lps->itemWidth = 10; - lps->itemHeight = dat->normalHeight; - } - return TRUE; - - case WM_DRAWITEM: - HBRUSH hbrBack; - SIZE sz; - { - int cxIcon = g_iIconSX; - int cyIcon = g_iIconSY; - - LPDRAWITEMSTRUCT lps = (LPDRAWITEMSTRUCT)lParam; - PROTOACCOUNT *acc = (PROTOACCOUNT *)lps->itemData; - if ((lps->CtlID != IDC_ACCLIST) || (lps->itemID == -1) || !acc) - break; - - SetBkMode(lps->hDC, TRANSPARENT); - if (lps->itemState & ODS_SELECTED) { - hbrBack = GetSysColorBrush(COLOR_HIGHLIGHT); - SetTextColor(lps->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); - } - else { - hbrBack = GetSysColorBrush(COLOR_WINDOW); - SetTextColor(lps->hDC, GetSysColor(COLOR_WINDOWTEXT)); - } - FillRect(lps->hDC, &lps->rcItem, hbrBack); - - lps->rcItem.left += 2; - lps->rcItem.top += 2; - lps->rcItem.bottom -= 2; - - int tmp; - if (acc->bOldProto) - tmp = SKINICON_OTHER_ON; - else if (acc->bDynDisabled) - tmp = SKINICON_OTHER_OFF; - else - tmp = acc->bIsEnabled ? SKINICON_OTHER_TICK : SKINICON_OTHER_NOTICK; - - HICON hIcon = Skin_LoadIcon(tmp); - DrawIconEx(lps->hDC, lps->rcItem.left, lps->rcItem.top, hIcon, cxIcon, cyIcon, 0, hbrBack, DI_NORMAL); - IcoLib_ReleaseIcon(hIcon); - - lps->rcItem.left += cxIcon + 2; - - if (acc->ppro) { - hIcon = IcoLib_GetIconByHandle(acc->ppro->m_hProtoIcon); - DrawIconEx(lps->hDC, lps->rcItem.left, lps->rcItem.top, hIcon, cxIcon, cyIcon, 0, hbrBack, DI_NORMAL); - IcoLib_ReleaseIcon(hIcon); - } - lps->rcItem.left += cxIcon + 2; - - int length = SendDlgItemMessage(hwndDlg, IDC_ACCLIST, LB_GETTEXTLEN, lps->itemID, 0); - int size = max(length + 1, 256); - TCHAR *text = (TCHAR *)_alloca(sizeof(TCHAR) * size); - SendDlgItemMessage(hwndDlg, IDC_ACCLIST, LB_GETTEXT, lps->itemID, (LPARAM)text); - - SelectObject(lps->hDC, dat->hfntTitle); - tmp = lps->rcItem.bottom; - lps->rcItem.bottom = lps->rcItem.top + max(cyIcon, dat->titleHeight); - DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS | DT_VCENTER); - lps->rcItem.bottom = tmp; - GetTextExtentPoint32(lps->hDC, text, length, &sz); - lps->rcItem.top += max(cxIcon, sz.cy) + 2; - - if (lps->itemID == (unsigned)dat->iSelected) { - SelectObject(lps->hDC, dat->hfntText); - mir_sntprintf(text, size, _T("%s: %S"), TranslateT("Protocol"), acc->szProtoName); - length = (int)mir_tstrlen(text); - DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS); - GetTextExtentPoint32(lps->hDC, text, length, &sz); - lps->rcItem.top += sz.cy + 2; - - if (acc->ppro && Proto_IsProtocolLoaded(acc->szProtoName)) { - char *szIdName = (char *)acc->ppro->GetCaps(PFLAG_UNIQUEIDTEXT, 0); - TCHAR *tszIdName = szIdName ? mir_a2t(szIdName) : mir_tstrdup(TranslateT("Account ID")); - - CONTACTINFO ci = { 0 }; - ci.cbSize = sizeof(ci); - ci.hContact = NULL; - ci.szProto = acc->szModuleName; - ci.dwFlag = CNF_UNIQUEID | CNF_TCHAR; - if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)& ci)) { - switch (ci.type) { - case CNFT_ASCIIZ: - mir_sntprintf(text, size, _T("%s: %s"), tszIdName, ci.pszVal); - mir_free(ci.pszVal); - break; - case CNFT_DWORD: - mir_sntprintf(text, size, _T("%s: %d"), tszIdName, ci.dVal); - break; - } - } - else mir_sntprintf(text, size, _T("%s: %s"), tszIdName, TranslateT("")); - mir_free(tszIdName); - } - else mir_sntprintf(text, size, TranslateT("Protocol is not loaded.")); - - length = (int)mir_tstrlen(text); - DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS); - GetTextExtentPoint32(lps->hDC, text, length, &sz); - lps->rcItem.top += sz.cy + 2; - } - } - return TRUE; - - case WM_MY_REFRESH: - dat->iSelected = -1; - { - int i = ListBox_GetCurSel(hwndList); - PROTOACCOUNT *acc = (i == LB_ERR) ? NULL : (PROTOACCOUNT *)ListBox_GetItemData(hwndList, i); - - SendMessage(hwndList, LB_RESETCONTENT, 0, 0); - for (i = 0; i < accounts.getCount(); i++) { - PROTOACCOUNT *p = accounts[i]; - PROTOCOLDESCRIPTOR *pd = Proto_IsProtocolLoaded(p->szProtoName); - if (pd != NULL && pd->type != PROTOTYPE_PROTOCOL) - continue; - - int iItem = SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)p->tszAccountName); - SendMessage(hwndList, LB_SETITEMDATA, iItem, (LPARAM)p); - - if (p == acc) - ListBox_SetCurSel(hwndList, iItem); - } - - dat->iSelected = ListBox_GetCurSel(hwndList); // -1 if error = > nothing selected in our case - if (dat->iSelected >= 0) - sttSelectItem(dat, hwndList, dat->iSelected); - else if (acc && acc->hwndAccMgrUI) - ShowWindow(acc->hwndAccMgrUI, SW_HIDE); - } - sttUpdateAccountInfo(hwndDlg, dat); - break; - - case WM_CONTEXTMENU: - if (GetWindowLongPtr((HWND)wParam, GWL_ID) == IDC_ACCLIST) { - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - int iItem = ListBox_GetCurSel(hwndList); - - if (pt.x == -1 && pt.y == -1) { - if (iItem != LB_ERR) { - RECT rc; - ListBox_GetItemRect(hwndList, iItem, &rc); - pt.x = rc.left + g_iIconSX + 4; - pt.y = rc.top + 4 + max(g_iIconSX, dat->titleHeight); - ClientToScreen(hwndList, &pt); - } - } - else { - // menu was activated with mouse = > find item under cursor & set focus to our control. - POINT ptItem = pt; - ScreenToClient(hwndList, &ptItem); - iItem = (short)LOWORD(SendMessage(hwndList, LB_ITEMFROMPOINT, 0, MAKELPARAM(ptItem.x, ptItem.y))); - if (iItem != LB_ERR) { - ListBox_SetCurSel(hwndList, iItem); - sttUpdateAccountInfo(hwndDlg, dat); - sttSelectItem(dat, hwndList, iItem); - SetFocus(hwndList); - } - } - - if (iItem != LB_ERR) { - pa = (PROTOACCOUNT*)ListBox_GetItemData(hwndList, iItem); - HMENU hMenu = CreatePopupMenu(); - if (!pa->bOldProto && !pa->bDynDisabled) - AppendMenu(hMenu, MF_STRING, 1, TranslateT("Rename")); - - AppendMenu(hMenu, MF_STRING, 3, TranslateT("Delete")); - - if (Proto_IsAccountEnabled(pa)) - AppendMenu(hMenu, MF_STRING, 4, TranslateT("Configure")); - - if (pa->bOldProto || pa->bDynDisabled) - AppendMenu(hMenu, MF_STRING, 5, TranslateT("Upgrade")); - - switch (TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) { - case 1: - PostMessage(hwndList, WM_MY_RENAME, 0, 0); - break; - - case 2: - sttClickButton(hwndDlg, IDC_EDIT); - break; - - case 3: - sttClickButton(hwndDlg, IDC_REMOVE); - break; - - case 4: - sttClickButton(hwndDlg, IDC_OPTIONS); - break; - - case 5: - sttClickButton(hwndDlg, IDC_UPGRADE); - break; - } - DestroyMenu(hMenu); - } - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_ACCLIST: - switch (HIWORD(wParam)) { - case LBN_SELCHANGE: - sttUpdateAccountInfo(hwndDlg, dat); - sttSelectItem(dat, hwndList, ListBox_GetCurSel(hwndList)); - SetFocus(hwndList); - break; - - case LBN_DBLCLK: - PostMessage(hwndList, WM_MY_RENAME, 0, 0); - break; - - case LBN_MY_CHECK: - pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, lParam); - if (pa) { - if (pa->bOldProto || pa->bDynDisabled) - break; - - pa->bIsEnabled = !pa->bIsEnabled; - if (pa->bIsEnabled) { - if (ActivateAccount(pa)) { - pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0); - if (!db_get_b(NULL, "CList", "MoveProtoMenus", TRUE)) - pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0); - } - } - else { - DWORD dwStatus = CallProtoServiceInt(NULL, pa->szModuleName, PS_GETSTATUS, 0, 0); - if (dwStatus >= ID_STATUS_ONLINE) { - TCHAR buf[200]; - mir_sntprintf(buf, TranslateT("Account %s is being disabled"), pa->tszAccountName); - if (IDNO == ::MessageBox(hwndDlg, - TranslateT("Account is online. Disable account?"), - buf, MB_ICONWARNING | MB_DEFBUTTON2 | MB_YESNO)) { - pa->bIsEnabled = 1; //stay enabled - } - } - - if (!pa->bIsEnabled) - DeactivateAccount(pa, true, false); - } - - WriteDbAccounts(); - NotifyEventHooks(hAccListChanged, PRAC_CHECKED, (LPARAM)pa); - sttUpdateAccountInfo(hwndDlg, dat); - RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); - } - break; - - case LBN_MY_RENAME: - int iItem = ListBox_GetCurSel(hwndList); - pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, iItem); - if (pa) { - mir_free(pa->tszAccountName); - pa->tszAccountName = (TCHAR*)lParam; - WriteDbAccounts(); - NotifyEventHooks(hAccListChanged, PRAC_CHANGED, (LPARAM)pa); - - ListBox_DeleteString(hwndList, iItem); - iItem = ListBox_AddString(hwndList, pa->tszAccountName); - ListBox_SetItemData(hwndList, iItem, (LPARAM)pa); - ListBox_SetCurSel(hwndList, iItem); - - sttSelectItem(dat, hwndList, iItem); - - RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); - } - else mir_free((TCHAR*)lParam); - } - break; - - case IDC_ADD: - { - AccFormDlgParam param = { PRAC_ADDED, NULL }; - if (IDOK == DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_ACCFORM), hwndDlg, AccFormDlgProc, (LPARAM)¶m)) - SendMessage(hwndDlg, WM_MY_REFRESH, 0, 0); - } - break; - - case IDC_EDIT: - idx = ListBox_GetCurSel(hwndList); - if (idx != -1) - PostMessage(hwndList, WM_MY_RENAME, 0, 0); - break; - - case IDC_REMOVE: - idx = ListBox_GetCurSel(hwndList); - if (idx != -1) { - pa = (PROTOACCOUNT*)ListBox_GetItemData(hwndList, idx); - TCHAR buf[200]; - mir_sntprintf(buf, TranslateT("Account %s is being deleted"), pa->tszAccountName); - if (pa->bOldProto) { - MessageBox(hwndDlg, TranslateT("You need to disable plugin to delete this account"), buf, MB_ICONERROR | MB_OK); - break; - } - if (IDYES == MessageBox(hwndDlg, errMsg, buf, MB_ICONWARNING | MB_DEFBUTTON2 | MB_YESNO)) { - // lock controls to avoid changes during remove process - ListBox_SetCurSel(hwndList, -1); - sttUpdateAccountInfo(hwndDlg, dat); - EnableWindow(hwndList, FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); - - ListBox_SetItemData(hwndList, idx, 0); - - accounts.remove(pa); - - CheckProtocolOrder(); - - WriteDbAccounts(); - NotifyEventHooks(hAccListChanged, PRAC_REMOVED, (LPARAM)pa); - - UnloadAccount(pa, true, true); - SendMessage(hwndDlg, WM_MY_REFRESH, 0, 0); - - EnableWindow(hwndList, TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), TRUE); - } - } - break; - - case IDC_OPTIONS: - idx = ListBox_GetCurSel(hwndList); - if (idx != -1) { - pa = (PROTOACCOUNT*)ListBox_GetItemData(hwndList, idx); - if (pa->bOldProto) { - OPENOPTIONSDIALOG ood; - ood.cbSize = sizeof(ood); - ood.pszGroup = "Network"; - ood.pszPage = pa->szModuleName; - ood.pszTab = NULL; - Options_Open(&ood); - } - else OpenAccountOptions(pa); - } - break; - - case IDC_UPGRADE: - idx = ListBox_GetCurSel(hwndList); - if (idx != -1) { - AccFormDlgParam param = { PRAC_UPGRADED, (PROTOACCOUNT*)ListBox_GetItemData(hwndList, idx) }; - DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_ACCFORM), hwndDlg, AccFormDlgProc, (LPARAM)¶m); - } - break; - - case IDC_LNK_NETWORK: - pshn.hdr.idFrom = 0; - pshn.hdr.code = PSN_APPLY; - pshn.hdr.hwndFrom = hwndDlg; - SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&pshn); - { - OPENOPTIONSDIALOG ood = { 0 }; - ood.cbSize = sizeof(ood); - ood.pszPage = "Network"; - Options_Open(&ood); - } - break; - - case IDC_LNK_ADDONS: - CallService(MS_UTILS_OPENURL, OUF_NEWWINDOW, (LPARAM)"http://miranda-ng.org/"); - break; - - case IDOK: - pshn.hdr.idFrom = 0; - pshn.hdr.code = PSN_APPLY; - pshn.hdr.hwndFrom = hwndDlg; - SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&pshn); - DestroyWindow(hwndDlg); - break; - - case IDCANCEL: - pshn.hdr.idFrom = 0; - pshn.hdr.code = PSN_RESET; - pshn.hdr.hwndFrom = hwndDlg; - SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&pshn); - DestroyWindow(hwndDlg); - break; - } - break; - - case PSM_CHANGED: - idx = ListBox_GetCurSel(hwndList); - if (idx != -1) { - pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, idx); - if (pa) { - pa->bAccMgrUIChanged = TRUE; - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - break; - - case WM_NOTIFY: - if (((LPNMHDR)lParam)->idFrom == 0) { - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - pshn.hdr.idFrom = 0; - pshn.hdr.code = PSN_APPLY; - for (int i = 0; i < accounts.getCount(); i++) { - pa = accounts[i]; - if (pa->hwndAccMgrUI && pa->bAccMgrUIChanged) { - pshn.hdr.hwndFrom = pa->hwndAccMgrUI; - SendMessage(pa->hwndAccMgrUI, WM_NOTIFY, 0, (LPARAM)&pshn); - pa->bAccMgrUIChanged = FALSE; - } - } - return TRUE; - - case PSN_RESET: - pshn.hdr.idFrom = 0; - pshn.hdr.code = PSN_RESET; - for (int i = 0; i < accounts.getCount(); i++) { - pa = accounts[i]; - if (pa->hwndAccMgrUI && pa->bAccMgrUIChanged) { - pshn.hdr.hwndFrom = pa->hwndAccMgrUI; - SendMessage(pa->hwndAccMgrUI, WM_NOTIFY, 0, (LPARAM)&pshn); - pa->bAccMgrUIChanged = FALSE; - } - } - return TRUE; - } - } - break; - - case WM_DESTROY: - for (int i = 0; i < accounts.getCount(); i++) { - pa = accounts[i]; - pa->bAccMgrUIChanged = FALSE; - if (pa->hwndAccMgrUI) { - DestroyWindow(pa->hwndAccMgrUI); - pa->hwndAccMgrUI = NULL; - } - } - - Window_FreeIcon_IcoLib(hwndDlg); - Button_FreeIcon_IcoLib(hwndDlg, IDC_ADD); - Button_FreeIcon_IcoLib(hwndDlg, IDC_EDIT); - Button_FreeIcon_IcoLib(hwndDlg, IDC_REMOVE); - Button_FreeIcon_IcoLib(hwndDlg, IDC_OPTIONS); - Button_FreeIcon_IcoLib(hwndDlg, IDC_UPGRADE); - Utils_SaveWindowPosition(hwndDlg, NULL, "AccMgr", ""); - sttSubclassAccList(GetDlgItem(hwndDlg, IDC_ACCLIST), FALSE); - DeleteObject(dat->hfntTitle); - DeleteObject(dat->hfntText); - mir_free(dat); - hAccMgr = NULL; - break; - } - - return FALSE; -} - -static INT_PTR OptProtosShow(WPARAM, LPARAM) -{ - if (!hAccMgr) - hAccMgr = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_ACCMGR), NULL, AccMgrDlgProc, 0); - - ShowWindow(hAccMgr, SW_RESTORE); - SetForegroundWindow(hAccMgr); - SetActiveWindow(hAccMgr); - return 0; -} - -int OptProtosLoaded(WPARAM, LPARAM) -{ - CLISTMENUITEM mi = { sizeof(mi) }; - mi.icolibItem = Skin_GetIconHandle(SKINICON_OTHER_ACCMGR); - mi.position = 1900000000; - mi.pszName = LPGEN("&Accounts..."); - mi.pszService = MS_PROTO_SHOWACCMGR; - Menu_AddMainMenuItem(&mi); - return 0; -} - -static int OnAccListChanged(WPARAM eventCode, LPARAM lParam) -{ - PROTOACCOUNT *pa = (PROTOACCOUNT*)lParam; - - switch (eventCode) { - case PRAC_CHANGED: - if (pa->ppro) { - mir_free(pa->ppro->m_tszUserName); - pa->ppro->m_tszUserName = mir_tstrdup(pa->tszAccountName); - pa->ppro->OnEvent(EV_PROTO_ONRENAME, 0, lParam); - } - } - - return 0; -} - -static int ShutdownAccMgr(WPARAM, LPARAM) -{ - if (IsWindow(hAccMgr)) - DestroyWindow(hAccMgr); - hAccMgr = NULL; - return 0; -} - -int LoadProtoOptions(void) -{ - CreateServiceFunction(MS_PROTO_SHOWACCMGR, OptProtosShow); - - HookEvent(ME_SYSTEM_MODULESLOADED, OptProtosLoaded); - HookEvent(ME_PROTO_ACCLISTCHANGED, OnAccListChanged); - HookEvent(ME_SYSTEM_PRESHUTDOWN, ShutdownAccMgr); - return 0; -} -- cgit v1.2.3