From c75b4a71ab585492cebdc708e8145440afe72143 Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Mon, 21 Mar 2022 18:53:43 +0530 Subject: [PATCH 1/7] Update lib/crow to CppCrow/Crow (#52) * Update crow * use CROW_USE_LOCALTIMEZONE * Update response codes to valid http-codes - Remove 208, it is a WebDAV code and not supported by crow. - Remove 408, it is not required to respond in 408 scenari, and was incorrect use --- .github/workflows/main.yml | 2 +- .gitignore | 3 ++- .gitmodules | 2 +- lib/crow | 2 +- tinyphone/server.cpp | 19 +++++++++++-------- tinyphone/server.h | 10 ++++++---- 6 files changed, 22 insertions(+), 16 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6137cf05..21326d63 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -66,7 +66,7 @@ jobs: - name: Upload Artifacts uses: actions/upload-artifact@v2 with: - name: tinyphone + name: tinyphone.msi path: | ./tinyphone-installer/bin/Release/tinyphone_installer.msi diff --git a/.gitignore b/.gitignore index 97bfa7bd..0389ea63 100644 --- a/.gitignore +++ b/.gitignore @@ -263,4 +263,5 @@ GitHubVS.sln.DotSettings *.dll lib/datadog-cpp -logs/ \ No newline at end of file +logs/ +.vagrant/ diff --git a/.gitmodules b/.gitmodules index 42bdda5d..dbd2c757 100644 --- a/.gitmodules +++ b/.gitmodules @@ -9,7 +9,7 @@ url = https://github.com/xiph/opus.git [submodule "lib/crow"] path = lib/crow - url = git@github.com:kingster/crow.git + url = git@github.com:kingster/Crow.git [submodule "lib/boost"] path = lib/boost url = https://github.com/boostorg/boost.git diff --git a/lib/crow b/lib/crow index 3e5d33ca..588020ee 160000 --- a/lib/crow +++ b/lib/crow @@ -1 +1 @@ -Subproject commit 3e5d33ca8ace207b04480cb9bc0533eaa32add14 +Subproject commit 588020ee1c6c73ff079e57cafc6edd4d818e566e diff --git a/tinyphone/server.cpp b/tinyphone/server.cpp index c04f4c76..8c3723af 100644 --- a/tinyphone/server.cpp +++ b/tinyphone/server.cpp @@ -20,6 +20,8 @@ #include "portaudio.h" #include +#define CROW_MAIN + using namespace std; using namespace pj; using json = nlohmann::json; @@ -184,14 +186,14 @@ void TinyPhoneHttpServer::Start() { tp::MetricsClient.increment("api.login.exists"); try { phone.EnableAccount(existing_account); - return tp::response(208, { + return tp::response(200, { { "message", "Account already exists" }, { "account_name", account_name }, { "id", existing_account->getId() }, - { "result", 202 } + { "result", 200 } }); } catch(...) { - return tp::response(408, { + return tp::response(202, { { "message", "Account already exists, but login progress, please try again in sometime" }, { "account_name", account_name }, { "id", existing_account->getId() }, @@ -217,7 +219,7 @@ void TinyPhoneHttpServer::Start() { }); } else { - return tp::response(408, { + return tp::response(202, { { "message", "Account login still in progress" }, { "account_name", account_name }, { "result", 202 } @@ -716,7 +718,8 @@ void TinyPhoneHttpServer::Start() { auto tar_bytes = file_all_bytes(tmp_file); remove(tmp_file.c_str()); - auto response = crow::response(tar_bytes); + std::string data_str(tar_bytes.begin(), tar_bytes.end()); + auto response = crow::response(data_str); response.set_header("Content-Type", "application/octet-stream"); std::string ip_addr = local_ip_address(); @@ -739,11 +742,11 @@ void TinyPhoneHttpServer::Start() { json response = { {"message", "Server Shutdown Recieved"}, {"result", 401}, - {"source", req.remoteIpAddress}, + {"source", req.remote_ip_address}, }; - CROW_LOG_INFO << "Shutdown Request from client: " << req.remoteIpAddress; + CROW_LOG_INFO << "Shutdown Request from client: " << req.remote_ip_address; tp::MetricsClient.increment("api.exit"); - if (req.remoteIpAddress.compare("127.0.0.1") == 0) { + if (req.remote_ip_address.compare("127.0.0.1") == 0) { CROW_LOG_INFO << "Shutdown Request from localhost authenticated"; response["result"] = 200; app.stop(); diff --git a/tinyphone/server.h b/tinyphone/server.h index 3c9070dc..4bb05f7f 100644 --- a/tinyphone/server.h +++ b/tinyphone/server.h @@ -2,6 +2,7 @@ #ifndef SERVER_HEADER_FILE_H #define SERVER_HEADER_FILE_H +#define CROW_USE_LOCALTIMEZONE 1 #include #include @@ -29,15 +30,16 @@ class TinyPhoneHTTPLogHandler : public crow::ILogHandler { log_writer.close(); } - void log(const std::string &message, crow::LogLevel /*level*/) override { - log_writer << message ; + void log(const std::string message, crow::LogLevel /*level*/) { + log_writer << message << std::endl ; #ifdef _DEBUG - std::cout << message; + std::cout << message << std::endl ; #endif log_writer.flush(); } }; + struct TinyPhoneMiddleware { std::string message; @@ -103,4 +105,4 @@ class TinyPhoneHttpServer { }; #endif - \ No newline at end of file + From cd98d5a9c112c781dc5ddda008e2ef917b98364a Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Tue, 22 Mar 2022 15:20:12 +0530 Subject: [PATCH 2/7] Update Readme & github trigger --- .github/workflows/main.yml | 3 ++- README.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 21326d63..720baee4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,10 +1,11 @@ name: Tinyphone Build on: - release: push: branches: - master + tags: + - v* pull_request: branches: - master diff --git a/README.md b/README.md index b263f31d..5143a09e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Tinyphone Minimalist Softphone based on PJSIP with API Control -[![AppVeyor](https://img.shields.io/appveyor/ci/kingster/tinyphone)](https://ci.appveyor.com/project/kingster/tinyphone/) +[![Tinyphone Build](https://github.com/voiceip/tinyphone/actions/workflows/main.yml/badge.svg)](https://github.com/voiceip/tinyphone/actions/workflows/main.yml) ## Getting Started From 5b87c6438ecf6bd5b39647f84a979ec03cbca7aa Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Thu, 21 Apr 2022 19:53:42 +0530 Subject: [PATCH 3/7] Windows-2019 + VS2019 Changes (#53) - Use windows-2019 for win github ci - Use scoop/devel - Update Boost to 1.74.0 (boost_1_74_0-msvc-14.2-32.exe) - Update VS Project to 2019 - Update WindowsTargetPlatformVersion to 10.0 - Update PlatformToolset to v142 --- .github/workflows/docker.yaml | 9 ++-- .github/workflows/main.yml | 14 +++--- .gitmodules | 14 +++--- appveyor.yml | 50 +++++++++------------ distribution/docker/Dockerfile.base | 50 +++++++++++---------- distribution/docker/README.md | 2 +- distribution/docker/VsDevCmdPowerShell.bat | 3 -- distribution/docker/release.ps1 | 25 ++++++----- lib/json | 2 +- tinyphone-installer/actions/actions.vcxproj | 8 ++-- tinyphone/config.cpp | 2 +- tinyphone/tinyphone.vcxproj | 16 +++---- tinyphone/utils.h | 5 ++- 13 files changed, 97 insertions(+), 103 deletions(-) delete mode 100644 distribution/docker/VsDevCmdPowerShell.bat diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 6b3822b5..dfea7cb1 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -15,7 +15,7 @@ jobs: tinyphone_docker_job: if: github.event.label.name == 'ci/github' || github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'release' name: Build Tinyphone - runs-on: windows-2016 + runs-on: windows-2019 steps: - name: Checkout uses: actions/checkout@v2 @@ -45,9 +45,8 @@ jobs: - name: Build and Push tinyphone_base to registry if: contains(steps.changed_files.outputs.modified, 'Dockerfile.base') run: | - docker build --file=./distribution/docker/Dockerfile.base -t ghcr.io/${{ github.repository_owner }}/tinyphone_base:latest -t ghcr.io/${{ github.repository_owner }}/tinyphone_base:${{ steps.vars.outputs.sha_short }} ./distribution/docker - docker push ghcr.io/${{ github.repository_owner }}/tinyphone_base:latest - docker push ghcr.io/${{ github.repository_owner }}/tinyphone_base:${{ steps.vars.outputs.sha_short }} + docker build --file=./distribution/docker/Dockerfile.base -t ghcr.io/${{ github.repository_owner }}/tinyphone_base:vc2019 -t ghcr.io/${{ github.repository_owner }}/tinyphone_base:${{ steps.vars.outputs.sha_short }} ./distribution/docker + docker push ghcr.io/${{ github.repository_owner }}/tinyphone_base:vc2019 - name: Update CodeDir run : | sed -i 's/$env:CodeDir/C:\\Code\\tinyphone/g' ./distribution/docker/release.ps1 @@ -55,7 +54,7 @@ jobs: shell : bash - name: Build tinyphone run: | - cat ./distribution/docker/release.ps1 | docker run -v ${PWD}:"C:\Code\tinyphone" -i ghcr.io/${{ github.repository_owner }}/tinyphone_base:latest + cat ./distribution/docker/release.ps1 | docker run -v ${PWD}:"C:\Code\tinyphone" -i ghcr.io/${{ github.repository_owner }}/tinyphone_base:vc2019 - name: Upload Artifacts uses: actions/upload-artifact@v2 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 720baee4..a128c24d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,7 +4,7 @@ on: push: branches: - master - tags: + tags: - v* pull_request: branches: @@ -13,7 +13,7 @@ on: jobs: tinyphone_win_job: name: Build Tinyphone Windows - runs-on: windows-2016 + runs-on: windows-2019 steps: - name: Checkout uses: actions/checkout@v2 @@ -29,15 +29,15 @@ jobs: uses: actions/cache@v2 id: cache-boost with: - path: C:\local\boost_1_68_0 - key: boost + path: C:\local\boost_1_74_0 + key: boost-74 - name: Install Boost if: steps.cache-boost.outputs.cache-hit != 'true' run: | - # Use the boost_1_72_0-msvc-14.1-64.exe for Windows 2016 - $Url = "https://boost.teeks99.com/bin/1.68.0/boost_1_68_0-msvc-14.0-32.exe" + # Use the boost_1_74_0-msvc-14.1-64.exe for Windows 2019 + $Url = "https://onboardcloud.dl.sourceforge.net/project/boost/boost-binaries/1.74.0/boost_1_74_0-msvc-14.2-32.exe" (New-Object System.Net.WebClient).DownloadFile($Url, "$env:TEMP\boost.exe") - Start-Process -Wait -FilePath "$env:TEMP\boost.exe" "/SILENT","/SP-","/SUPPRESSMSGBOXES","/DIR=C:\local\boost_1_68_0" + Start-Process -Wait -FilePath "$env:TEMP\boost.exe" "/SILENT","/SP-","/SUPPRESSMSGBOXES","/DIR=C:\local\boost_1_74_0" - name: Install Scoop & Binaries run : | diff --git a/.gitmodules b/.gitmodules index dbd2c757..a50af69e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "lib/pjproject"] path = lib/pjproject - url = git@github.com:voiceip/pjproject.git + url = https://github.com/voiceip/pjproject.git [submodule "lib/vp8vfw"] path = lib/vp8vfw url = https://github.com/XhmikosR/vp8vfw.git @@ -9,7 +9,7 @@ url = https://github.com/xiph/opus.git [submodule "lib/crow"] path = lib/crow - url = git@github.com:kingster/Crow.git + url = https://github.com/kingster/Crow.git [submodule "lib/boost"] path = lib/boost url = https://github.com/boostorg/boost.git @@ -21,16 +21,16 @@ url = https://github.com/curl/curl.git [submodule "lib/bcg729"] path = lib/bcg729 - url = git@github.com:BelledonneCommunications/bcg729.git + url = https://github.com/BelledonneCommunications/bcg729.git [submodule "lib/cryptopp"] path = lib/cryptopp - url = git@github.com:weidai11/cryptopp.git + url = https://github.com/weidai11/cryptopp.git [submodule "lib/portaudio"] path = lib/portaudio - url = git@github.com:voiceip/portaudio.git + url = https://github.com/voiceip/portaudio.git [submodule "lib/statsd-cpp"] path = lib/statsd-cpp - url = git@github.com:voiceip/statsd-cpp.git + url = https://github.com/voiceip/statsd-cpp.git [submodule "tinyphone-osx/vendor/boost"] path = tinyphone-osx/vendor/boost - url = git@github.com:faithfracture/Apple-Boost-BuildScript.git + url = https://github.com/faithfracture/Apple-Boost-BuildScript.git diff --git a/appveyor.yml b/appveyor.yml index 2a09af2d..a57608ce 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,5 @@ version: 1.0.{build} -image: Visual Studio 2017 +image: Visual Studio 2019 clone_depth: 5 init: - ps: >- @@ -10,10 +10,10 @@ branches: only: - master install: -- appveyor DownloadFile https://master.dl.sourceforge.net/project/boost/boost-binaries/1.68.0/boost_1_68_0-msvc-14.0-32.exe -- call boost_1_68_0-msvc-14.0-32.exe /SILENT +- appveyor DownloadFile https://onboardcloud.dl.sourceforge.net/project/boost/boost-binaries/1.74.0/boost_1_74_0-msvc-14.2-32.exe +- call boost_1_74_0-msvc-14.2-32.exe /SILENT - ps : | - ls "C:\local\boost_1_68_0" + ls "C:\local\boost_1_74_0" # Install Scoop iwr -useb get.scoop.sh -outfile 'install_scoop.ps1' @@ -34,14 +34,7 @@ build_script: cmd /c subst E: C:\projects\tinyphone - cd E:\lib\curl\ - ls - .\buildconf.bat - cd E:\lib\curl\winbuild - - ls - - pushd "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools" + pushd "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools" cmd /c "VsDevCmd.bat&set" | foreach { if ($_ -match "=") { @@ -49,28 +42,27 @@ build_script: } } popd - Write-Host "`nVisual Studio 2017 Command Prompt variables set." -ForegroundColor Yellow + Write-Host "`nVisual Studio 2019 Command Prompt variables set." -ForegroundColor Yellow - where.exe msbuild.exe - - nmake /f Makefile.vc mode=dll VC=15 DEBUG=no - - cd E:\lib\curl\builds + cd E:\lib\curl\ + ls + .\buildconf.bat + cd E:\lib\curl\winbuild - ls + where.exe msbuild.exe + nmake /f Makefile.vc mode=dll VC=19 DEBUG=no - cmd /c MKLINK /D E:\lib\curl\builds\libcurl-vc-x86-release-dll-ipv6-sspi-winssl E:\lib\curl\builds\libcurl-vc15-x86-release-dll-ipv6-sspi-winssl - ls E:\lib\curl\builds - cmd /c .\libcurl-vc15-x86-release-dll-ipv6-sspi-winssl\bin\curl.exe https://wttr.in/bangalore + cmd /c MKLINK /D E:\lib\curl\builds\libcurl-vc-x86-release-dll-ipv6-sspi-winssl E:\lib\curl\builds\libcurl-vc19-x86-release-dll-ipv6-sspi-winssl + cmd /c .\libcurl-vc19-x86-release-dll-ipv6-sspi-winssl\bin\curl.exe https://wttr.in/bangalore #G729 cd E:\lib\bcg729\build\ - cmake .. - msbuild /m bcg729.sln /p:Configuration=$BuildMode /p:Platform=Win32 + cmake .. -A Win32 + msbuild /m bcg729.sln /p:Configuration=$BuildMode /p:Platform=Win32 /p:PlatformToolset=v142 if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) } cd E:\lib\cryptopp - msbuild /m cryptlib.vcxproj /p:Configuration=$BuildMode /p:Platform=Win32 /p:PlatformToolset=v140_xp + msbuild /m cryptlib.vcxproj /p:Configuration=$BuildMode /p:Platform=Win32 /p:PlatformToolset=v142 if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) } $wc = New-Object net.webclient; $wc.Downloadfile("https://download.steinberg.net/sdk_downloads/asiosdk_2.3.3_2019-06-14.zip", "E:\lib\portaudio\src\hostapi\asio\asiosdk_2.3.3_2019-06-14.zip") @@ -78,23 +70,23 @@ build_script: unzip asiosdk_2.3.3_2019-06-14.zip mv asiosdk_2.3.3_2019-06-14 ASIOSDK cd E:\lib\portaudio\build\msvc - msbuild /m portaudio.sln /p:Configuration=$BuildMode /p:Platform=Win32 + msbuild /m portaudio.sln /p:Configuration=$BuildMode /p:Platform=Win32 /p:PlatformToolset=v142 /p:WindowsTargetPlatformVersion=10.0 if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) } cd E:\lib\pjproject - msbuild /m pjproject-vs14.sln -target:libpjproject:Rebuild /p:Configuration=$BuildMode-Static /p:Platform=Win32 + msbuild /m pjproject-vs14.sln -target:libpjproject:Rebuild /p:Configuration=$BuildMode-Static /p:Platform=Win32 /p:PlatformToolset=v142 if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) } cd E:\lib\statsd-cpp cmake . - msbuild /m statsd-cpp.vcxproj /p:Configuration=$BuildMode /p:Platform=Win32 + msbuild /m statsd-cpp.vcxproj /p:Configuration=$BuildMode /p:Platform=Win32 /p:PlatformToolset=v142 /p:WindowsTargetPlatformVersion=10.0 if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) } cd E:\tinyphone sed -i 's/stampver.inf.*\$/stampver.inf $/g' tinyphone.vcxproj - msbuild /m tinyphone.sln /p:Configuration=$BuildMode /p:Platform=x86 + msbuild /m tinyphone.sln /p:Configuration=$BuildMode /p:Platform=x86 /p:PlatformToolset=v142 /p:WindowsTargetPlatformVersion=10.0 if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) } Write-Host "`nBuild Completed." -ForegroundColor Yellow diff --git a/distribution/docker/Dockerfile.base b/distribution/docker/Dockerfile.base index a02acd7d..ef6d858f 100644 --- a/distribution/docker/Dockerfile.base +++ b/distribution/docker/Dockerfile.base @@ -1,5 +1,5 @@ # escape=` -FROM mcr.microsoft.com/dotnet/framework/runtime:3.5-windowsservercore-ltsc2016 +FROM mcr.microsoft.com/dotnet/framework/runtime:3.5-windowsservercore-ltsc2019 MAINTAINER Kinshuk B (hi@kinsh.uk) RUN powershell.exe mkdir C:\BuildTools @@ -11,15 +11,25 @@ SHELL ["cmd", "/S", "/C"] COPY Install.cmd C:\TEMP\ ADD https://aka.ms/vscollect.exe C:\TEMP\collect.exe -# Download and install Build Tools 14.0 -ADD https://download.microsoft.com/download/E/E/D/EEDF18A8-4AED-4CE0-BEBE-70A83094FC5A/BuildTools_Full.exe C:\TEMP\msbuild14.exe -RUN start /wait C:\TEMP\msbuild14.exe /q /full /log C:\TEMP\msbuild14.log +# Install Scoop +RUN powershell.exe [Net.ServicePointManager]::SecurityProtocol =[Net.SecurityProtocolType]::Tls12 ; (New-Object System.Net.WebClient).DownloadFile('https://get.scoop.sh', 'install_scoop.ps1'); .\install_scoop.ps1 -RunAsAdmin + +# Use devel branch of scoop due to https://github.com/ScoopInstaller/Scoop/issues/4792 +RUN scoop config SCOOP_BRANCH develop ; scoop update + +# Install Git & other tools +RUN powershell.exe scoop install git curl wget openssh unzip make sed; +RUN powershell.exe [environment]::setenvironmentvariable('GIT_SSH', (resolve-path (scoop which ssh)), 'USER'); + +# Download channel for fixed install. +RUN curl -L https://aka.ms/vs/16/release/channel -o C:\TEMP\VisualStudio.chman # Download channel for fixed install. -ADD https://aka.ms/vs/15/release/channel C:\TEMP\VisualStudio.chman +# ADD https://aka.ms/vs/16/release/channel C:\TEMP\VisualStudio.chman + +# Download and install Build Tools for Visual Studio 2019 for native desktop workload. +ADD https://aka.ms/vs/16/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe -# Download and install Build Tools for Visual Studio 2017 for native desktop workload. -ADD https://aka.ms/vs/15/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe RUN C:\TEMP\Install.cmd C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache ` --channelUri C:\TEMP\VisualStudio.chman ` --installChannelUri C:\TEMP\VisualStudio.chman ` @@ -27,24 +37,22 @@ RUN C:\TEMP\Install.cmd C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --n --add Microsoft.Component.MSBuild ` --add Microsoft.VisualStudio.Component.VC.140 ` --add Microsoft.VisualStudio.Component.WinXP ` + --add Microsoft.VisualStudio.Component.VC.ATLMFC ` + --add Microsoft.VisualStudio.Component.VC.ATL ` + --add Microsoft.VisualStudio.Component.VC.Modules.x86.x64 ` # --remove Microsoft.VisualStudio.Component.Windows10SDK.10240 ` # --remove Microsoft.VisualStudio.Component.Windows10SDK.10586 ` # --remove Microsoft.VisualStudio.Component.Windows10SDK.14393 ` - # --remove Microsoft.VisualStudio.Component.Windows81SDK ` + --remove Microsoft.VisualStudio.Component.Windows81SDK ` --installPath C:\BuildTools + # --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\BuildTools" # Verify if .NET isn't broken (bug with the ltsc2016 docker image) # RUN powershell.exe -Command echo Everything is OK -# Install Scoop -RUN powershell.exe [Net.ServicePointManager]::SecurityProtocol =[Net.SecurityProtocolType]::Tls12 ; Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh'); - -# Install Git & other tools -RUN powershell.exe scoop install git curl wget cmake win32-openssh unzip make; -RUN powershell.exe [environment]::setenvironmentvariable('GIT_SSH', (resolve-path (scoop which ssh)), 'USER'); -ADD https://boost.teeks99.com/bin/1.68.0/boost_1_68_0-msvc-14.0-32.exe C:\TEMP\boost_1_68_0-msvc-14.0-32.exe -RUN cmd.exe /c C:\TEMP\boost_1_68_0-msvc-14.0-32.exe /SILENT +ADD https://onboardcloud.dl.sourceforge.net/project/boost/boost-binaries/1.74.0/boost_1_74_0-msvc-14.2-32.exe C:\TEMP\boost.exe +RUN cmd.exe /c C:\TEMP\boost.exe /SILENT ADD https://github.com/wixtoolset/wix3/releases/download/wix3112rtm/wix311.exe C:\TEMP\wix311.exe RUN powershell.exe C:\TEMP\Install.cmd C:\TEMP\wix311.exe /install /quiet /norestart @@ -57,11 +65,7 @@ RUN powershell.exe Remove-Item -LiteralPath 'C:\Program Files\WindowsPowerShell\ WORKDIR C:\BuildTools -ADD VsDevCmdPowerShell.bat C:\BuildTools\ -ENTRYPOINT C:\BuildTools\VsDevCmdPowerShell.bat - -# Start developer command prompt with any other commands specified. -# ENTRYPOINT C:\BuildTools\Common7\Tools\VsDevCmd.bat && +# Define the entry point for the Docker container. +# This entry point starts the developer command prompt and launches the PowerShell shell. +ENTRYPOINT ["C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"] -# Default to PowerShell if no other command specified. -# CMD ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"] diff --git a/distribution/docker/README.md b/distribution/docker/README.md index b589fb4c..b44c878b 100644 --- a/distribution/docker/README.md +++ b/distribution/docker/README.md @@ -8,5 +8,5 @@ docker build -f Dockerfile.base -m 2G -t tinyphone_base . ``` sed -i 's/$env:CodeDir/C:\\Code\\tinyphone/g' ./distribution/docker/release.ps1 -cat ./distribution/docker/release.ps1 | docker run -v `pwd`:"C:\Code\tinyphone" -i tinyphone_base +cat ./distribution/docker/release.ps1 | docker run -v ${PWD}:"C:\Code\tinyphone" -i tinyphone_base ``` diff --git a/distribution/docker/VsDevCmdPowerShell.bat b/distribution/docker/VsDevCmdPowerShell.bat deleted file mode 100644 index be9afe7a..00000000 --- a/distribution/docker/VsDevCmdPowerShell.bat +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -call C:\BuildTools\Common7\Tools\VsDevCmd.bat -powershell.exe -NoLogo -ExecutionPolicy Bypass %* diff --git a/distribution/docker/release.ps1 b/distribution/docker/release.ps1 index d9d1c319..a678b1e9 100644 --- a/distribution/docker/release.ps1 +++ b/distribution/docker/release.ps1 @@ -17,37 +17,38 @@ cd E:\lib\curl\ cd E:\lib\curl\winbuild where.exe msbuild.exe -nmake /f Makefile.vc mode=dll VC=15 MACHINE=x86 DEBUG=no +nmake /f Makefile.vc mode=dll VC=19 MACHINE=x86 DEBUG=no -cmd /c MKLINK /D E:\lib\curl\builds\libcurl-vc-x86-release-dll-ipv6-sspi-winssl E:\lib\curl\builds\libcurl-vc15-x86-release-dll-ipv6-sspi-winssl -cmd /c E:\lib\curl\builds\libcurl-vc15-x86-release-dll-ipv6-sspi-winssl\bin\curl.exe https://wttr.in/bangalore +cmd /c MKLINK /D E:\lib\curl\builds\libcurl-vc-x86-release-dll-ipv6-sspi-winssl E:\lib\curl\builds\libcurl-vc19-x86-release-dll-ipv6-sspi-winssl +cmd /c E:\lib\curl\builds\libcurl-vc19-x86-release-dll-ipv6-sspi-winssl\bin\curl.exe https://wttr.in/bangalore #G729 cd E:\lib\bcg729\build\ -cmake .. -msbuild /m bcg729.sln /p:Configuration=$BuildMode /p:Platform=Win32 +cmake .. -A Win32 +msbuild /m bcg729.sln /p:Configuration=$BuildMode /p:Platform=Win32 /p:PlatformToolset=v142 #cryptopp cd E:\lib\cryptopp -msbuild /m cryptlib.vcxproj /p:Configuration=$BuildMode /p:Platform=Win32 /p:PlatformToolset=v140_xp +msbuild /m cryptlib.vcxproj /p:Configuration=$BuildMode /p:Platform=Win32 /p:PlatformToolset=v142 #portaudio -$wc = New-Object net.webclient; $wc.Downloadfile("https://download.steinberg.net/sdk_downloads/asiosdk_2.3.3_2019-06-14.zip", "E:\lib\portaudio\src\hostapi\asio\asiosdk_2.3.3_2019-06-14.zip") +curl "https://download.steinberg.net/sdk_downloads/asiosdk_2.3.3_2019-06-14.zip" -o "E:\lib\portaudio\src\hostapi\asio\asiosdk_2.3.3_2019-06-14.zip" cd E:\lib\portaudio\src\hostapi\asio -unzip asiosdk_2.3.3_2019-06-14.zip +Expand-Archive -LiteralPath E:\lib\portaudio\src\hostapi\asio\asiosdk_2.3.3_2019-06-14.zip -DestinationPath E:\lib\portaudio\src\hostapi\asio -Force + mv asiosdk_2.3.3_2019-06-14 ASIOSDK cd E:\lib\portaudio\build\msvc -msbuild /m portaudio.sln /p:Configuration=$BuildMode /p:Platform=Win32 +msbuild /m portaudio.sln /p:Configuration=$BuildMode /p:Platform=Win32 /p:PlatformToolset=v142 /p:WindowsTargetPlatformVersion=10.0 #pjproject cd E:\lib\pjproject -msbuild /m pjproject-vs14.sln -target:libpjproject:Rebuild /p:Configuration=$BuildMode-Static /p:Platform=Win32 +msbuild /m pjproject-vs14.sln -target:libpjproject:Rebuild /p:Configuration=$BuildMode-Static /p:Platform=Win32 /p:PlatformToolset=v142 #statsd-cpp cd E:\lib\statsd-cpp cmake . -msbuild /m statsd-cpp.vcxproj /p:Configuration=$BuildMode /p:Platform=Win32 +msbuild /m statsd-cpp.vcxproj /p:Configuration=$BuildMode /p:Platform=Win32 /p:PlatformToolset=v142 /p:WindowsTargetPlatformVersion=10.0 #tinyphone cd E:\tinyphone @@ -55,7 +56,7 @@ sed -i 's/stampver.inf.*\$/stampver.inf $/g' tinyphone.vcxproj #msbuild /m tinyphone.sln -target:tinyphone /p:Configuration=$BuildMode /p:Platform=x86 #msbuild /m tinyphone.sln -target:tinyphone:Rebuild /p:Configuration=$BuildMode /p:Platform=x86 -msbuild /m tinyphone.sln /p:Configuration=$BuildMode /p:Platform=x86 +msbuild /m tinyphone.sln /p:Configuration=$BuildMode /p:Platform=x86 /p:PlatformToolset=v142 /p:WindowsTargetPlatformVersion=10.0 #required for github-ci permission issue. diff --git a/lib/json b/lib/json index ef90d62d..4f8fba14 160000 --- a/lib/json +++ b/lib/json @@ -1 +1 @@ -Subproject commit ef90d62ddf4713f0ca1029d6884997f2a073ca60 +Subproject commit 4f8fba14066156b73f1189a2b8bd568bde5284c5 diff --git a/tinyphone-installer/actions/actions.vcxproj b/tinyphone-installer/actions/actions.vcxproj index 27e90d9b..9409f6d3 100644 --- a/tinyphone-installer/actions/actions.vcxproj +++ b/tinyphone-installer/actions/actions.vcxproj @@ -23,13 +23,13 @@ Win32Proj actions installer-actions - 8.1 + 10.0 DynamicLibrary true - v140_xp + v142 Unicode false @@ -43,14 +43,14 @@ DynamicLibrary true - v140 + v142 Unicode Dynamic DynamicLibrary false - v140 + v142 true Unicode diff --git a/tinyphone/config.cpp b/tinyphone/config.cpp index 2d6ec8b5..0cc315c2 100644 --- a/tinyphone/config.cpp +++ b/tinyphone/config.cpp @@ -1,8 +1,8 @@ #include "stdafx.h" +#include #include "config.h" #include "net.h" #include "utils.h" -#include #include "crypt.h" #ifdef __APPLE__ diff --git a/tinyphone/tinyphone.vcxproj b/tinyphone/tinyphone.vcxproj index 1d64337c..c671a80a 100644 --- a/tinyphone/tinyphone.vcxproj +++ b/tinyphone/tinyphone.vcxproj @@ -22,13 +22,13 @@ {968AADC8-5E16-44C2-919C-48683EF6729E} Win32Proj tinyphone - 8.1 + 10.0 Application true - v140_xp + v142 MultiByte false @@ -43,13 +43,13 @@ Application true - v140 + v142 Unicode Application false - v140 + v142 true Unicode @@ -90,14 +90,14 @@ Disabled WIN32;_DEBUG;_CONSOLE;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true - E:\lib\statsd-cpp\include;E:\lib\portaudio\include;..\lib;..\lib\curl\include;..\lib\json\single_include;C:\local\boost_1_68_0;..\lib\crow\include;..\lib\pjproject\pjnath\include;..\lib\pjproject\pjmedia\include;..\lib\pjproject\pjlib-util\include;..\lib\pjproject\pjlib\include;..\lib\pjproject\pjsip\include;%(AdditionalIncludeDirectories) + E:\lib\statsd-cpp\include;E:\lib\portaudio\include;..\lib;..\lib\curl\include;..\lib\json\single_include;C:\local\boost_1_74_0;..\lib\crow\include;..\lib\pjproject\pjnath\include;..\lib\pjproject\pjmedia\include;..\lib\pjproject\pjlib-util\include;..\lib\pjproject\pjlib\include;..\lib\pjproject\pjsip\include;%(AdditionalIncludeDirectories) MultiThreadedDebug true Windows true - ..\lib\portaudio\build\msvc\Win32\Debug;..\lib\cryptopp\Win32\Output\Debug;..\lib\bcg729\build\src\Debug;..\lib\curl\builds\libcurl-vc-x86-release-dll-ipv6-sspi-winssl\lib;C:\local\boost_1_68_0\lib32-msvc-14.0;..\lib\opus\win32\VS2015\Win32\Debug;..\lib\vp8vfw\vp8\lib\Win32;..\lib\pjproject\pjsip\lib;..\lib\pjproject\pjnath\lib;..\lib\pjproject\pjmedia\lib;..\lib\pjproject\pjlib-util\lib;..\lib\pjproject\pjlib\lib;..\lib\pjproject\lib;%(AdditionalLibraryDirectories) + ..\lib\portaudio\build\msvc\Win32\Debug;..\lib\cryptopp\Win32\Output\Debug;..\lib\bcg729\build\src\Debug;..\lib\curl\builds\libcurl-vc-x86-release-dll-ipv6-sspi-winssl\lib;C:\local\boost_1_74_0\lib32-msvc-14.2;..\lib\opus\win32\VS2015\Win32\Debug;..\lib\vp8vfw\vp8\lib\Win32;..\lib\pjproject\pjsip\lib;..\lib\pjproject\pjnath\lib;..\lib\pjproject\pjmedia\lib;..\lib\pjproject\pjlib-util\lib;..\lib\pjproject\pjlib\lib;..\lib\pjproject\lib;%(AdditionalLibraryDirectories) Wtsapi32.lib;ws2_32.lib;libcurl.lib;version.lib;cryptlib.lib;bcg729.lib;winmm.lib;iphlpapi.lib;portaudio_x86.lib;%(AdditionalDependencies) false @@ -133,7 +133,7 @@ true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - E:\lib\statsd-cpp\include;E:\lib\portaudio\include;..\lib;..\lib\curl\include;..\lib\json\single_include;C:\local\boost_1_68_0;..\lib\crow\include;..\lib\pjproject\pjnath\include;..\lib\pjproject\pjmedia\include;..\lib\pjproject\pjlib-util\include;..\lib\pjproject\pjlib\include;..\lib\pjproject\pjsip\include;%(AdditionalIncludeDirectories) + E:\lib\statsd-cpp\include;E:\lib\portaudio\include;..\lib;..\lib\curl\include;..\lib\json\single_include;C:\local\boost_1_74_0;..\lib\crow\include;..\lib\pjproject\pjnath\include;..\lib\pjproject\pjmedia\include;..\lib\pjproject\pjlib-util\include;..\lib\pjproject\pjlib\include;..\lib\pjproject\pjsip\include;%(AdditionalIncludeDirectories) true @@ -141,7 +141,7 @@ true true false - ..\lib\portaudio\build\msvc\Win32\Release;..\lib\cryptopp\Win32\Output\Release;..\lib\bcg729\build\src\Release;..\lib\curl\builds\libcurl-vc-x86-release-dll-ipv6-sspi-winssl\lib;C:\local\boost_1_68_0\lib32-msvc-14.0;..\lib\opus\win32\VS2015\Win32\Debug;..\lib\vp8vfw\vp8\lib\Win32;..\lib\pjproject\pjsip\lib;..\lib\pjproject\pjnath\lib;..\lib\pjproject\pjmedia\lib;..\lib\pjproject\pjlib-util\lib;..\lib\pjproject\pjlib\lib;..\lib\pjproject\lib;%(AdditionalLibraryDirectories) + ..\lib\portaudio\build\msvc\Win32\Release;..\lib\cryptopp\Win32\Output\Release;..\lib\bcg729\build\src\Release;..\lib\curl\builds\libcurl-vc-x86-release-dll-ipv6-sspi-winssl\lib;C:\local\boost_1_74_0\lib32-msvc-14.2;..\lib\opus\win32\VS2015\Win32\Debug;..\lib\vp8vfw\vp8\lib\Win32;..\lib\pjproject\pjsip\lib;..\lib\pjproject\pjnath\lib;..\lib\pjproject\pjmedia\lib;..\lib\pjproject\pjlib-util\lib;..\lib\pjproject\pjlib\lib;..\lib\pjproject\lib;%(AdditionalLibraryDirectories) Wtsapi32.lib;ws2_32.lib;libcurl.lib;version.lib;cryptlib.lib;bcg729.lib;winmm.lib;iphlpapi.lib;portaudio_x86.lib;%(AdditionalDependencies) false diff --git a/tinyphone/utils.h b/tinyphone/utils.h index d5ee6ff0..2c684028 100644 --- a/tinyphone/utils.h +++ b/tinyphone/utils.h @@ -4,10 +4,13 @@ #define UTILS_HEADER_FILE_H #ifdef _MSC_VER +#if _MSC_VER < 1500 // VC++ 8.0 and below #define snprintf _snprintf #define vsnprintf _vsnprintf #endif +#endif +#include #include #include #include @@ -18,8 +21,6 @@ #include #include "consts.h" -#include - #include #include From e21cc5806d06cc61a0929cf63d34e706b3641d20 Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Fri, 22 Apr 2022 00:31:46 +0530 Subject: [PATCH 4/7] Bugfix: crash when dns server list is > 4 (#54) --- tinyphone-osx/src/osxapp.cpp | 1 - tinyphone/baseapp.cpp | 14 +++++++++----- tinyphone/stampver.inf | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/tinyphone-osx/src/osxapp.cpp b/tinyphone-osx/src/osxapp.cpp index 22b6059d..cbc163a9 100644 --- a/tinyphone-osx/src/osxapp.cpp +++ b/tinyphone-osx/src/osxapp.cpp @@ -45,7 +45,6 @@ namespace tp { if (family == AF_INET) { // IPV4 address char str[INET_ADDRSTRLEN]; // String representation of address inet_ntop(AF_INET, & (res->nsaddr_list[i].sin_addr.s_addr), str, INET_ADDRSTRLEN); - // std::cout << "DNS: " << str << std::endl ; dnsServers.push_back(str); } else if (family == AF_INET6) { // IPV6 address diff --git a/tinyphone/baseapp.cpp b/tinyphone/baseapp.cpp index 09dbb57c..cf076d12 100644 --- a/tinyphone/baseapp.cpp +++ b/tinyphone/baseapp.cpp @@ -10,10 +10,13 @@ #include "tpendpoint.h" #include +#include using namespace std; using namespace pj; +#define MAX_DNS_SERVERS 4 + inline void pj_logerror(pj_status_t status, char * message) { if (status != PJ_SUCCESS) { CROW_LOG_ERROR << "pjsua returned error : " << status; @@ -99,14 +102,15 @@ namespace tp { pj_dns_resolver* resolver; pj_logerror(pjsip_endpt_create_resolver(endpt, &resolver),"pjsip_endpt_create_resolver"); - struct pj_str_t servers[4]; - for (unsigned int i = 0; i < dnsServers.size() ; ++i) { - pj_cstr(&servers[i], dnsServers.at(i).c_str()); + struct pj_str_t servers[MAX_DNS_SERVERS]; + int dnsServersCount = min(static_cast(dnsServers.size()), MAX_DNS_SERVERS); + for (unsigned int i = 0; i < dnsServersCount; ++i) { + pj_cstr(&servers[i], dnsServers.at(i).c_str()); } - pj_dns_resolver_set_ns(resolver, dnsServers.size(), servers, NULL); + pj_dns_resolver_set_ns(resolver, dnsServersCount, servers, NULL); pjsip_endpt_set_resolver(endpt, resolver); - CROW_LOG_INFO << "PJSUA2 Set DNS Resolvers Done... : " << dnsServers.size(); + CROW_LOG_INFO << "PJSUA2 Set DNS Resolvers Done... : " << dnsServersCount; } catch (Error & err) { CROW_LOG_ERROR << "Exception: " << err.info(); diff --git a/tinyphone/stampver.inf b/tinyphone/stampver.inf index 1e0978be..7a818093 100644 --- a/tinyphone/stampver.inf +++ b/tinyphone/stampver.inf @@ -1,5 +1,5 @@ ;StampVer information file -FileVersion=36.0.0.81 -ProductVersion=36.0.0.81 +FileVersion=36.0.0.82 +ProductVersion=36.0.0.82 FileFormat=%a.%b.%c ProductFormat=%a.%b.%c From 573fe38d2deff369b05fc6fe0039eec6d6ad6d35 Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Fri, 22 Apr 2022 19:43:40 +0530 Subject: [PATCH 5/7] Remove microsip code (#55) --- microsip/AccountDlg.cpp | 512 --- microsip/AccountDlg.h | 66 - microsip/AddDlg.cpp | 94 - microsip/AddDlg.h | 40 - microsip/BaseDialog.cpp | 173 - microsip/BaseDialog.h | 63 - microsip/ButtonDialer.cpp | 194 - microsip/ButtonDialer.h | 85 - microsip/CLevelsSliderCtrl.cpp | 96 - microsip/CLevelsSliderCtrl.h | 14 - microsip/CListCtrl_DataModel.h | 96 - microsip/CListCtrl_SortItemsEx.cpp | 67 - microsip/CListCtrl_SortItemsEx.h | 11 - microsip/CListCtrl_Sortable.cpp | 191 - microsip/CListCtrl_Sortable.h | 27 - microsip/CSVFile.cpp | 119 - microsip/CSVFile.h | 11 - microsip/Calls.cpp | 626 --- microsip/Calls.h | 84 - microsip/ClosableTabCtrl.cpp | 581 --- microsip/ClosableTabCtrl.h | 46 - microsip/Contacts.cpp | 836 ---- microsip/Contacts.h | 92 - microsip/Crypto.cpp | 261 -- microsip/Crypto.h | 56 - microsip/Dialer.cpp | 1175 ------ microsip/Dialer.h | 162 - microsip/IconButton.cpp | 15 - microsip/IconButton.h | 11 - microsip/MMNotificationClient.h | 145 - microsip/MessagesDlg.cpp | 1376 ------- microsip/MessagesDlg.h | 123 - microsip/ModelessMessageBox.cpp | 11 - microsip/ModelessMessageBox.h | 67 - microsip/Preview.cpp | 132 - microsip/Preview.h | 45 - microsip/Resource.h | 376 -- microsip/RinginDlg.cpp | 252 -- microsip/RinginDlg.h | 54 - microsip/SettingsDlg.cpp | 771 ---- microsip/SettingsDlg.h | 79 - microsip/ShortcutsDlg.cpp | 147 - microsip/ShortcutsDlg.h | 43 - microsip/StdioFileEx.cpp | 1114 ------ microsip/StdioFileEx.h | 353 -- microsip/TemplateSmartPtr.h | 135 - microsip/Transfer.cpp | 128 - microsip/Transfer.h | 48 - microsip/VisualStylesXP.cpp | 458 --- microsip/VisualStylesXP.h | 246 -- microsip/addons.cpp | 24 - microsip/addons.h | 22 - microsip/addons.rc2 | 0 microsip/addons/CXMLFile/XMLFile.cpp | 823 ---- microsip/addons/CXMLFile/XMLFile.h | 103 - microsip/atlrx.h | 2013 ---------- microsip/const.h | Bin 2164 -> 0 bytes microsip/define.h | 54 - microsip/ggets.cpp | 212 -- microsip/ggets.h | 52 - microsip/global.cpp | 1314 ------- microsip/global.h | 272 -- microsip/jumplist.cpp | 551 --- microsip/jumplist.h | 74 - microsip/langpack.cpp | 392 -- microsip/langpack.h | 48 - microsip/main.rc | 99 - microsip/mainDlg.cpp | 4007 -------------------- microsip/mainDlg.h | 242 -- microsip/microsip.cpp | 235 -- microsip/microsip.h | 47 - microsip/microsip.vcxproj | 346 -- microsip/microsip.vcxproj.filters | 328 -- microsip/microsip.vcxproj.user | 4 - microsip/res/active-secure.ico | Bin 1150 -> 0 bytes microsip/res/active.ico | Bin 1150 -> 0 bytes microsip/res/away.ico | Bin 1150 -> 0 bytes microsip/res/blank.ico | Bin 1150 -> 0 bytes microsip/res/busy.ico | Bin 1150 -> 0 bytes microsip/res/callin.ico | Bin 1150 -> 0 bytes microsip/res/callmiss.ico | Bin 1150 -> 0 bytes microsip/res/callout.ico | Bin 1150 -> 0 bytes microsip/res/close.ico | Bin 198 -> 0 bytes microsip/res/close2.ico | Bin 1150 -> 0 bytes microsip/res/conference-secure.ico | Bin 1150 -> 0 bytes microsip/res/conference.ico | Bin 1150 -> 0 bytes microsip/res/default.ico | Bin 1150 -> 0 bytes microsip/res/delete.bmp | Bin 824 -> 0 bytes microsip/res/dialog.rc2 | 481 --- microsip/res/downarrow.bmp | Bin 230 -> 0 bytes microsip/res/dropdown.ico | Bin 1150 -> 0 bytes microsip/res/exit.ico | Bin 1150 -> 0 bytes microsip/res/hold.ico | Bin 1150 -> 0 bytes microsip/res/inactive.ico | Bin 9622 -> 0 bytes microsip/res/main-shortcuts.ico | Bin 4286 -> 0 bytes microsip/res/main.rc2 | 118 - microsip/res/menu.rc2 | 61 - microsip/res/message-in.ico | Bin 1150 -> 0 bytes microsip/res/message.ico | Bin 1406 -> 0 bytes microsip/res/microsip.ico | Bin 110831 -> 0 bytes microsip/res/missed.ico | Bin 1150 -> 0 bytes microsip/res/mutedin.ico | Bin 1150 -> 0 bytes microsip/res/mutedout.ico | Bin 1150 -> 0 bytes microsip/res/mutein.ico | Bin 1150 -> 0 bytes microsip/res/muteout.ico | Bin 1150 -> 0 bytes microsip/res/offline.ico | Bin 1150 -> 0 bytes microsip/res/on-hold.ico | Bin 1150 -> 0 bytes microsip/res/on-remote-hold-conference.ico | Bin 1150 -> 0 bytes microsip/res/on-remote-hold.ico | Bin 1150 -> 0 bytes microsip/res/on-the-phone.ico | Bin 1150 -> 0 bytes microsip/res/online.ico | Bin 1150 -> 0 bytes microsip/res/search.ico | Bin 1150 -> 0 bytes microsip/res/secure.ico | Bin 1150 -> 0 bytes microsip/res/transfer.ico | Bin 1150 -> 0 bytes microsip/res/unknown.ico | Bin 1150 -> 0 bytes microsip/res/uparrow.bmp | Bin 230 -> 0 bytes microsip/res/video.ico | Bin 1150 -> 0 bytes microsip/res/voicemail-down.bmp | Bin 1272 -> 0 bytes microsip/res/voicemail-focus.bmp | Bin 1272 -> 0 bytes microsip/res/voicemail-grey-down.bmp | Bin 1688 -> 0 bytes microsip/res/voicemail-grey-focus.bmp | Bin 1688 -> 0 bytes microsip/res/voicemail-grey.bmp | Bin 1688 -> 0 bytes microsip/res/voicemail.bmp | Bin 1272 -> 0 bytes microsip/settings.cpp | 964 ----- microsip/settings.h | 205 - microsip/stdafx.cpp | 7 - microsip/stdafx.h | 60 - microsip/targetver.h | 28 - microsip/utf.cpp | 420 -- microsip/utf.h | 5 - microsip/zip.cpp | 2830 -------------- microsip/zip.h | 203 - 132 files changed, 28551 deletions(-) delete mode 100644 microsip/AccountDlg.cpp delete mode 100644 microsip/AccountDlg.h delete mode 100644 microsip/AddDlg.cpp delete mode 100644 microsip/AddDlg.h delete mode 100644 microsip/BaseDialog.cpp delete mode 100644 microsip/BaseDialog.h delete mode 100644 microsip/ButtonDialer.cpp delete mode 100644 microsip/ButtonDialer.h delete mode 100644 microsip/CLevelsSliderCtrl.cpp delete mode 100644 microsip/CLevelsSliderCtrl.h delete mode 100644 microsip/CListCtrl_DataModel.h delete mode 100644 microsip/CListCtrl_SortItemsEx.cpp delete mode 100644 microsip/CListCtrl_SortItemsEx.h delete mode 100644 microsip/CListCtrl_Sortable.cpp delete mode 100644 microsip/CListCtrl_Sortable.h delete mode 100644 microsip/CSVFile.cpp delete mode 100644 microsip/CSVFile.h delete mode 100644 microsip/Calls.cpp delete mode 100644 microsip/Calls.h delete mode 100644 microsip/ClosableTabCtrl.cpp delete mode 100644 microsip/ClosableTabCtrl.h delete mode 100644 microsip/Contacts.cpp delete mode 100644 microsip/Contacts.h delete mode 100644 microsip/Crypto.cpp delete mode 100644 microsip/Crypto.h delete mode 100644 microsip/Dialer.cpp delete mode 100644 microsip/Dialer.h delete mode 100644 microsip/IconButton.cpp delete mode 100644 microsip/IconButton.h delete mode 100644 microsip/MMNotificationClient.h delete mode 100644 microsip/MessagesDlg.cpp delete mode 100644 microsip/MessagesDlg.h delete mode 100644 microsip/ModelessMessageBox.cpp delete mode 100644 microsip/ModelessMessageBox.h delete mode 100644 microsip/Preview.cpp delete mode 100644 microsip/Preview.h delete mode 100644 microsip/Resource.h delete mode 100644 microsip/RinginDlg.cpp delete mode 100644 microsip/RinginDlg.h delete mode 100644 microsip/SettingsDlg.cpp delete mode 100644 microsip/SettingsDlg.h delete mode 100644 microsip/ShortcutsDlg.cpp delete mode 100644 microsip/ShortcutsDlg.h delete mode 100644 microsip/StdioFileEx.cpp delete mode 100644 microsip/StdioFileEx.h delete mode 100644 microsip/TemplateSmartPtr.h delete mode 100644 microsip/Transfer.cpp delete mode 100644 microsip/Transfer.h delete mode 100644 microsip/VisualStylesXP.cpp delete mode 100644 microsip/VisualStylesXP.h delete mode 100644 microsip/addons.cpp delete mode 100644 microsip/addons.h delete mode 100644 microsip/addons.rc2 delete mode 100644 microsip/addons/CXMLFile/XMLFile.cpp delete mode 100644 microsip/addons/CXMLFile/XMLFile.h delete mode 100644 microsip/atlrx.h delete mode 100644 microsip/const.h delete mode 100644 microsip/define.h delete mode 100644 microsip/ggets.cpp delete mode 100644 microsip/ggets.h delete mode 100644 microsip/global.cpp delete mode 100644 microsip/global.h delete mode 100644 microsip/jumplist.cpp delete mode 100644 microsip/jumplist.h delete mode 100644 microsip/langpack.cpp delete mode 100644 microsip/langpack.h delete mode 100644 microsip/main.rc delete mode 100644 microsip/mainDlg.cpp delete mode 100644 microsip/mainDlg.h delete mode 100644 microsip/microsip.cpp delete mode 100644 microsip/microsip.h delete mode 100644 microsip/microsip.vcxproj delete mode 100644 microsip/microsip.vcxproj.filters delete mode 100644 microsip/microsip.vcxproj.user delete mode 100644 microsip/res/active-secure.ico delete mode 100644 microsip/res/active.ico delete mode 100644 microsip/res/away.ico delete mode 100644 microsip/res/blank.ico delete mode 100644 microsip/res/busy.ico delete mode 100644 microsip/res/callin.ico delete mode 100644 microsip/res/callmiss.ico delete mode 100644 microsip/res/callout.ico delete mode 100644 microsip/res/close.ico delete mode 100644 microsip/res/close2.ico delete mode 100644 microsip/res/conference-secure.ico delete mode 100644 microsip/res/conference.ico delete mode 100644 microsip/res/default.ico delete mode 100644 microsip/res/delete.bmp delete mode 100644 microsip/res/dialog.rc2 delete mode 100644 microsip/res/downarrow.bmp delete mode 100644 microsip/res/dropdown.ico delete mode 100644 microsip/res/exit.ico delete mode 100644 microsip/res/hold.ico delete mode 100644 microsip/res/inactive.ico delete mode 100644 microsip/res/main-shortcuts.ico delete mode 100644 microsip/res/main.rc2 delete mode 100644 microsip/res/menu.rc2 delete mode 100644 microsip/res/message-in.ico delete mode 100644 microsip/res/message.ico delete mode 100644 microsip/res/microsip.ico delete mode 100644 microsip/res/missed.ico delete mode 100644 microsip/res/mutedin.ico delete mode 100644 microsip/res/mutedout.ico delete mode 100644 microsip/res/mutein.ico delete mode 100644 microsip/res/muteout.ico delete mode 100644 microsip/res/offline.ico delete mode 100644 microsip/res/on-hold.ico delete mode 100644 microsip/res/on-remote-hold-conference.ico delete mode 100644 microsip/res/on-remote-hold.ico delete mode 100644 microsip/res/on-the-phone.ico delete mode 100644 microsip/res/online.ico delete mode 100644 microsip/res/search.ico delete mode 100644 microsip/res/secure.ico delete mode 100644 microsip/res/transfer.ico delete mode 100644 microsip/res/unknown.ico delete mode 100644 microsip/res/uparrow.bmp delete mode 100644 microsip/res/video.ico delete mode 100644 microsip/res/voicemail-down.bmp delete mode 100644 microsip/res/voicemail-focus.bmp delete mode 100644 microsip/res/voicemail-grey-down.bmp delete mode 100644 microsip/res/voicemail-grey-focus.bmp delete mode 100644 microsip/res/voicemail-grey.bmp delete mode 100644 microsip/res/voicemail.bmp delete mode 100644 microsip/settings.cpp delete mode 100644 microsip/settings.h delete mode 100644 microsip/stdafx.cpp delete mode 100644 microsip/stdafx.h delete mode 100644 microsip/targetver.h delete mode 100644 microsip/utf.cpp delete mode 100644 microsip/utf.h delete mode 100644 microsip/zip.cpp delete mode 100644 microsip/zip.h diff --git a/microsip/AccountDlg.cpp b/microsip/AccountDlg.cpp deleted file mode 100644 index ca188ab4..00000000 --- a/microsip/AccountDlg.cpp +++ /dev/null @@ -1,512 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "AccountDlg.h" -#include "mainDlg.h" -#include "langpack.h" - -#include - -AccountDlg::AccountDlg(CWnd* pParent /*=NULL*/) -: CDialog(AccountDlg::IDD, pParent) -{ - accountId = 0; - Create (IDD, pParent); - -} - -AccountDlg::~AccountDlg(void) -{ -} - -int AccountDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (langPack.rtl) { - ModifyStyleEx(0,WS_EX_LAYOUTRTL); - } - return 0; -} - -BOOL AccountDlg::OnInitDialog() -{ - CDialog::OnInitDialog(); - - TranslateDialog(this->m_hWnd); - - CString str; - - str.Format(_T("%s"),Translate(_T("display password"))); - GetDlgItem(IDC_SYSLINK_DISPLAY_PASSWORD)->SetWindowText(str); - - CComboBox *combobox; - - combobox= (CComboBox*)GetDlgItem(IDC_TRANSPORT); - combobox->AddString(Translate(_T("Auto"))); - combobox->AddString(_T("UDP")); - combobox->AddString(_T("TCP")); - combobox->AddString(_T("TLS")); - combobox->SetCurSel(0); - - combobox= (CComboBox*)GetDlgItem(IDC_SRTP); - combobox->AddString(Translate(_T("Disabled"))); - combobox->AddString(Translate(_T("Optional"))); - combobox->AddString(Translate(_T("Mandatory"))); - combobox->SetCurSel(0); - - ((CButton*)GetDlgItem(IDC_ICE))->SetCheck(m_Account.ice); - - CEdit* edit; - - combobox= (CComboBox*)GetDlgItem(IDC_PUBLIC_ADDR); - combobox->AddString(Translate(_T("Auto"))); - char buf[256]={0}; - if ( gethostname(buf, 256) == 0) { - struct addrinfo* l_addrInfo = NULL; - struct addrinfo l_addrInfoHints; - ZeroMemory(&l_addrInfoHints, sizeof(addrinfo)); - l_addrInfoHints.ai_socktype = SOCK_STREAM; - l_addrInfoHints.ai_family = PF_INET; - if ( getaddrinfo(buf,NULL, &l_addrInfoHints,&l_addrInfo) == 0 ) { - if (l_addrInfo) { - struct addrinfo* l_addrInfoCurrent = l_addrInfo; - for (l_addrInfoCurrent = l_addrInfo; l_addrInfoCurrent; l_addrInfoCurrent=l_addrInfoCurrent->ai_next) { - struct sockaddr_in *ipv4 = (struct sockaddr_in *)l_addrInfoCurrent->ai_addr; - char * ip = inet_ntoa(ipv4->sin_addr); - combobox->AddString(CString(ip)); - } - } - } - } - combobox->SetCurSel(0); - if (accountSettings.enableSTUN && !accountSettings.stun.IsEmpty()) { - combobox->EnableWindow(FALSE); - } - - return TRUE; -} - -void AccountDlg::OnDestroy() -{ - mainDlg->accountDlg = NULL; - CDialog::OnDestroy(); -} - -void AccountDlg::PostNcDestroy() -{ - CDialog::PostNcDestroy(); - delete this; -} - -BEGIN_MESSAGE_MAP(AccountDlg, CDialog) - ON_WM_CREATE() - ON_WM_CLOSE() - ON_WM_DESTROY() - ON_BN_CLICKED(IDCANCEL, &AccountDlg::OnBnClickedCancel) - ON_BN_CLICKED(IDOK, &AccountDlg::OnBnClickedOk) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_SIP_SERVER, &AccountDlg::OnNMClickSyslinkSipServer) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_SIP_PROXY, &AccountDlg::OnNMClickSyslinkSipProxy) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_USERNAME, &AccountDlg::OnNMClickSyslinkUsername) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_DOMAIN, &AccountDlg::OnNMClickSyslinkDomain) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_AUTHID, &AccountDlg::OnNMClickSyslinkAuthID) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_PASSWORD, &AccountDlg::OnNMClickSyslinkPassword) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_NAME, &AccountDlg::OnNMClickSyslinkName) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_VOICEMAIL, &AccountDlg::OnNMClickSyslinkVoicemail) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_ENCRYPTION, &AccountDlg::OnNMClickSyslinkEncryption) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_TRANSPORT, &AccountDlg::OnNMClickSyslinkTransport) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_PUBLIC_ADDRESS, &AccountDlg::OnNMClickSyslinkPublicAddress) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_PUBLISH_PRESENCE, &AccountDlg::OnNMClickSyslinkPublishPresence) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_ICE, &AccountDlg::OnNMClickSyslinkIce) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_REWRITE, &AccountDlg::OnNMClickSyslinkRewrite) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_SESSION_TIMER, &AccountDlg::OnNMClickSyslinkSessionTimer) - ON_NOTIFY(NM_CLICK, IDC_SYSLINK_DISPLAY_PASSWORD, &AccountDlg::OnNMClickSyslinkDisplayPasswod) - ON_NOTIFY(NM_RETURN, IDC_SYSLINK_DISPLAY_PASSWORD, &AccountDlg::OnNMClickSyslinkDisplayPasswod) - ON_BN_CLICKED(IDC_ACCOUNT_REMOVE, &AccountDlg::OnBnClickedDelete) - -END_MESSAGE_MAP() - - -void AccountDlg::OnClose() -{ - DestroyWindow(); -} - -void AccountDlg::OnBnClickedCancel() -{ - OnClose(); -} - -void AccountDlg::Load(int id) -{ - CEdit* edit; - CComboBox *combobox; - accountId = id; - if (accountSettings.AccountLoad(id,&m_Account)) { - accountId = id; - } else { - accountId = 0; - } - - edit = (CEdit*)GetDlgItem(IDC_ACCOUNT_LABEL); - edit->SetWindowText(m_Account.label); - - edit = (CEdit*)GetDlgItem(IDC_EDIT_SERVER); - edit->SetWindowText(m_Account.server); - - edit = (CEdit*)GetDlgItem(IDC_EDIT_PROXY); - edit->SetWindowText(m_Account.proxy); - - edit = (CEdit*)GetDlgItem(IDC_EDIT_DOMAIN); - edit->SetWindowText(m_Account.domain); - - - edit = (CEdit*)GetDlgItem(IDC_EDIT_AUTHID); - edit->SetWindowText(m_Account.authID); - - edit = (CEdit*)GetDlgItem(IDC_EDIT_USERNAME); - edit->SetWindowText(m_Account.username); - - edit = (CEdit*)GetDlgItem(IDC_EDIT_PASSWORD); - edit->SetWindowText(m_Account.password); - - edit = (CEdit*)GetDlgItem(IDC_EDIT_DISPLAYNAME); - edit->SetWindowText(m_Account.displayName); - - edit = (CEdit*)GetDlgItem(IDC_EDIT_VOICEMAIL); - edit->SetWindowText(m_Account.voicemailNumber); - -int i; - - combobox= (CComboBox*)GetDlgItem(IDC_TRANSPORT); - if (m_Account.transport==_T("udp")) { - i=1; - } else if (m_Account.transport==_T("tcp")) { - i=2; - } else if (m_Account.transport==_T("tls")) { - i=3; - } else { - i=0; - } - if (i>0) { - combobox->SetCurSel(i); - } - - combobox= (CComboBox*)GetDlgItem(IDC_SRTP); - if (m_Account.srtp==_T("optional")) { - i=1; - } else if (m_Account.srtp==_T("mandatory")) { - i=2; - } - else { - i=0; - } - if (i>0) { - combobox->SetCurSel(i); - } - - combobox= (CComboBox*)GetDlgItem(IDC_PUBLIC_ADDR); - if (combobox->IsWindowEnabled()) { - if (m_Account.publicAddr.GetLength()) { - combobox->SetWindowText(m_Account.publicAddr); - } - } - - ((CButton*)GetDlgItem(IDC_PUBLISH))->SetCheck(m_Account.publish); - - ((CButton*)GetDlgItem(IDC_REWRITE))->SetCheck(m_Account.allowRewrite); - ((CButton*)GetDlgItem(IDC_SESSION_TIMER))->SetCheck(m_Account.disableSessionTimer); - if (accountId>0 && !m_Account.username.IsEmpty()) { - GetDlgItem(IDC_ACCOUNT_REMOVE)->ShowWindow(SW_SHOW); - } else { - GetDlgItem(IDC_ACCOUNT_REMOVE)->ShowWindow(SW_HIDE); - } -} - -void AccountDlg::OnBnClickedOk() -{ - CEdit* edit; - CString str; - CComboBox *combobox; - int i; - - edit = (CEdit*)GetDlgItem(IDC_ACCOUNT_LABEL); - edit->GetWindowText(str); - m_Account.label=str.Trim(); - - edit = (CEdit*)GetDlgItem(IDC_EDIT_SERVER); - edit->GetWindowText(str); - m_Account.server=str.Trim(); - - edit = (CEdit*)GetDlgItem(IDC_EDIT_PROXY); - edit->GetWindowText(str); - m_Account.proxy=str.Trim(); - - edit = (CEdit*)GetDlgItem(IDC_EDIT_DOMAIN); - edit->GetWindowText(str); - m_Account.domain=str.Trim(); - - edit = (CEdit*)GetDlgItem(IDC_EDIT_AUTHID); - edit->GetWindowText(str); - m_Account.authID=str.Trim(); - - edit = (CEdit*)GetDlgItem(IDC_EDIT_USERNAME); - edit->GetWindowText(str); - m_Account.username=str.Trim(); - - edit = (CEdit*)GetDlgItem(IDC_EDIT_PASSWORD); - edit->GetWindowText(str); - m_Account.password=str.Trim(); - - edit = (CEdit*)GetDlgItem(IDC_EDIT_DISPLAYNAME); - edit->GetWindowText(str); - m_Account.displayName=str.Trim(); - - edit = (CEdit*)GetDlgItem(IDC_EDIT_VOICEMAIL); - edit->GetWindowText(str); - m_Account.voicemailNumber=str.Trim(); - - combobox= (CComboBox*)GetDlgItem(IDC_TRANSPORT); - i = combobox->GetCurSel(); - switch (i) { - case 1: - m_Account.transport=_T("udp"); - break; - case 2: - m_Account.transport=_T("tcp"); - break; - case 3: - m_Account.transport=_T("tls"); - break; - default: - m_Account.transport=_T(""); - } - - m_Account.rememberPassword = 1; - - combobox= (CComboBox*)GetDlgItem(IDC_SRTP); - i = combobox->GetCurSel(); - switch (i) { - case 1: - m_Account.srtp=_T("optional"); - break; - case 2: - m_Account.srtp=_T("mandatory"); - break; - default: - m_Account.srtp=_T(""); - } - - m_Account.ice = ((CButton*)GetDlgItem(IDC_ICE))->GetCheck(); - - m_Account.publish = ((CButton*)GetDlgItem(IDC_PUBLISH))->GetCheck(); - - m_Account.allowRewrite = ((CButton*)GetDlgItem(IDC_REWRITE))->GetCheck(); - - m_Account.disableSessionTimer = ((CButton*)GetDlgItem(IDC_SESSION_TIMER))->GetCheck(); - - combobox= (CComboBox*)GetDlgItem(IDC_PUBLIC_ADDR); - if (combobox->IsWindowEnabled()) { - i = combobox->GetCurSel(); - combobox->GetWindowText(m_Account.publicAddr); - if (m_Account.publicAddr == Translate(_T("Auto"))) - { - m_Account.publicAddr = _T(""); - } - } - - if ( - m_Account.domain.IsEmpty() || - m_Account.username.IsEmpty()) { - CString str; - str.Append(Translate(_T("Please fill out at least the required fields marked with *."))); - str.AppendFormat(_T(" %s"),Translate(_T("Ask your SIP provider how to configure the account correctly."))); - AfxMessageBox(str); - return; - } - - - this->ShowWindow(SW_HIDE); - mainDlg->accountDlg = NULL; - - if (!accountId) { - Account dummy; - int i = 1; - while (true) { - if (!accountSettings.AccountLoad(i,&dummy)) { - break; - } - i++; - } - accountId = i; - } - - accountSettings.AccountSave(accountId,&m_Account); - - mainDlg->PJAccountDelete(true); - - accountSettings.accountId = accountId; - accountSettings.account = m_Account; - accountSettings.AccountLoad(accountSettings.accountId,&accountSettings.account); - if (!accountSettings.account.rememberPassword) { - accountSettings.account.username = m_Account.username; - accountSettings.account.password = m_Account.password; - } - accountSettings.SettingsSave(); - mainDlg->pageDialer->RebuildButtons(); - mainDlg->PJAccountAdd(); - OnClose(); -} - -void AccountDlg::OnNMClickSyslinkSipServer(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("sipServer")); - *pResult = 0; -} - -void AccountDlg::OnNMClickSyslinkSipProxy(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("sipProxy")); - *pResult = 0; -} - -void AccountDlg::OnNMClickSyslinkUsername(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("username")); - *pResult = 0; -} - -void AccountDlg::OnNMClickSyslinkDomain(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("domain")); - *pResult = 0; -} - -void AccountDlg::OnNMClickSyslinkAuthID(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("login")); - *pResult = 0; -} - -void AccountDlg::OnNMClickSyslinkPassword(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("password")); - *pResult = 0; -} - -void AccountDlg::OnNMClickSyslinkName(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("name")); - *pResult = 0; -} - -void AccountDlg::OnNMClickSyslinkVoicemail(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("voicemail")); - *pResult = 0; -} - -void AccountDlg::OnNMClickSyslinkEncryption(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("encryption")); - *pResult = 0; -} - -void AccountDlg::OnNMClickSyslinkTransport(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("transport")); - *pResult = 0; -} - -void AccountDlg::OnNMClickSyslinkPublicAddress(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("publicAddress")); - *pResult = 0; -} - -void AccountDlg::OnNMClickSyslinkPublishPresence(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("publishPresence")); - *pResult = 0; -} - -void AccountDlg::OnNMClickSyslinkIce(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("ice")); - *pResult = 0; -} - -void AccountDlg::OnNMClickSyslinkRewrite(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("allowRewrite")); - *pResult = 0; -} - -void AccountDlg::OnNMClickSyslinkSessionTimer(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("sessionTimers")); - *pResult = 0; -} - -void AccountDlg::OnNMClickSyslinkDisplayPasswod(NMHDR *pNMHDR, LRESULT *pResult) -{ - GetDlgItem(IDC_SYSLINK_DISPLAY_PASSWORD)->ShowWindow(SW_HIDE); - CEdit* edit = (CEdit*)GetDlgItem(IDC_EDIT_PASSWORD); - edit->SetPasswordChar(0); - edit->Invalidate(); - edit->SetFocus(); - int nLength = edit->GetWindowTextLength(); - edit->SetSel(nLength,nLength); - *pResult = 0; -} - -void AccountDlg::OnBnClickedDelete() -{ - if (accountId>0 && AfxMessageBox(Translate(_T("Are you sure you want to remove?")), MB_YESNO)==IDYES) { - this->ShowWindow(SW_HIDE); - mainDlg->accountDlg = NULL; - - Account account; - int i = accountId; - while (true) { - if (!accountSettings.AccountLoad(i+1,&account)) { - break; - } - accountSettings.AccountSave(i,&account); - if (accountSettings.accountId == i+1) { - accountSettings.accountId = i; - accountSettings.SettingsSave(); - accountId = 0; - } - i++; - } - accountSettings.AccountDelete(i); - if (accountId && accountId == accountSettings.accountId) { - mainDlg->PJAccountDelete(true); - if (i>1) { - accountSettings.accountId = 1; - accountSettings.AccountLoad(accountSettings.accountId,&accountSettings.account); - mainDlg->PJAccountAdd(); - } else { - accountSettings.accountId = 0; - } - accountSettings.SettingsSave(); - } - OnClose(); - } -} - diff --git a/microsip/AccountDlg.h b/microsip/AccountDlg.h deleted file mode 100644 index c8896dd4..00000000 --- a/microsip/AccountDlg.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#pragma once - -#include "resource.h" -#include "const.h" -#include "settings.h" - -class AccountDlg : - public CDialog -{ -public: - //CFont m_font; - AccountDlg(CWnd* pParent = NULL); // standard constructor - ~AccountDlg(); - enum { IDD = IDD_ACCOUNT }; - - void Load(int id); - -private: - int accountId; - Account m_Account; -protected: - virtual BOOL OnInitDialog(); - afx_msg void OnDestroy(); - virtual void PostNcDestroy(); - DECLARE_MESSAGE_MAP() -public: - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnClose(); - afx_msg void OnBnClickedCancel(); - afx_msg void OnBnClickedOk(); - afx_msg void OnBnClickedDelete(); - afx_msg void OnNMClickSyslinkSipServer(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkSipProxy(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkUsername(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkDomain(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkAuthID(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkPassword(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkName(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkVoicemail(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkEncryption(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkTransport(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkPublicAddress(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkPublishPresence(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkIce(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkRewrite(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkSessionTimer(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkDisplayPasswod(NMHDR *pNMHDR, LRESULT *pResult); -}; diff --git a/microsip/AddDlg.cpp b/microsip/AddDlg.cpp deleted file mode 100644 index 5730335f..00000000 --- a/microsip/AddDlg.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "microsip.h" -#include "AddDlg.h" -#include "mainDlg.h" -#include "langpack.h" - -AddDlg::AddDlg(CWnd* pParent /*=NULL*/) - : CDialog(AddDlg::IDD, pParent) -{ - Create (IDD, pParent); -} - -AddDlg::~AddDlg() -{ -} - -int AddDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (langPack.rtl) { - ModifyStyleEx(0,WS_EX_LAYOUTRTL); - } - return 0; -} - -BOOL AddDlg::OnInitDialog() -{ - CDialog::OnInitDialog(); - TranslateDialog(this->m_hWnd); - return TRUE; -} - -void AddDlg::PostNcDestroy() -{ - CDialog::PostNcDestroy(); - delete this; -} - - -BEGIN_MESSAGE_MAP(AddDlg, CDialog) - ON_WM_CREATE() - ON_WM_CLOSE() - ON_BN_CLICKED(IDOK, &AddDlg::OnBnClickedOk) - ON_BN_CLICKED(IDCANCEL, &AddDlg::OnBnClickedCancel) -END_MESSAGE_MAP() - - -void AddDlg::OnClose() -{ - this->ShowWindow(SW_HIDE); -} - -void AddDlg::OnBnClickedOk() -{ - CString number; - CString name; - BOOL presence; - - GetDlgItem(IDC_EDIT_NUMBER)->GetWindowText(number); - number=number.Trim(); - if (number.GetLength()) { - GetDlgItem(IDC_EDIT_NAME)->GetWindowText(name); - name=name.Trim(); - name=name.GetLength()?name:number; - if (listIndex != -1) { - mainDlg->pageContacts->ContactDelete(listIndex); - } - presence = ((CButton*)GetDlgItem(IDC_PRESENCE))->GetCheck(); - mainDlg->pageContacts->ContactAdd(number, name, presence, -1, TRUE); - OnClose(); - } -} - -void AddDlg::OnBnClickedCancel() -{ - OnClose(); -} diff --git a/microsip/AddDlg.h b/microsip/AddDlg.h deleted file mode 100644 index 501e2db3..00000000 --- a/microsip/AddDlg.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#pragma once - -class AddDlg : public CDialog -{ - -public: - AddDlg(CWnd* pParent = NULL); - virtual ~AddDlg(); - enum { IDD = IDD_ADD }; - - int listIndex; - -protected: - virtual BOOL OnInitDialog(); - virtual void PostNcDestroy(); - DECLARE_MESSAGE_MAP() -public: - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnClose(); - afx_msg void OnBnClickedOk(); - afx_msg void OnBnClickedCancel(); -}; diff --git a/microsip/BaseDialog.cpp b/microsip/BaseDialog.cpp deleted file mode 100644 index 28b3b113..00000000 --- a/microsip/BaseDialog.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "BaseDialog.h" -#include "resource.h" -#include "global.h" - -CBaseDialog::CBaseDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/) -: CDialog(nIDTemplate, pParent), -m_szMinimum(0, 0) -{ -} - - -BEGIN_MESSAGE_MAP(CBaseDialog, CDialog) - //{{AFX_MSG_MAP(CBaseDialog) - ON_WM_GETMINMAXINFO() - ON_WM_SIZE() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -BOOL CBaseDialog::PreTranslateMessage(MSG* pMsg) -{ - BOOL catched = FALSE; - if (pMsg->message == WM_KEYDOWN) { - if (GetAsyncKeyState(VK_CONTROL)<0) { - if (pMsg->wParam == 'M') { - PostMessage(WM_COMMAND,ID_ACCOUNT_EDIT_RANGE,0); - catched = TRUE; - } - if (pMsg->wParam == 'P') { - PostMessage(WM_COMMAND,ID_SETTINGS,0); - catched = TRUE; - } - if (pMsg->wParam == 'S') { - PostMessage(WM_COMMAND,ID_SHORTCUTS,0); - catched = TRUE; - } - if (pMsg->wParam == 'W') { - PostMessage(WM_COMMAND,ID_MENU_WEBSITE,0); - catched = TRUE; - } - if (pMsg->wParam == 'Q') { - PostMessage(WM_COMMAND,ID_EXIT,0); - catched = TRUE; - } - } - } - if (!catched) { - return CDialog::PreTranslateMessage(pMsg); - } else { - return TRUE; - } -} - -void CBaseDialog::AutoMove(int iID, double dXMovePct, double dYMovePct, double dXSizePct, double dYSizePct) -{ - ASSERT((dXMovePct + dXSizePct) <= 100.0); // can't use more than 100% of the resize for the child - ASSERT((dYMovePct + dYSizePct) <= 100.0); // can't use more than 100% of the resize for the child - SMovingChild s; - GetDlgItem(iID, &s.m_hWnd); - ASSERT(s.m_hWnd != NULL); - s.m_dXMoveFrac = dXMovePct / 100.0; - s.m_dYMoveFrac = dYMovePct / 100.0; - s.m_dXSizeFrac = dXSizePct / 100.0; - s.m_dYSizeFrac = dYSizePct / 100.0; - ::GetWindowRect(s.m_hWnd, &s.m_rcInitial); - ScreenToClient(s.m_rcInitial); - m_MovingChildren.push_back(s); -} - -void CBaseDialog::AutoMove(HWND hWnd, double dXMovePct, double dYMovePct, double dXSizePct, double dYSizePct) -{ - ASSERT((dXMovePct + dXSizePct) <= 100.0); // can't use more than 100% of the resize for the child - ASSERT((dYMovePct + dYSizePct) <= 100.0); // can't use more than 100% of the resize for the child - SMovingChild s; - s.m_hWnd = hWnd; - ASSERT(s.m_hWnd != NULL); - s.m_dXMoveFrac = dXMovePct / 100.0; - s.m_dYMoveFrac = dYMovePct / 100.0; - s.m_dXSizeFrac = dXSizePct / 100.0; - s.m_dYSizeFrac = dYSizePct / 100.0; - ::GetWindowRect(s.m_hWnd, &s.m_rcInitial); - ScreenToClient(s.m_rcInitial); - m_MovingChildren.push_back(s); -} - -void CBaseDialog::AutoUnmove(HWND hWnd) -{ - ASSERT(hWnd != NULL); - for (MovingChildren::iterator p = m_MovingChildren.begin(); p != m_MovingChildren.end(); ++p) - { - if (p->m_hWnd == hWnd) - { - m_MovingChildren.erase(p); - break; - } - } -} - -BOOL CBaseDialog::OnInitDialog() -{ - CDialog::OnInitDialog(); - - // use the initial dialog size as the default minimum - if ((m_szMinimum.cx == 0) && (m_szMinimum.cy == 0)) - { - CRect rcWindow; - GetWindowRect(rcWindow); - m_szMinimum = rcWindow.Size(); - } - - // keep the initial size of the client area as a baseline for moving/sizing controls - CRect rcClient; - GetClientRect(rcClient); - m_szInitial = rcClient.Size(); - - return TRUE; // return TRUE unless you set the focus to a control -} - -void CBaseDialog::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) -{ - CDialog::OnGetMinMaxInfo(lpMMI); - - if (lpMMI->ptMinTrackSize.x < m_szMinimum.cx) - lpMMI->ptMinTrackSize.x = m_szMinimum.cx; - if (lpMMI->ptMinTrackSize.y < m_szMinimum.cy) - lpMMI->ptMinTrackSize.y = m_szMinimum.cy; -} - -void CBaseDialog::OnSize(UINT nType, int cx, int cy) -{ - CDialog::OnSize(nType, cx, cy); - - int iXDelta = cx - m_szInitial.cx; - int iYDelta = cy - m_szInitial.cy; - HDWP hDefer = NULL; - for (MovingChildren::iterator p = m_MovingChildren.begin(); p != m_MovingChildren.end(); ++p) - { - if (p->m_hWnd != NULL) - { - CRect rcNew(p->m_rcInitial); - rcNew.OffsetRect(int(iXDelta * p->m_dXMoveFrac), int(iYDelta * p->m_dYMoveFrac)); - rcNew.right += int(iXDelta * p->m_dXSizeFrac); - rcNew.bottom += int(iYDelta * p->m_dYSizeFrac); - if (hDefer == NULL) - hDefer = BeginDeferWindowPos(m_MovingChildren.size()); - UINT uFlags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER; - if ((p->m_dXSizeFrac != 0.0) || (p->m_dYSizeFrac != 0.0)) - uFlags |= SWP_NOCOPYBITS; - DeferWindowPos(hDefer, p->m_hWnd, NULL, rcNew.left, rcNew.top, rcNew.Width(), rcNew.Height(), uFlags); - } - } - if (hDefer != NULL) - EndDeferWindowPos(hDefer); - -} \ No newline at end of file diff --git a/microsip/BaseDialog.h b/microsip/BaseDialog.h deleted file mode 100644 index e539dbe5..00000000 --- a/microsip/BaseDialog.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#pragma once - -#include - -class CBaseDialog : public CDialog -{ - // Construction -public: - CBaseDialog(UINT nIDTemplate, CWnd* pParent = NULL); // standard constructor - - void AutoMove(int iID, double dXMovePct, double dYMovePct, double dXSizePct, double dYSizePct); - void AutoMove(HWND hWnd, double dXMovePct, double dYMovePct, double dXSizePct, double dYSizePct); - void AutoUnmove(HWND hWnd); - - // Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CBaseDialog) -protected: - //}}AFX_VIRTUAL - -protected: - //{{AFX_MSG(CBaseDialog) - virtual BOOL OnInitDialog(); - virtual BOOL PreTranslateMessage(MSG* pMsg); - afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI); - afx_msg void OnSize(UINT nType, int cx, int cy); - //}}AFX_MSG - DECLARE_MESSAGE_MAP() - -private: - struct SMovingChild - { - HWND m_hWnd; - double m_dXMoveFrac; - double m_dYMoveFrac; - double m_dXSizeFrac; - double m_dYSizeFrac; - CRect m_rcInitial; - }; - typedef std::vector MovingChildren; - - MovingChildren m_MovingChildren; - CSize m_szInitial; - CSize m_szMinimum; -}; diff --git a/microsip/ButtonDialer.cpp b/microsip/ButtonDialer.cpp deleted file mode 100644 index 7d1c981b..00000000 --- a/microsip/ButtonDialer.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - - // ButtonDialer.cpp : implementation file - // - -#include "stdafx.h" -#include "ButtonDialer.h" -#include "Strsafe.h" -#include "const.h" - -///////////////////////////////////////////////////////////////////////////// -// CButtonDialer - -CButtonDialer::CButtonDialer() -{ - forceNumeric = false; - m_map.SetAt(_T("1"), _T("")); - m_map.SetAt(_T("2"), _T("ABC")); - m_map.SetAt(_T("3"), _T("DEF")); - m_map.SetAt(_T("4"), _T("GHI")); - m_map.SetAt(_T("5"), _T("JKL")); - m_map.SetAt(_T("6"), _T("MNO")); - m_map.SetAt(_T("7"), _T("PQRS")); - m_map.SetAt(_T("8"), _T("TUV")); - m_map.SetAt(_T("9"), _T("WXYZ")); - m_map.SetAt(_T("0"), _T("")); - m_map.SetAt(_T("*"), _T("")); - m_map.SetAt(_T("#"), _T("")); -} - -CButtonDialer::~CButtonDialer() -{ - CloseTheme(); -} - - -BEGIN_MESSAGE_MAP(CButtonDialer, CButton) - ON_WM_THEMECHANGED() - ON_WM_MOUSEMOVE() - ON_WM_SIZE() -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CButtonDialer message handlers - -void CButtonDialer::PreSubclassWindow() -{ - OpenTheme(); - - HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); - LOGFONT lf; - GetObject(hFont, sizeof(LOGFONT), &lf); - lf.lfHeight = 12; - CDC *pDC = GetDC(); - if (pDC) { - dpiX = GetDeviceCaps(pDC->m_hDC, LOGPIXELSX); - dpiY = GetDeviceCaps(pDC->m_hDC, LOGPIXELSY); - lf.lfHeight = MulDiv(lf.lfHeight, dpiY, 96); - ReleaseDC(pDC); - } - else { - dpiX = dpiY = 96; - } - StringCchCopy(lf.lfFaceName, LF_FACESIZE, _T("Microsoft Sans Serif")); - m_FontLetters.CreateFontIndirect(&lf); - - DWORD dwStyle = ::GetClassLong(m_hWnd, GCL_STYLE); - dwStyle &= ~CS_DBLCLKS; - ::SetClassLong(m_hWnd, GCL_STYLE, dwStyle); -} - -LRESULT CButtonDialer::OnThemeChanged() -{ - CloseTheme(); - OpenTheme(); - return 0L; -} - -void CButtonDialer::OnSize(UINT type, int w, int h) -{ - CButton::OnSize(type, w, h); -} - -void CButtonDialer::OnMouseMove(UINT nFlags, CPoint point) -{ - CRect rect; - GetClientRect(&rect); - if (rect.PtInRect(point)) { - if (GetCapture() != this) { - SetCapture(); - Invalidate(); - } - } - else { - ReleaseCapture(); - Invalidate(); - } - CButton::OnMouseMove(nFlags, point); -} - -void CButtonDialer::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) -{ - CDC dc; - dc.Attach(lpDrawItemStruct->hDC); //Get device context object - CRect rt; - rt = lpDrawItemStruct->rcItem; //Get button rect - dc.FillSolidRect(rt, dc.GetBkColor()); - dc.SetBkMode(TRANSPARENT); - - CRect rtl = rt; - UINT state = lpDrawItemStruct->itemState; //Get state of the button - - if (!m_hTheme) { - UINT uStyle = DFCS_BUTTONPUSH; - if ((state & ODS_SELECTED)) { - uStyle |= DFCS_PUSHED; - rtl.left += 1; - rtl.top += 1; - } - dc.DrawFrameControl(rt, DFC_BUTTON, uStyle); - } - else { - UINT uStyleTheme = RBS_NORMAL; - if ((state & ODS_SELECTED)) { - uStyleTheme = PBS_PRESSED; - } - else if (GetCapture() == this) { - uStyleTheme = PBS_HOT; - } - DrawThemeBackground(m_hTheme, dc.m_hDC, - BP_PUSHBUTTON, uStyleTheme, - rt, NULL); - } - - CString strTemp; - GetWindowText(strTemp); // Get the caption which have been set - - int x12 = MulDiv(12, dpiX, 96); - int x14 = MulDiv(14, dpiX, 96); - int x4 = MulDiv(4, dpiX, 96); - - CString letters; - COLORREF crOldColor; - if (!forceNumeric && m_map.Lookup(strTemp, letters)) { - rtl.left += x14; - dc.DrawText(strTemp, rtl, DT_LEFT | DT_VCENTER | DT_SINGLELINE); // Draw out the caption - HFONT hOldFont = (HFONT)SelectObject(dc.m_hDC, m_FontLetters); - // Do your text drawing - rtl.left += x12; - rtl.right -= x4; - crOldColor = dc.SetTextColor(RGB(127, 127, 127)); - dc.DrawText(letters, rtl, DT_LEFT | DT_VCENTER | DT_SINGLELINE); - dc.SetTextColor(crOldColor); - // Always select the old font back into the DC - SelectObject(dc.m_hDC, hOldFont); - } - else { - if (forceNumeric) { - crOldColor = dc.SetTextColor(RGB(80, 80, 80)); - } - else { - crOldColor = dc.SetTextColor(RGB(127, 127, 127)); - } - dc.DrawText(strTemp, rt, DT_CENTER | DT_VCENTER | DT_SINGLELINE); // Draw out the caption - dc.SetTextColor(crOldColor); - } - - if ((state & ODS_FOCUS)) // If the button is focused - { - int iChange = 3; - rt.top += iChange; - rt.left += iChange; - rt.right -= iChange; - rt.bottom -= iChange; - dc.DrawFocusRect(rt); - } - dc.Detach(); -} diff --git a/microsip/ButtonDialer.h b/microsip/ButtonDialer.h deleted file mode 100644 index 1717bf94..00000000 --- a/microsip/ButtonDialer.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#if !defined(AFX_DIALERBUTTON_H__8E7A4504_82E5_4C81_8A30_642AC65A4550__INCLUDED_) -#define AFX_DIALERBUTTON_H__8E7A4504_82E5_4C81_8A30_642AC65A4550__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 -// ButtonDialer.h : header file -// - -#pragma comment(lib, "UxTheme.lib") - -///////////////////////////////////////////////////////////////////////////// -// CButtonDialer window - -class CButtonDialer : public CButton -{ -// Construction -public: - CButtonDialer(); - -// Attributes -public: - -// Operations -public: - bool forceNumeric; -// Overrides - // ClassWizard generated virtual function overrides - //{{AFX_VIRTUAL(CButtonDialer) - public: - virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); - //}}AFX_VIRTUAL - -// Implementation -public: - virtual ~CButtonDialer(); -// Generated message map functions -protected: - //{{AFX_MSG(CButtonDialer) - // NOTE - the ClassWizard will add and remove member functions here. - //}}AFX_MSG - - CFont m_FontLetters; - CMapStringToString m_map; - HTHEME m_hTheme; - int dpiX; - int dpiY; - - - void OpenTheme() { m_hTheme = OpenThemeData(m_hWnd, L"Button"); } - void CloseTheme() { - if (m_hTheme) { CloseThemeData(m_hTheme); m_hTheme = NULL; } - } - DECLARE_MESSAGE_MAP() - - virtual void PreSubclassWindow(); - afx_msg LRESULT OnThemeChanged(); - afx_msg void OnMouseMove(UINT,CPoint); - afx_msg void OnSize(UINT type, int w, int h); -}; - -///////////////////////////////////////////////////////////////////////////// - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_DIALERBUTTON_H__8E7A4504_82E5_4C81_8A30_642AC65A4550__INCLUDED_) diff --git a/microsip/CLevelsSliderCtrl.cpp b/microsip/CLevelsSliderCtrl.cpp deleted file mode 100644 index ab7f1f47..00000000 --- a/microsip/CLevelsSliderCtrl.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "CLevelsSliderCtrl.h" - -BEGIN_MESSAGE_MAP(CLevelsSliderCtrl, CSliderCtrl) - ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw) -END_MESSAGE_MAP() - -void CLevelsSliderCtrl::OnCustomDraw(NMHDR *pNotifyStruct, LRESULT *result) -{ - NMCUSTOMDRAW *pNmcd = (NMCUSTOMDRAW *)pNotifyStruct; - - switch (pNmcd->dwDrawStage) { - case CDDS_PREPAINT: - if (GetStyle() & TBS_ENABLESELRANGE) { - *result = CDRF_NOTIFYITEMDRAW; - } - break; - case CDDS_ITEMPREPAINT: - switch (pNmcd->dwItemSpec) { - case TBCD_THUMB: { - CDC *pDC = CDC::FromHandle(pNmcd->hdc); - CRect rect = pNmcd->rc; - int dpiX = GetDeviceCaps(pDC->m_hDC, LOGPIXELSX); - int dpiY = GetDeviceCaps(pDC->m_hDC, LOGPIXELSY); - if (GetStyle()&TBS_VERT) { - rect.DeflateRect(MulDiv(6, dpiX, 96), MulDiv(3, dpiX, 96)); - } - else { - rect.DeflateRect(MulDiv(3, dpiX, 96), MulDiv(6, dpiX, 96)); - } - pDC->FillSolidRect(&rect, RGB(170, 170, 170)); - *result = CDRF_SKIPDEFAULT; - break; - } - case TBCD_CHANNEL: { - CDC *pDC = CDC::FromHandle(pNmcd->hdc); - int min, max, selmin, selmax; - bool hot; - GetRange(min, max); - GetSelection(selmin, selmax); - max -= min; - CRect rect; - GetChannelRect(&rect); - if (GetStyle()&TBS_VERT) { - hot = selmin <= 0; - // fix windows bug - if (rect.right > rect.bottom) { - rect.left ^= rect.top ^= rect.left ^= rect.top; // swap left and top values - rect.right ^= rect.bottom ^= rect.right ^= rect.bottom; // swap right and bottom values - } - rect.DeflateRect(2, 2); - selmin = (int)(((double)(selmin - min) / max * rect.Height()) + 0.5) + rect.top; - selmax = (int)(((double)(selmax - min) / max * rect.Height()) + 0.5) + rect.top; - if (!IsActive) { - pDC->FillSolidRect(CRect(rect.left, rect.top, rect.right, rect.bottom), pDC->GetBkColor()); - } - else { - pDC->FillSolidRect(CRect(rect.left, rect.top, rect.right, rect.bottom), GetSysColor(COLOR_WINDOW)); - } - pDC->FillSolidRect(CRect(rect.left, selmin, rect.right, selmax), hot ? RGB(255, 0, 0) : GetSysColor(COLOR_HIGHLIGHT)); - pDC->ExcludeClipRect(rect); - } - else { - hot = selmax >= 100; - // fix windows bug - if (rect.bottom > rect.right) { - rect.left ^= rect.top ^= rect.left ^= rect.top; // swap left and top values - rect.right ^= rect.bottom ^= rect.right ^= rect.bottom; // swap right and bottom values - } - rect.DeflateRect(2, 2); - selmin = (int)(((double)(selmin - min) / max * rect.Width()) + 0.5) + rect.left; - selmax = (int)(((double)(selmax - min) / max * rect.Width()) + 0.5) + rect.left; - if (!IsActive) { - pDC->FillSolidRect(CRect(rect.left, rect.top, rect.right, rect.bottom), pDC->GetBkColor()); - } - else { - pDC->FillSolidRect(CRect(rect.left, rect.top, rect.right, rect.bottom), GetSysColor(COLOR_WINDOW)); - } - pDC->FillSolidRect(CRect(selmin, rect.top, selmax, rect.bottom), hot ? RGB(255, 0, 0) : GetSysColor(COLOR_HIGHLIGHT)); - pDC->ExcludeClipRect(rect); - } - *result = CDRF_DODEFAULT | CDRF_NOTIFYPOSTPAINT; - break; - } - } - break; - case CDDS_ITEMPOSTPAINT: - switch (pNmcd->dwItemSpec) { - case TBCD_CHANNEL: { - CDC *pDC = CDC::FromHandle(pNmcd->hdc); - pDC->SelectClipRgn(NULL); - break; - } - } - break; - } -} diff --git a/microsip/CLevelsSliderCtrl.h b/microsip/CLevelsSliderCtrl.h deleted file mode 100644 index cc4d2409..00000000 --- a/microsip/CLevelsSliderCtrl.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "stdafx.h" - -class CLevelsSliderCtrl : public CSliderCtrl -{ -public: - CLevelsSliderCtrl(){IsActive = false;}; - bool IsActive; - -protected: - DECLARE_MESSAGE_MAP() - afx_msg void OnCustomDraw(NMHDR *pNotifyStruct, LRESULT *result); -}; diff --git a/microsip/CListCtrl_DataModel.h b/microsip/CListCtrl_DataModel.h deleted file mode 100644 index 290dd232..00000000 --- a/microsip/CListCtrl_DataModel.h +++ /dev/null @@ -1,96 +0,0 @@ -#pragma once - -#include -#include - -using namespace std; - -struct CListCtrl_DataRecord -{ - CListCtrl_DataRecord() - {} - - CListCtrl_DataRecord(const string& city, const string& state, const string& country) - :m_City(city) - ,m_State(state) - ,m_Country(country) - {} - - string m_City; - string m_State; - string m_Country; - - const string& GetCellText(int col, bool title) const - { - switch(col) - { - case 0: { static string title0("City"); return title ? title0 : m_City; } - case 1: { static string title1("State"); return title ? title1 : m_State; } - case 2: { static string title2("Country"); return title ? title2 : m_Country; } - default:{ static string emptyStr; return emptyStr; } - } - } - - int GetColCount() const { return 3; } -}; - -class CListCtrl_DataModel -{ - vector m_Records; - int m_LookupTime; - int m_RowMultiplier; - -public: - CListCtrl_DataModel() - :m_RowMultiplier(0) - ,m_LookupTime(0) - { - InitDataModel(); - } - - void InitDataModel() - { - m_Records.clear(); - m_Records.push_back( CListCtrl_DataRecord("Copenhagen", "Sjaelland", "Denmark") ); - m_Records.push_back( CListCtrl_DataRecord("Aarhus", "Jutland", "Denmark") ); - m_Records.push_back( CListCtrl_DataRecord("Odense", "Fyn", "Denmark") ); - m_Records.push_back( CListCtrl_DataRecord("Malmoe", "Skaane", "Sweeden") ); - - if (m_RowMultiplier > 1) - { - vector rowset(m_Records); - m_Records.reserve((m_RowMultiplier-1) * rowset.size()); - for(int i = 0 ; i < m_RowMultiplier ; ++i) - { - m_Records.insert(m_Records.end(), rowset.begin(), rowset.end()); - } - } - } - - const string& GetCellText(size_t lookupId, int col) const - { - if (lookupId >= m_Records.size()) - { - static const string oob("Out of Bound"); - return oob; - } - // How many times should we search sequential for the row ? - for(int i=0; i < m_LookupTime; ++i) - { - for(size_t rowId = 0; rowId < m_Records.size(); ++rowId) - { - if (rowId==lookupId) - break; - } - } - return m_Records.at(lookupId).GetCellText(col, false); - } - - size_t GetRowIds() const { return m_Records.size(); } - int GetColCount() const { return CListCtrl_DataRecord().GetColCount(); } - const string& GetColTitle(int col) const { return CListCtrl_DataRecord().GetCellText(col, true); } - - vector& GetRecords() { return m_Records; } - void SetLookupTime(int lookupTimes) { m_LookupTime = lookupTimes; } - void SetRowMultiplier(int multiply) { if (m_RowMultiplier != multiply ) { m_RowMultiplier = multiply; InitDataModel(); } } -}; \ No newline at end of file diff --git a/microsip/CListCtrl_SortItemsEx.cpp b/microsip/CListCtrl_SortItemsEx.cpp deleted file mode 100644 index d54e669f..00000000 --- a/microsip/CListCtrl_SortItemsEx.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "stdafx.h" - -#include "CListCtrl_SortItemsEx.h" -#include "Calls.h" -#include "mainDlg.h" - -BEGIN_MESSAGE_MAP(CListCtrl_SortItemsEx, CListCtrl) - ON_NOTIFY_REFLECT_EX(LVN_COLUMNCLICK, OnHeaderClick) // Column Click -END_MESSAGE_MAP() - -namespace { - struct PARAMSORT - { - PARAMSORT(HWND hWnd, int columnIndex, bool ascending) - :m_hWnd(hWnd) - ,m_ColumnIndex(columnIndex) - ,m_Ascending(ascending) - {} - - HWND m_hWnd; - int m_ColumnIndex; - bool m_Ascending; - }; - - // Comparison extracts values from the List-Control - int CALLBACK SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) - { - PARAMSORT& ps = *(PARAMSORT*)lParamSort; - if (ps.m_ColumnIndex == 1 && mainDlg && mainDlg->pageCalls) { - CListCtrl *list = (CListCtrl*)mainDlg->pageCalls->GetDlgItem(IDC_CALLS); - if (list && ps.m_hWnd==list->m_hWnd) { - LVITEM item; - item.iItem = lParam1; - item.iSubItem = 0; - item.mask = LVIF_PARAM; - ListView_GetItem(ps.m_hWnd,&item); - Call *pCall1 = (Call *)item.lParam; - item.iItem = lParam2; - ListView_GetItem(ps.m_hWnd,&item); - Call *pCall2 = (Call *)item.lParam; - if (ps.m_Ascending) { - if (pCall1->time > pCall2->time) return 1; - else if (pCall1->time < pCall2->time) return -1; - else return 0; - } else { - if (pCall1->time > pCall2->time) return -1; - else if (pCall1->time < pCall2->time) return 1; - else return 0; - } - } - } - TCHAR left[256] = _T(""), right[256] = _T(""); - ListView_GetItemText(ps.m_hWnd, lParam1, ps.m_ColumnIndex, left, sizeof(left)); - ListView_GetItemText(ps.m_hWnd, lParam2, ps.m_ColumnIndex, right, sizeof(right)); - if (ps.m_Ascending) - return _tcscmp( left, right ); - else - return _tcscmp( right, left ); - } -} - -bool CListCtrl_SortItemsEx::SortColumn(int columnIndex, bool ascending) -{ - PARAMSORT paramsort(m_hWnd, columnIndex, ascending); - ListView_SortItemsEx(m_hWnd, SortFunc, ¶msort); - return true; -} diff --git a/microsip/CListCtrl_SortItemsEx.h b/microsip/CListCtrl_SortItemsEx.h deleted file mode 100644 index 625bcf23..00000000 --- a/microsip/CListCtrl_SortItemsEx.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "CListCtrl_Sortable.h" - -class CListCtrl_SortItemsEx : public CListCtrl_Sortable -{ - DECLARE_MESSAGE_MAP(); - -public: - virtual bool SortColumn(int columnIndex, bool ascending); -}; \ No newline at end of file diff --git a/microsip/CListCtrl_Sortable.cpp b/microsip/CListCtrl_Sortable.cpp deleted file mode 100644 index cf47be47..00000000 --- a/microsip/CListCtrl_Sortable.cpp +++ /dev/null @@ -1,191 +0,0 @@ -#include "stdafx.h" - -#include "CListCtrl_Sortable.h" -#include "Resource.h" - -#include - -BEGIN_MESSAGE_MAP(CListCtrl_Sortable, CListCtrl) - ON_NOTIFY_REFLECT_EX(LVN_COLUMNCLICK, OnHeaderClick) // Column Click -END_MESSAGE_MAP() - -namespace { - bool IsThemeEnabled() - { - HMODULE hinstDll; - bool XPStyle = false; - bool (__stdcall *pIsAppThemed)(); - bool (__stdcall *pIsThemeActive)(); - - // Test if operating system has themes enabled - hinstDll = ::LoadLibrary(_T("UxTheme.dll")); - if (hinstDll) - { - (FARPROC&)pIsAppThemed = ::GetProcAddress(hinstDll, "IsAppThemed"); - (FARPROC&)pIsThemeActive = ::GetProcAddress(hinstDll,"IsThemeActive"); - ::FreeLibrary(hinstDll); - if (pIsAppThemed != NULL && pIsThemeActive != NULL) - { - if (pIsAppThemed() && pIsThemeActive()) - { - // Test if application has themes enabled by loading the proper DLL - hinstDll = LoadLibrary(_T("comctl32.dll")); - if (hinstDll) - { - DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hinstDll, "DllGetVersion"); - ::FreeLibrary(hinstDll); - if (pDllGetVersion != NULL) - { - DLLVERSIONINFO dvi; - ZeroMemory(&dvi, sizeof(dvi)); - dvi.cbSize = sizeof(dvi); - HRESULT hRes = pDllGetVersion ((DLLVERSIONINFO *) &dvi); - if (SUCCEEDED(hRes)) - XPStyle = dvi.dwMajorVersion >= 6; - } - } - } - } - } - return XPStyle; - } - - LRESULT EnableWindowTheme(HWND hwnd, LPCWSTR app, LPCWSTR idlist) - { - HMODULE hinstDll; - HRESULT (__stdcall *pSetWindowTheme)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList); - HANDLE (__stdcall *pOpenThemeData)(HWND hwnd, LPCWSTR pszClassList); - HRESULT (__stdcall *pCloseThemeData)(HANDLE hTheme); - - hinstDll = ::LoadLibrary(_T("UxTheme.dll")); - if (hinstDll) - { - (FARPROC&)pOpenThemeData = ::GetProcAddress(hinstDll, "OpenThemeData"); - (FARPROC&)pCloseThemeData = ::GetProcAddress(hinstDll, "CloseThemeData"); - (FARPROC&)pSetWindowTheme = ::GetProcAddress(hinstDll, "SetWindowTheme"); - ::FreeLibrary(hinstDll); - if (pSetWindowTheme && pOpenThemeData && pCloseThemeData) - { - HANDLE theme = pOpenThemeData(hwnd,L"ListView"); - if (theme!=NULL) - { - VERIFY(pCloseThemeData(theme)==S_OK); - return pSetWindowTheme(hwnd, app, idlist); - } - } - } - return S_FALSE; - } -} - -BOOL CListCtrl_Sortable::OnHeaderClick(NMHDR* pNMHDR, LRESULT* pResult) -{ - NMLISTVIEW* pLV = reinterpret_cast(pNMHDR); - - SetFocus(); // Ensure other controls gets kill-focus - - int colIndex = pLV->iSubItem; - - if (m_SortCol==colIndex) - { - m_Ascending = !m_Ascending; - } - else - { - m_SortCol = colIndex; - m_Ascending = true; - } - - if (SortColumn(m_SortCol, m_Ascending)) - SetSortArrow(m_SortCol, m_Ascending); - - return FALSE; // Let parent-dialog get chance -} - -void CListCtrl_Sortable::SetSortArrow(int colIndex, bool ascending) -{ - if (IsThemeEnabled()) - { -#if (_WIN32_WINNT >= 0x501) - for(int i = 0; i < GetHeaderCtrl()->GetItemCount(); ++i) - { - HDITEM hditem = {0}; - hditem.mask = HDI_FORMAT; - VERIFY( GetHeaderCtrl()->GetItem( i, &hditem ) ); - hditem.fmt &= ~(HDF_SORTDOWN|HDF_SORTUP); - if (i == colIndex) - { - hditem.fmt |= ascending ? HDF_SORTUP : HDF_SORTDOWN; - } - VERIFY( CListCtrl::GetHeaderCtrl()->SetItem( i, &hditem ) ); - } -#endif - } - else - { - UINT bitmapID = m_Ascending ? IDB_UPARROW : IDB_DOWNARROW; - for(int i = 0; i < GetHeaderCtrl()->GetItemCount(); ++i) - { - HDITEM hditem = {0}; - hditem.mask = HDI_BITMAP | HDI_FORMAT; - VERIFY( GetHeaderCtrl()->GetItem( i, &hditem ) ); - if (hditem.fmt & HDF_BITMAP && hditem.fmt & HDF_BITMAP_ON_RIGHT) - { - if (hditem.hbm) - { - DeleteObject(hditem.hbm); - hditem.hbm = NULL; - } - hditem.fmt &= ~(HDF_BITMAP|HDF_BITMAP_ON_RIGHT); - VERIFY( CListCtrl::GetHeaderCtrl()->SetItem( i, &hditem ) ); - } - if (i == colIndex) - { - hditem.fmt |= HDF_BITMAP|HDF_BITMAP_ON_RIGHT; - hditem.hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(bitmapID), IMAGE_BITMAP, 0,0, LR_LOADMAP3DCOLORS); - VERIFY( hditem.hbm!=NULL ); - VERIFY( CListCtrl::GetHeaderCtrl()->SetItem( i, &hditem ) ); - } - } - } -} - -void CListCtrl_Sortable::PreSubclassWindow() -{ - CListCtrl::PreSubclassWindow(); - - // Focus retangle is not painted properly without double-buffering -#if (_WIN32_WINNT >= 0x501) - SetExtendedStyle(LVS_EX_DOUBLEBUFFER | GetExtendedStyle()); -#endif - SetExtendedStyle(GetExtendedStyle() | LVS_EX_FULLROWSELECT); - SetExtendedStyle(GetExtendedStyle() | LVS_EX_HEADERDRAGDROP); - - EnableWindowTheme(GetSafeHwnd(), L"Explorer", NULL); -} - -void CListCtrl_Sortable::ResetSortOrder() -{ - m_Ascending = true; - m_SortCol = -1; - SetSortArrow(m_SortCol, m_Ascending); -} - -// The column version of GetItemData(), one can specify an unique -// identifier when using InsertColumn() -int CListCtrl_Sortable::GetColumnData(int col) const -{ - LVCOLUMN lvc = {0}; - lvc.mask = LVCF_SUBITEM; - VERIFY( GetColumn(col, &lvc) ); - return lvc.iSubItem; -} - -void CListCtrl_Sortable::SetSortColumn(int columnIndex, bool ascending) -{ - m_SortCol = columnIndex; - m_Ascending = ascending; - if (SortColumn(m_SortCol, m_Ascending)) { - SetSortArrow(m_SortCol, m_Ascending); - } -} diff --git a/microsip/CListCtrl_Sortable.h b/microsip/CListCtrl_Sortable.h deleted file mode 100644 index 0fb2f762..00000000 --- a/microsip/CListCtrl_Sortable.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "CListCtrl_DataModel.h" - -class CListCtrl_Sortable : public CListCtrl -{ - bool m_Ascending; - int m_SortCol; - - DECLARE_MESSAGE_MAP(); - - afx_msg BOOL OnHeaderClick(NMHDR* pNMHDR, LRESULT* pResult); - void PreSubclassWindow(); - -public: - CListCtrl_Sortable() - :m_Ascending(false) - ,m_SortCol(-1) - {} - int GetColumnData(int col) const; - void SetSortArrow(int col, bool ascending); - int GetSortColumn() const { return m_SortCol; } - bool IsAscending() const { return m_Ascending; } - void ResetSortOrder(); - virtual bool SortColumn(int columnIndex, bool ascending) = 0; - void SetSortColumn(int columnIndex, bool ascending); -}; \ No newline at end of file diff --git a/microsip/CSVFile.cpp b/microsip/CSVFile.cpp deleted file mode 100644 index bd116e60..00000000 --- a/microsip/CSVFile.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "StdAfx.h" - -#include "CSVFile.h" - -CCSVFile::CCSVFile(): - CStdioFileEx() -{ -} - -bool CCSVFile::ReadData(CStringArray &arr) -{ - ULONGLONG pos = GetPosition(); - - // Read next line - CString sLine; - if (!ReadString(sLine)) - return false; - sLine.Trim(); - LPCTSTR p = sLine; - - int nValue = 0; - - // Parse values in this line - - while (*p != '\0') - { - CString s; // String to hold this value - - if (*p == '"') - { - // Bump past opening quote - p++; - // Parse quoted value - while (*p != '\0') - { - // Test for quote character - if (*p == '"') - { - // Found one quote - p++; - // If pair of quotes, keep one - // Else interpret as end of value - if (*p != '"') - { - p++; - break; - } - } - // Add this character to value - s.AppendChar(*p++); - } - } - else - { - // Parse unquoted value - while (*p != '\0' && *p != ',') - { - s.AppendChar(*p++); - } - // Advance to next character (if not already end of string) - if (*p != '\0') - p++; - } - // Add this string to value array - if (nValue < arr.GetCount()) - arr[nValue] = s; - else - arr.Add(s); - nValue++; - } - // Trim off any unused array values - if (arr.GetCount() > nValue) - arr.RemoveAt(nValue, arr.GetCount() - nValue); - // We return true if ReadString() succeeded--even if no values - return true; -} - -void CCSVFile::WriteData(CStringArray &arr) -{ - static TCHAR chQuote = '"'; - static TCHAR chComma = ','; - - // Loop through each string in array - for (int i = 0; i < arr.GetCount(); i++) - { - // Separate this value from previous - if (i > 0) - WriteString(_T(",")); - // We need special handling if string contains - // comma or double quote - bool bComma = (arr[i].Find(chComma) != -1); - bool bQuote = (arr[i].Find(chQuote) != -1); - if (bComma || bQuote) - { - Write(&chQuote, sizeof(TCHAR)); - if (bQuote) - { - for (int j = 0; j < arr[i].GetLength(); i++) - { - // Pairs of quotes interpreted as single quote - if (arr[i][j] == chQuote) - Write(&chQuote, sizeof(TCHAR)); - TCHAR ch = arr[i][j]; - Write(&ch, sizeof(TCHAR)); - } - } - else - { - WriteString(arr[i]); - } - Write(&chQuote, sizeof(TCHAR)); - } - else - { - WriteString(arr[i]); - } - } - WriteString(_T("\n")); -} diff --git a/microsip/CSVFile.h b/microsip/CSVFile.h deleted file mode 100644 index e67047c1..00000000 --- a/microsip/CSVFile.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include "afx.h" -#include "StdioFileEx.h" - -class CCSVFile : public CStdioFileEx -{ -public: - CCSVFile(); - bool ReadData(CStringArray &arr); - void WriteData(CStringArray &arr); -}; diff --git a/microsip/Calls.cpp b/microsip/Calls.cpp deleted file mode 100644 index 6baed38d..00000000 --- a/microsip/Calls.cpp +++ /dev/null @@ -1,626 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "Calls.h" -#include "microsip.h" -#include "global.h" -#include "settings.h" -#include -#include -#include "mainDlg.h" -#include "langpack.h" - -Calls::Calls(CWnd* pParent /*=NULL*/) -: CBaseDialog(Calls::IDD, pParent) -{ - Create (IDD, pParent); -} - -Calls::~Calls(void) -{ -} - -BOOL Calls::OnInitDialog() -{ - CBaseDialog::OnInitDialog(); - - AutoMove(IDC_CALLS,0,0,100,100); - AutoMove(IDC_SEARCH_PICTURE,0,100,0,0); - AutoMove(IDC_FILER_VALUE,0,100,100,0); - - TranslateDialog(this->m_hWnd); - - nextKey = 0; - lastDay = 0; - - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CALLS); - - list->SetExtendedStyle( list->GetExtendedStyle() | LVS_EX_FULLROWSELECT ); - - imageList = new CImageList(); - imageList->Create(16,16,ILC_COLOR32,3,3); - imageList->SetBkColor(RGB(255, 255, 255)); - imageList->Add(theApp.LoadIcon(IDI_CALL_OUT)); - imageList->Add(theApp.LoadIcon(IDI_CALL_IN)); - imageList->Add(theApp.LoadIcon(IDI_CALL_MISS)); - list->SetImageList(imageList,LVSIL_SMALL); - list->InsertColumn(0,Translate(_T("Number")),LVCFMT_LEFT, accountSettings.callsWidth0>0?accountSettings.callsWidth0:81); - list->InsertColumn(1,Translate(_T("Time")),LVCFMT_LEFT, accountSettings.callsWidth1>0?accountSettings.callsWidth1:71); - list->InsertColumn(2,Translate(_T("Duration")),LVCFMT_LEFT, accountSettings.callsWidth2>0?accountSettings.callsWidth2:40); - list->InsertColumn(3,Translate(_T("Info")),LVCFMT_LEFT, accountSettings.callsWidth3>0?accountSettings.callsWidth3:50); - - CallsLoad(); - - return TRUE; -} - -void Calls::OnCreated() -{ - m_SortItemsExListCtrl.SetSortColumn(1,false); -} - -void Calls::PostNcDestroy() -{ - CBaseDialog::PostNcDestroy(); - mainDlg->pageCalls=NULL; - delete imageList; - delete this; -} - -void Calls::DoDataExchange(CDataExchange* pDX) -{ - CBaseDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_CALLS, m_SortItemsExListCtrl); -} - - -BEGIN_MESSAGE_MAP(Calls, CBaseDialog) - ON_WM_CREATE() - ON_NOTIFY(HDN_ENDTRACK, 0, OnEndtrack) - ON_BN_CLICKED(IDOK, OnBnClickedOk) - ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel) - ON_EN_CHANGE(IDC_FILER_VALUE, OnFilterValueChange) - ON_COMMAND(ID_CALL,OnMenuCall) - ON_COMMAND(ID_CHAT,OnMenuChat) - ON_COMMAND(ID_COPY,OnMenuCopy) - ON_COMMAND(ID_DELETE,OnMenuDelete) - ON_NOTIFY(NM_DBLCLK, IDC_CALLS, &Calls::OnNMDblclkCalls) - ON_MESSAGE(WM_CONTEXTMENU,OnContextMenu) -#ifdef _GLOBAL_VIDEO - ON_COMMAND(ID_VIDEOCALL,OnMenuCallVideo) -#endif -END_MESSAGE_MAP() - -BOOL Calls::PreTranslateMessage(MSG* pMsg) -{ - BOOL catched = FALSE; - if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) { - CEdit* edit = (CEdit*)GetDlgItem(IDC_FILER_VALUE); - if (edit == GetFocus()) { - catched = TRUE; - if (isFiltered()) { - filterReset(); - } - } - } - if (!catched) { - return CBaseDialog::PreTranslateMessage(pMsg); - } else { - return TRUE; - } -} - -void Calls::OnEndtrack(NMHDR* pNMHDR, LRESULT* pResult) -{ - HD_NOTIFY *phdn = (HD_NOTIFY *)pNMHDR; - int width = phdn->pitem->cxy; - switch (phdn->iItem) { - case 0: - accountSettings.callsWidth0 = width; - break; - case 1: - accountSettings.callsWidth1 = width; - break; - case 2: - accountSettings.callsWidth2 = width; - break; - case 3: - accountSettings.callsWidth3 = width; - break; - case 4: - accountSettings.callsWidth4 = width; - break; - } - mainDlg->AccountSettingsPendingSave(); - *pResult = 0; -} - - -void Calls::OnBnClickedOk() -{ - MessageDlgOpen(accountSettings.singleMode); -} - -void Calls::OnBnClickedCancel() -{ - mainDlg->ShowWindow(SW_HIDE); -} - -void Calls::OnFilterValueChange() -{ - CallsClear(); - CallsLoad(); -} - -bool Calls::isFiltered(Call *pCall) { - CEdit* edit = (CEdit*)GetDlgItem(IDC_FILER_VALUE); - CString str; - edit->GetWindowText(str); - if (!str.IsEmpty()) { - if (!pCall ) { - return true; - } - str.MakeLower(); - CString name = pCall->name; - CString number = pCall->number; - name.MakeLower(); - number.MakeLower(); - if (name.Find(str) ==-1 && number.Find(str) ==-1) { - return true; - } - } - return false; -} - -void Calls::filterReset() -{ - CEdit* edit = (CEdit*)GetDlgItem(IDC_FILER_VALUE); - edit->SetWindowText(_T("")); -} - -LRESULT Calls::OnContextMenu(WPARAM wParam,LPARAM lParam) -{ - int x = GET_X_LPARAM(lParam); - int y = GET_Y_LPARAM(lParam); - POINT pt = { x, y }; - RECT rc; - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CALLS); - POSITION pos = list->GetFirstSelectedItemPosition(); - int selectedItem = -1; - if (pos) { - selectedItem = list->GetNextSelectedItem(pos); - } - if (x!=-1 || y!=-1) { - ScreenToClient(&pt); - GetClientRect(&rc); - if (!PtInRect(&rc, pt)) { - x = y = -1; - } - } else { - if (selectedItem != -1) { - list->GetItemPosition(selectedItem,&pt); - list->ClientToScreen(&pt); - x = 40+pt.x; - y = 8+pt.y; - } else { - ::ClientToScreen((HWND)wParam, &pt); - x = 10+pt.x; - y = 26+pt.y; - } - } - if (x!=-1 || y!=-1) { - CMenu menu; - if (menu.LoadMenu(IDR_MENU_CONTACT)) { - CMenu* tracker = menu.GetSubMenu(0); - TranslateMenu(tracker->m_hMenu); - tracker->RemoveMenu(ID_ADD,0); - tracker->RemoveMenu(ID_EDIT,0); - if (selectedItem != -1) { - tracker->EnableMenuItem(ID_CALL, FALSE); -#ifdef _GLOBAL_VIDEO - tracker->EnableMenuItem(ID_VIDEOCALL, FALSE); -#endif - tracker->EnableMenuItem(ID_CHAT, FALSE); - tracker->EnableMenuItem(ID_COPY, FALSE); - tracker->EnableMenuItem(ID_DELETE, FALSE); - } else { - tracker->EnableMenuItem(ID_CALL, TRUE); -#ifdef _GLOBAL_VIDEO - tracker->EnableMenuItem(ID_VIDEOCALL, TRUE); -#endif - tracker->EnableMenuItem(ID_CHAT, TRUE); - tracker->EnableMenuItem(ID_COPY, TRUE); - tracker->EnableMenuItem(ID_DELETE, TRUE); - } - tracker->TrackPopupMenu( 0, x, y, this ); - } - return TRUE; - } - return DefWindowProc(WM_CONTEXTMENU,wParam,lParam); -} - -void Calls::MessageDlgOpen(BOOL isCall, BOOL hasVideo) -{ - if (accountSettings.singleMode && call_get_count_noincoming() && isCall) { - mainDlg->GotoTab(0); - return; - } - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CALLS); - POSITION pos = list->GetFirstSelectedItemPosition(); - if (pos) { - int i = list->GetNextSelectedItem(pos); - Call *pCall = (Call *) list->GetItemData(i); - if (isCall) { - mainDlg->MakeCall(pCall->number, hasVideo); - } else { - mainDlg->MessagesOpen(pCall->number); - } - } -} - -void Calls::OnNMDblclkCalls(NMHDR *pNMHDR, LRESULT *pResult) -{ - LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR); - if (pNMItemActivate->iItem!=-1) { - MessageDlgOpen(accountSettings.singleMode); - } - *pResult = 0; -} - -void Calls::OnMenuCall() -{ - MessageDlgOpen(TRUE); -} - -#ifdef _GLOBAL_VIDEO -void Calls::OnMenuCallVideo() -{ - MessageDlgOpen(TRUE, TRUE); -} -#endif - -void Calls::OnMenuChat() -{ - MessageDlgOpen(); -} - -void Calls::OnMenuCopy() -{ - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CALLS); - POSITION pos = list->GetFirstSelectedItemPosition(); - if (pos) - { - int i = list->GetNextSelectedItem(pos); - Call *pCall = (Call *) list->GetItemData(i); - mainDlg->CopyStringToClipboard(pCall->number); - } -} - -void Calls::OnMenuDelete() -{ - CListCtrl *pList= (CListCtrl*)GetDlgItem(IDC_CALLS); - POSITION pos = pList->GetFirstSelectedItemPosition(); - while (pos) { - Delete(pList->GetNextSelectedItem(pos)); - pos = pList->GetFirstSelectedItemPosition(); - } -} - -void Calls::Delete(int i) -{ - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CALLS); - Call *pCall = (Call *) list->GetItemData(i); - pCall->number = _T(""); - CallSave(pCall); - delete pCall; - list->DeleteItem(i); -} - -void Calls::Add(pj_str_t id, CString number, CString name, int type) -{ - CString callId = PjToStr(&id); - int i = Get(callId); - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CALLS); - if (i==-1) { - ReloadTime(); - SIPURI sipuri; - ParseSIPURI(number, &sipuri); - if (!sipuri.user.IsEmpty() || !sipuri.domain.IsEmpty()) { - Call *pCall = new Call(); - pCall->id = callId; - if (sipuri.user.IsEmpty()) { - pCall->number = sipuri.domain+sipuri.parameters; - } else { - if (sipuri.parameters.IsEmpty() && (accountSettings.account.domain == sipuri.domain || sipuri.domain.IsEmpty())) { - pCall->number = sipuri.user; - } else { - pCall->number = sipuri.user+_T("@")+sipuri.domain+sipuri.parameters; - } - } - pCall->name = name; - pCall->type = type; - pCall->time = CTime::GetCurrentTime().GetTime(); - pCall->duration = 0; - if (nextKey>=1000) { - nextKey = 0; - } - pCall->key = nextKey; - Insert(pCall); - CallSave(pCall); - } - } else { - Call *pCall = (Call *) list->GetItemData(i); - if (pCall->type == MSIP_CALL_MISS && pCall->type != type) { - pCall->type = type; - list->SetItem(i,0,LVIF_IMAGE,NULL,type,0,0,0); - CallSave(pCall); - } - } -} - -void Calls::SetDuration(pj_str_t id, int sec) { - CString callId = PjToStr(&id); - int i = Get(callId); - if (i!=-1) { - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CALLS); - Call *pCall = (Call *) list->GetItemData(i); - pCall->duration = sec; - list->SetItemText(i,2,GetDuration(pCall->duration)); - CallSave(pCall); - } -} - -void Calls::SetInfo(pj_str_t id, CString str) { - CString callId = PjToStr(&id); - int i = Get(callId); - if (i!=-1) { - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CALLS); - Call *pCall = (Call *) list->GetItemData(i); - pCall->info = str; - list->SetItemText(i,3,str); - CallSave(pCall); - } -} - -int Calls::Get(CString id) -{ - if (isFiltered()) { - filterReset(); - } - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CALLS); - int count = list->GetItemCount(); - for (int i=0;iGetItemData(i); - if (pCall->id == id) { - return i; - } - } - return -1; -} - - -void Calls::Insert(Call *pCall, int pos) -{ - if (isFiltered(pCall)) { - return; - } - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CALLS); - CString number; - if (pCall->name != pCall->number) { - number.AppendFormat(_T("%s (%s)"),pCall->name,pCall->number); - } else { - number = pCall->name; - } - int i = list->InsertItem(LVIF_TEXT|LVIF_PARAM|LVIF_IMAGE,pos,number,0,0,pCall->type,(LPARAM)pCall); - list->SetItemText(i,1,FormatTime(pCall->time)); - list->SetItemText(i,2,GetDuration(pCall->duration)); - list->SetItemText(i,3,pCall->info); -} - -void Calls::CallsClear() -{ - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CALLS); - int count = list->GetItemCount(); - for (int i=0;iGetItemData(i); - delete pCall; - } - list->DeleteAllItems(); -} - -CString Calls::FormatTime(int time, CTime *pTimeNow) -{ - CTime timeNow; - if (!pTimeNow) { - timeNow = CTime::GetCurrentTime(); - pTimeNow = &timeNow; - } - if (!lastDay) { - lastDay = pTimeNow->GetDay(); - } - CTime timeCall(time); - return timeCall.Format( - pTimeNow->GetYear()==timeCall.GetYear() && - pTimeNow->GetMonth()==timeCall.GetMonth() && - pTimeNow->GetDay()==timeCall.GetDay() - ?_T("%X"):_T("%c") - ); -} - -void Calls::ReloadTime() -{ - CTime timeNow = CTime::GetCurrentTime(); - if (lastDay && lastDay != timeNow.GetDay()) { - lastDay = timeNow.GetDay(); - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CALLS); - int count = list->GetItemCount(); - for (int i=0;iGetItemData(i); - CTime timeCall(pCall->time); - list->SetItemText(i,1,FormatTime(pCall->time, &timeNow)); - } - } -} - - -void Calls::CallSave(Call *pCall) -{ - CString key; - // pCall->number == "" means delete - CString data = !pCall->number.IsEmpty() ? CallEncode(pCall) : _T("null"); - key.Format(_T("%d"), pCall->key); - WritePrivateProfileString(_T("Calls"), key, data, accountSettings.iniFile); - if (pCall->key == nextKey) { - nextKey++; - } -} - -void Calls::CallsLoad() -{ - CString key; - CString val; - LPTSTR ptr = val.GetBuffer(255); - int prevTime = 0; - int pos = -1; - int inserted = 0; - nextKey=0; - int i=0; - while (true) { - key.Format(_T("%d"),i); - if (GetPrivateProfileString(_T("Calls"), key, NULL, ptr, 256, accountSettings.iniFile)) { - if (val != _T("null")) { - Call *pCall = new Call(); - CallDecode(ptr, pCall); - bool skip = false; - if (isFiltered(pCall)) { - skip = true; - delete pCall; - } - if (!skip) { - pCall->key = i; - if (pos == -1) { - if ( prevTime > pCall->time) { - pos = inserted; - } - } - if (pos == -1) { - Insert(pCall); - prevTime = pCall->time; - nextKey = pCall->key; - } else { - Insert(pCall, pos); - } - inserted++; - } - } - } else { - i--; - break; - } - i++; - } - if (i!=-1) { - nextKey++; - } - m_SortItemsExListCtrl.SortColumn(m_SortItemsExListCtrl.GetSortColumn(),m_SortItemsExListCtrl.IsAscending()); -} - -CString Calls::CallEncode(Call *pCall) -{ - CString data; - data.Format(_T("%s;%s;%d;%d;%d;%s"), pCall->number, pCall->name, pCall->type, pCall->time, pCall->duration, pCall->info); - return data; -} - -void Calls::CallDecode(CString str, Call *pCall) -{ - pCall->number=str; - pCall->name = pCall->number; - pCall->type = 0; - pCall->time = 0; - pCall->duration = 0; - - CString rab; - int begin; - int end; - begin = 0; - end = str.Find(';', begin); - - if (end != -1) - { - pCall->number=str.Mid(begin, end-begin); - begin = end + 1; - end = str.Find(';', begin); - if (end != -1) - { - pCall->name=str.Mid(begin, end-begin); - begin = end + 1; - end = str.Find(';', begin); - if (end != -1) - { - pCall->type=atoi(CStringA(str.Mid(begin, end-begin))); - if (pCall->type>2 || pCall->type<0) { - pCall->type = 0; - } - begin = end + 1; - end = str.Find(';', begin); - if (end != -1) - { - pCall->time=atoi(CStringA(str.Mid(begin, end-begin))); - begin = end + 1; - end = str.Find(';', begin); - if (end != -1) - { - pCall->duration=atoi(CStringA(str.Mid(begin, end-begin))); - begin = end + 1; - end = str.Find(';', begin); - if (end != -1) - { - pCall->info=str.Mid(begin, end-begin); - begin = end + 1; - end = str.Find(';', begin); - } else { - pCall->info=str.Mid(begin); - } - } - } - } - } - } -} -/* -CString Calls::GetNameByNumber(CString number) -{ - CString name; - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CALLS); - - CString sipURI = GetSIPURI(number); - int n = list->GetItemCount(); - for (int i=0; iGetItemData(i); - if (GetSIPURI(pCall->number) == sipURI) - { - name = pCall->name; - break; - } - } - return name; -} -*/ diff --git a/microsip/Calls.h b/microsip/Calls.h deleted file mode 100644 index 5d5ed0cc..00000000 --- a/microsip/Calls.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#pragma once - -#include "resource.h" -#include "global.h" -#include "BaseDialog.h" -#include "CListCtrl_SortItemsEx.h" - -class Calls : - public CBaseDialog -{ -public: - Calls(CWnd* pParent = NULL); // standard constructor - ~Calls(); - enum { IDD = IDD_CALLS }; - - CListCtrl_SortItemsEx m_SortItemsExListCtrl; - - void Add(pj_str_t id, CString number, CString name, int type); - void SetDuration(pj_str_t id, int sec); - void SetInfo(pj_str_t id, CString str); - void Delete(int i); - void UpdateCallButton(); - //CString GetNameByNumber(CString number); - - void CallsLoad(); - void CallsClear(); - CString FormatTime(int time, CTime *pTimeNow = NULL); - void ReloadTime(); - bool isFiltered(Call *pCall = NULL); - void filterReset(); - - void OnCreated(); - -private: - CImageList* imageList; - int lastDay; - int nextKey; - void CallSave(Call *pCall); - void CallDecode(CString str, Call *pCall); - CString CallEncode(Call *pCall); - void Insert(Call *pCall, int pos = 0); - int Get(CString id); - void MessageDlgOpen(BOOL isCall = FALSE, BOOL hasVideo = FALSE); - -protected: - virtual BOOL OnInitDialog(); - virtual void PostNcDestroy(); - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - DECLARE_MESSAGE_MAP() -public: - afx_msg void OnBnClickedOk(); - afx_msg void OnBnClickedCancel(); - afx_msg void OnFilterValueChange(); - afx_msg void OnMenuCall(); - afx_msg void OnMenuChat(); - afx_msg void OnMenuCopy(); - afx_msg void OnMenuDelete(); - afx_msg LRESULT OnContextMenu(WPARAM wParam,LPARAM lParam); - afx_msg void OnNMDblclkCalls(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnEndtrack(NMHDR* pNMHDR, LRESULT* pResult); -#ifdef _GLOBAL_VIDEO - afx_msg void OnMenuCallVideo(); -#endif - virtual BOOL PreTranslateMessage(MSG* pMsg); -}; - diff --git a/microsip/ClosableTabCtrl.cpp b/microsip/ClosableTabCtrl.cpp deleted file mode 100644 index 84c7c3c9..00000000 --- a/microsip/ClosableTabCtrl.cpp +++ /dev/null @@ -1,581 +0,0 @@ -#include "stdafx.h" -#include "mainDlg.h" -#include "ClosableTabCtrl.h" -#include "VisualStylesXP.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - - -// _WIN32_WINNT >= 0x0501 (XP only) -#define _WM_THEMECHANGED 0x031A -#define _ON_WM_THEMECHANGED() \ - { _WM_THEMECHANGED, 0, 0, 0, AfxSig_l, \ - (AFX_PMSG)(AFX_PMSGW) \ - (static_cast< LRESULT (AFX_MSG_CALL CWnd::*)(void) > (_OnThemeChanged)) \ - }, - -/////////////////////////////////////////////////////////////////////////////// -// CClosableTabCtrl - -IMPLEMENT_DYNAMIC(CClosableTabCtrl, CTabCtrl) - -BEGIN_MESSAGE_MAP(CClosableTabCtrl, CTabCtrl) - ON_WM_LBUTTONUP() - ON_WM_LBUTTONDOWN() - ON_WM_LBUTTONDBLCLK() - ON_WM_MBUTTONUP() - ON_WM_CREATE() - ON_WM_SYSCOLORCHANGE() - ON_WM_CONTEXTMENU() - _ON_WM_THEMECHANGED() - ON_WM_CTLCOLOR_REFLECT() - ON_WM_CTLCOLOR() - ON_WM_ERASEBKGND() - ON_WM_MEASUREITEM() - ON_WM_MEASUREITEM_REFLECT() -END_MESSAGE_MAP() - -CClosableTabCtrl::CClosableTabCtrl() -{ - m_bCloseable = true; - memset(&m_iiCloseButton, 0, sizeof m_iiCloseButton); - m_ptCtxMenu.SetPoint(-1, -1); - iTabClose = -1; -} - -CClosableTabCtrl::~CClosableTabCtrl() -{ -} - -void CClosableTabCtrl::GetCloseButtonRect(int iItem, const CRect& rcItem, CRect& rcCloseButton, bool bItemSelected, bool bVistaThemeActive) -{ - rcCloseButton.top = rcItem.top + 2; - rcCloseButton.bottom = rcCloseButton.top + (m_iiCloseButton.rcImage.bottom - m_iiCloseButton.rcImage.top); - rcCloseButton.right = rcItem.right - 2; - rcCloseButton.left = rcCloseButton.right - (m_iiCloseButton.rcImage.right - m_iiCloseButton.rcImage.left); - if (bVistaThemeActive) - rcCloseButton.left -= 1; // the close button does not look 'symetric' with a width of 16, give it 17 - if (bItemSelected) { - rcCloseButton.OffsetRect(-1, 0); - if (bVistaThemeActive) { - int iItems = GetItemCount(); - if (iItems > 1 && iItem == iItems - 1) - rcCloseButton.OffsetRect(-2, 0); - } - } - else { - if (bVistaThemeActive) { - int iItems = GetItemCount(); - if (iItems > 1 && iItem < iItems - 1) - rcCloseButton.OffsetRect(2, 0); - } - } -} - -int CClosableTabCtrl::GetTabUnderPoint(CPoint point) const -{ - int iTabs = GetItemCount(); - for (int i = 0; i < iTabs; i++) - { - CRect rcItem; - GetItemRect(i, rcItem); - rcItem.InflateRect(2, 2); // get the real tab item rect - if (rcItem.PtInRect(point)) - return i; - } - return -1; -} - -int CClosableTabCtrl::GetTabUnderContextMenu() const -{ - if (m_ptCtxMenu.x == -1 || m_ptCtxMenu.y == -1) - return -1; - return GetTabUnderPoint(m_ptCtxMenu); -} - -bool CClosableTabCtrl::SetDefaultContextMenuPos() -{ - int iTab = GetCurSel(); - if (iTab != -1) - { - CRect rcItem; - if (GetItemRect(iTab, &rcItem)) - { - rcItem.InflateRect(2, 2); // get the real tab item rect - m_ptCtxMenu.x = rcItem.left + rcItem.Width()/2; - m_ptCtxMenu.y = rcItem.top + rcItem.Height()/2; - return true; - } - } - return false; -} - -void CClosableTabCtrl::OnMButtonUp(UINT nFlags, CPoint point) -{ - if (m_bCloseable) - { - int iTab = GetTabUnderPoint(point); - if (iTab != -1) { - GetParent()->SendMessage(UM_CLOSETAB, (WPARAM)iTab); - return; - } - } - - CTabCtrl::OnMButtonUp(nFlags, point); -} - -void CClosableTabCtrl::OnLButtonUp(UINT nFlags, CPoint point) -{ - if (iTabClose != -1) { - GetParent()->SendMessage(UM_CLOSETAB, (WPARAM)iTabClose); - iTabClose = -1; - } else { - CTabCtrl::OnLButtonUp(nFlags, point); - } -} - -void CClosableTabCtrl::OnLButtonDown(UINT nFlags, CPoint point) -{ - if (m_bCloseable) - { - int iTab = GetTabUnderPoint(point); - if (iTab != -1) - { - CRect rcItem; - GetItemRect(iTab, rcItem); - rcItem.InflateRect(2, 2); // get the real tab item rect - - bool bVistaThemeActive = IsVistaThemeActive(); - CRect rcCloseButton; - GetCloseButtonRect(iTab, rcItem, rcCloseButton, iTab == GetCurSel(), bVistaThemeActive); - - // The visible part of our close icon is one pixel less on each side - if (!bVistaThemeActive) { - rcCloseButton.top += 1; - rcCloseButton.left += 1; - rcCloseButton.right -= 1; - rcCloseButton.bottom -= 1; - } - - if (rcCloseButton.PtInRect(point)) { - iTabClose = iTab; - return; - } - } - } - - CTabCtrl::OnLButtonDown(nFlags, point); -} - -void CClosableTabCtrl::OnLButtonDblClk(UINT nFlags, CPoint point) -{ - int iTab = GetTabUnderPoint(point); - if (iTab != -1) { - GetParent()->SendMessage(UM_DBLCLICKTAB, (WPARAM)iTab); - return; - } - CTabCtrl::OnLButtonDblClk(nFlags, point); -} - -// It would be nice if there would the option to restrict the maximum width of a tab control. -// We would need that feature actually for almost all our tab controls. Especially for the -// search results list - those tab control labels can get quite large. But I did not yet a -// find a way to limit the width of tabs. Although MSDN says that an owner drawn -// tab control receives a WM_MEASUREITEM, I never got one. - -// Vista: This gets never called for an owner drawn tab control -void CClosableTabCtrl::OnMeasureItem(int iCtlId, LPMEASUREITEMSTRUCT lpMeasureItemStruct) -{ - TRACE("CClosableTabCtrl::OnMeasureItem\n"); - __super::OnMeasureItem(iCtlId, lpMeasureItemStruct); -} - -// Vista: This gets never called for an owner drawn tab control -void CClosableTabCtrl::MeasureItem(LPMEASUREITEMSTRUCT) -{ - TRACE("CClosableTabCtrl::MeasureItem\n"); -} - -void CClosableTabCtrl::DrawItem(LPDRAWITEMSTRUCT lpDIS) -{ - CRect rect(lpDIS->rcItem); - int nTabIndex = lpDIS->itemID; - if (nTabIndex < 0) - return; - - TCHAR szLabel[256]; - TC_ITEM tci; - tci.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_STATE; - tci.pszText = szLabel; - tci.cchTextMax = _countof(szLabel); - tci.dwStateMask = TCIS_HIGHLIGHTED; - if (!GetItem(nTabIndex, &tci)) - return; - szLabel[_countof(szLabel) - 1] = _T('\0'); - //TRACE("CClosableTabCtrl::DrawItem: item=%u, state=%08x, color=%08x, rc=%3d,%3d,%3dx%3d\n", nTabIndex, tci.dwState, GetTextColor(lpDIS->hDC), lpDIS->rcItem.left, lpDIS->rcItem.top, lpDIS->rcItem.right - lpDIS->rcItem.left, lpDIS->rcItem.bottom - lpDIS->rcItem.top); - - CDC* pDC = CDC::FromHandle(lpDIS->hDC); - if (!pDC) - return; - - CRect rcFullItem(lpDIS->rcItem); - bool bSelected = (lpDIS->itemState & ODS_SELECTED) != 0; - - /////////////////////////////////////////////////////////////////////////////////////// - // Adding support for XP Styles (Vista Themes) for owner drawn tab controls simply - // does *not* work under Vista. Maybe it works under XP (did not try), but that is - // meaningless because under XP a owner drawn tab control is already rendered *with* - // the proper XP Styles. So, for XP there is no need to care about the theme API at all. - // - // However, under Vista, a tab control which has the TCS_OWNERDRAWFIXED - // style gets additional 3D-borders which are applied by Vista *after* WM_DRAWITEM - // was processed. Thus, there is no known workaround available to prevent Vista from - // adding those old fashioned 3D-borders. We can render the tab control items within - // the WM_DRAWITEM handler in whatever style we want, but Vista will in each case - // overwrite the borders of each tab control item with old fashioned 3D-borders... - // - // To complete this experience, tab controls also do not support NMCUSTOMDRAW. So, the - // only known way to customize a tab control is by using TCS_OWNERDRAWFIXED which does - // however not work properly under Vista. - // - // The "solution" which is currently implemented to prevent Vista from drawing those - // 3D-borders is by using "ExcludeClipRect" to reduce the drawing area which is used - // by Windows after WM_DRAWITEM was processed. This "solution" is very sensitive to - // the used rectangles and offsets in general. Incrementing/Decrementing one of the - // "rcItem", "rcFullItem", etc. rectangles makes the entire "solution" flawed again - // because some borders would become visible again. - // - HTHEME hTheme = NULL; - int iPartId = TABP_TABITEM; - int iStateId = TIS_NORMAL; - bool bVistaHotTracked = false; - bool bVistaThemeActive = IsVistaThemeActive(); - if (bVistaThemeActive) - { - // To determine if the current item is in 'hot tracking' mode, we need to evaluate - // the current foreground color - there is no flag which would indicate this state - // more safely. This applies only for Vista and for tab controls which have the - // TCS_OWNERDRAWFIXED style. - bVistaHotTracked = pDC->GetTextColor() == GetSysColor(COLOR_HOTLIGHT); - - hTheme = g_xpStyle.OpenThemeData(m_hWnd, L"TAB"); - if (hTheme) - { - if (bSelected) { - // get the real tab item rect - rcFullItem.left += 1; - rcFullItem.right -= 1; - rcFullItem.bottom -= 1; - } - else - rcFullItem.InflateRect(2, 2); // get the real tab item rect - - CRect rcBk(rcFullItem); - if (bSelected) - { - iStateId = TTIS_SELECTED; - if (nTabIndex == 0) { - // First item - if (nTabIndex == GetItemCount() - 1) - iPartId = TABP_TOPTABITEMBOTHEDGE; // First & Last item - else - iPartId = TABP_TOPTABITEMLEFTEDGE; - } - else if (nTabIndex == GetItemCount() - 1) { - // Last item - iPartId = TABP_TOPTABITEMRIGHTEDGE; - } - else { - iPartId = TABP_TOPTABITEM; - } - } - else - { - rcBk.top += 2; - iStateId = bVistaHotTracked ? TIS_HOT : TIS_NORMAL; - if (nTabIndex == 0) { - // First item - if (nTabIndex == GetItemCount() - 1) - iPartId = TABP_TABITEMBOTHEDGE; // First & Last item - else - iPartId = TABP_TABITEMLEFTEDGE; - } - else if (nTabIndex == GetItemCount() - 1) { - // Last item - iPartId = TABP_TABITEMRIGHTEDGE; - } - else { - iPartId = TABP_TABITEM; - } - } - if (g_xpStyle.IsThemeBackgroundPartiallyTransparent(hTheme, iPartId, iStateId)) - g_xpStyle.DrawThemeParentBackground(m_hWnd, *pDC, &rcFullItem); - g_xpStyle.DrawThemeBackground(hTheme, *pDC, iPartId, iStateId, &rcBk, NULL); - } - } - - // Following background clearing is needed for: - // WinXP/Vista (when used without an application theme) - // Vista (when used with an application theme but without a theme for the tab control) - if ( (!g_xpStyle.IsThemeActive() || !g_xpStyle.IsAppThemed()) - || (hTheme == NULL && bVistaThemeActive) ) { - CRect rectFill; - rectFill.left = rect.left+1; - rectFill.top = rect.top+1; - rectFill.right = rect.right-1; - rectFill.bottom = rect.bottom; - COLORREF clref = ::GetSysColor(COLOR_BTNFACE); - if (bSelected) { - BYTE r = GetRValue(clref); - BYTE g = GetGValue(clref); - BYTE b = GetBValue(clref); - if (r==g && g==b && b==255) { - clref = RGB(224, 224, 224); - } else { - clref = RGB(255, 255, 255); - } - } - pDC->FillSolidRect(rectFill, clref); - } - - int iOldBkMode = pDC->SetBkMode(TRANSPARENT); - - // Draw image on left side - CImageList *piml = GetImageList(); - if (tci.iImage >= 0 && piml && piml->m_hImageList) - { - IMAGEINFO ii; - piml->GetImageInfo(0, &ii); - rect.left += bSelected ? 8 : 4; - piml->Draw(pDC, tci.iImage, CPoint(rect.left, rect.top + (bSelected?2:1)), ILD_TRANSPARENT); - rect.left += (ii.rcImage.right - ii.rcImage.left); - if (!bSelected) - rect.left += 4; - } - - bool bCloseable = m_bCloseable; - if (bCloseable && GetParent()->SendMessage(UM_QUERYTAB, nTabIndex)) - bCloseable = false; - - // Draw 'Close button' at right side - if (bCloseable && m_ImgLstCloseButton.m_hImageList) - { - CRect rcCloseButton; - GetCloseButtonRect(nTabIndex, rect, rcCloseButton, bSelected, bVistaThemeActive); - - HTHEME hThemeNC = bVistaThemeActive ? g_xpStyle.OpenThemeData(m_hWnd, L"WINDOW") : NULL; - if (hThemeNC) { - // Possible "Close" parts: WP_CLOSEBUTTON, WP_SMALLCLOSEBUTTON, WP_MDICLOSEBUTTON - int iPartId = WP_SMALLCLOSEBUTTON; - int iStateId = (bSelected || bVistaHotTracked) ? CBS_NORMAL : CBS_DISABLED; - if (g_xpStyle.IsThemeBackgroundPartiallyTransparent(hTheme, iPartId, iStateId)) - g_xpStyle.DrawThemeParentBackground(m_hWnd, *pDC, &rcCloseButton); - g_xpStyle.DrawThemeBackground(hThemeNC, *pDC, iPartId, iStateId, rcCloseButton, NULL); - g_xpStyle.CloseThemeData(hThemeNC); - } - else { - m_ImgLstCloseButton.Draw(pDC, (bSelected || bVistaHotTracked) ? 0 : 1, rcCloseButton.TopLeft(), ILD_TRANSPARENT); - } - - rect.right = rcCloseButton.left - 2; - if (bSelected) - rect.left += hTheme ? 4 : 2; - } - - COLORREF crOldColor = CLR_NONE; - if (tci.dwState & TCIS_HIGHLIGHTED) - crOldColor = pDC->SetTextColor(RGB(192, 0, 0)); - else if (bVistaHotTracked) - crOldColor = pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT)); - - rect.top += bSelected ? 4 : 3; - // Vista: Tab control has troubles with determining the width of a tab if the - // label contains one '&' character. To get around this, we use the old code which - // replaces one '&' character with two '&' characters and we do not specify DT_NOPREFIX - // here when drawing the text. - // - // Vista: "DrawThemeText" can not be used in case we need a certain foreground color. Thus we always us - // "DrawText" to always get the same font and metrics (just for safety). - pDC->DrawText(szLabel, rect, DT_SINGLELINE | DT_TOP | DT_CENTER /*| DT_NOPREFIX*/); - - if (crOldColor != CLR_NONE) - pDC->SetTextColor(crOldColor); - pDC->SetBkMode(iOldBkMode); - - if (hTheme) - { - CRect rcClip(rcFullItem); - if (bSelected) { - rcClip.left -= 2 + 1; - rcClip.right += 2 + 1; - } - else { - rcClip.top += 2; - } - pDC->ExcludeClipRect(&rcClip); - g_xpStyle.CloseThemeData(hTheme); - } -} - -void CClosableTabCtrl::PreSubclassWindow() -{ - CTabCtrl::PreSubclassWindow(); - InternalInit(); -} - -int CClosableTabCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (CTabCtrl::OnCreate(lpCreateStruct) == -1) - return -1; - InternalInit(); - return 0; -} - -void CClosableTabCtrl::InternalInit() -{ - ModifyStyle(0, TCS_OWNERDRAWFIXED); - -#if 1 - // Under Vista Aero, all tab controls get by default the TCS_HOTTRACK - // style even if it was not specified within the resource file. Though, to 'see' - // the hot tracking effect the control also need to get initialized explicitly with - // the WS_CLIPCHILDREN style within a *seperate* function call. Yes, there is no - // logic to all this, not at all. It simply is that way. - // - // So, do *not* "optimize" that code by using only one "ModifyStyle" function call. - // The 2nd function call to "ModifyStyle" is very much by intention! - // - // However, the hot tracking effect which is achived this way does not survive a - // theme change. After the theme is changed (regardless whether we switch between - // Vista themes or from/to a non-Vista theme), the hot tracking effect is gone even - // if we try to modify the styles again within OnThemeChanged... - if (IsVistaThemeActive()) - ModifyStyle(0, WS_CLIPCHILDREN); -#else - // Remove the automatically applied hot tracking effect to avoid that the tab control - // may use it when it also sets the WS_CLIPCHILDREN (for other reasons) later. - ModifyStyle(TCS_HOTTRACK, 0); -#endif - - SetAllIcons(); -} - -void CClosableTabCtrl::OnSysColorChange() -{ - CTabCtrl::OnSysColorChange(); - SetAllIcons(); -} - -void CClosableTabCtrl::SetAllIcons() -{ - if (m_bCloseable) - { - const int iIconWidth = 16; - const int iIconHeight = 16; - m_ImgLstCloseButton.DeleteImageList(); - m_ImgLstCloseButton.Create(iIconWidth, iIconHeight, ILC_COLOR32 | ILC_MASK, 0, 1); - m_ImgLstCloseButton.Add(AfxGetApp()->LoadIcon(IDI_CLOSE)); - m_ImgLstCloseButton.Add(AfxGetApp()->LoadIcon(IDI_CLOSE_2)); - m_ImgLstCloseButton.GetImageInfo(0, &m_iiCloseButton); - Invalidate(); - } -} - -void CClosableTabCtrl::OnContextMenu(CWnd* pWnd, CPoint point) -{ - /* - if (m_bCloseable) - { - if (point.x == -1 || point.y == -1) { - if (!SetDefaultContextMenuPos()) - return; - point = m_ptCtxMenu; - ClientToScreen(&point); - } - else { - m_ptCtxMenu = point; - ScreenToClient(&m_ptCtxMenu); - } - - int iTab = GetTabUnderPoint(m_ptCtxMenu); - if (iTab != -1) - { - if (GetParent()->SendMessage(UM_QUERYTAB, (WPARAM)iTab) == 0) - { - CMenu menu; - menu.CreatePopupMenu(); - menu.AppendMenu(MF_STRING, MP_REMOVE, GetResString(IDS_FD_CLOSE)); - menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); - } - } - } - */ - return CTabCtrl::OnContextMenu(pWnd, point); -} - -BOOL CClosableTabCtrl::OnCommand(WPARAM wParam, LPARAM lParam) -{ - /* - if (wParam == MP_REMOVE) - { - if (m_ptCtxMenu.x != -1 && m_ptCtxMenu.y != -1) - { - int iTab = GetTabUnderPoint(m_ptCtxMenu); - if (iTab != -1) { - GetParent()->SendMessage(UM_CLOSETAB, (WPARAM)iTab); - return TRUE; - } - } - } - */ - return CTabCtrl::OnCommand(wParam, lParam); -} - -LRESULT CClosableTabCtrl::_OnThemeChanged() -{ - // Owner drawn tab control seems to have troubles with updating itself due to an XP theme change.. - ModifyStyle(TCS_OWNERDRAWFIXED, 0); // Reset control style to not-owner drawn - Default(); // Process original WM_THEMECHANGED message - ModifyStyle(0, TCS_OWNERDRAWFIXED); // Apply owner drawn style again - return 0; -} - -// Vista: This gets never called for an owner drawn tab control -HBRUSH CClosableTabCtrl::CtlColor(CDC* /*pDC*/, UINT /*nCtlColor*/) -{ - // Change any attributes of the DC here - // Return a non-NULL brush if the parent's handler should not be called - return NULL; -} - -// Vista: This gets never called for an owner drawn tab control -HBRUSH CClosableTabCtrl::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) -{ - HBRUSH hbr = CTabCtrl::OnCtlColor(pDC, pWnd, nCtlColor); - // Change any attributes of the DC here - // Return a different brush if the default is not desired - return hbr; -} - -// Vista: Can not be used to workaround the problems with owner drawn tab control -BOOL CClosableTabCtrl::OnEraseBkgnd(CDC* pDC) -{ - return CTabCtrl::OnEraseBkgnd(pDC); -} - -BOOL CClosableTabCtrl::DeleteItem(int nItem) -{ - // if we remove a tab which would lead to scrolling back to other tabs, all those become hidden for... whatever reasons - // its easy enough wo work arround by scrolling to the first visible tab _before_ we delete the other one - SetCurSel(0); - return __super::DeleteItem(nItem); -} - -bool CClosableTabCtrl::IsVistaThemeActive() const -{ - return g_xpStyle.IsThemeActive() && g_xpStyle.IsAppThemed(); -} diff --git a/microsip/ClosableTabCtrl.h b/microsip/ClosableTabCtrl.h deleted file mode 100644 index 1eb6aacb..00000000 --- a/microsip/ClosableTabCtrl.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -class CClosableTabCtrl : public CTabCtrl -{ - DECLARE_DYNAMIC(CClosableTabCtrl) - -public: - CClosableTabCtrl(); - virtual ~CClosableTabCtrl(); - BOOL DeleteItem(int nItem); - - bool m_bCloseable; - -protected: - CImageList m_ImgLstCloseButton; - IMAGEINFO m_iiCloseButton; - CPoint m_ptCtxMenu; - int iTabClose; - - void InternalInit(); - void SetAllIcons(); - void GetCloseButtonRect(int iItem, const CRect& rcItem, CRect& rcCloseButton, bool bItemSelected, bool bVistaThemeActive); - int GetTabUnderContextMenu() const; - int GetTabUnderPoint(CPoint point) const; - bool SetDefaultContextMenuPos(); - bool IsVistaThemeActive() const; - - virtual void PreSubclassWindow(); - virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); - virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); - - DECLARE_MESSAGE_MAP() - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnLButtonUp(UINT nFlags, CPoint point); - afx_msg void OnLButtonDown(UINT nFlags, CPoint point); - afx_msg void OnMButtonUp(UINT nFlags, CPoint point); - afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - afx_msg void OnSysColorChange(); - afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); - afx_msg LRESULT _OnThemeChanged(); - afx_msg HBRUSH CtlColor(CDC* /*pDC*/, UINT /*nCtlColor*/); - afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); - afx_msg BOOL OnEraseBkgnd(CDC* pDC); - afx_msg void OnMeasureItem(int, LPMEASUREITEMSTRUCT); - afx_msg void MeasureItem(LPMEASUREITEMSTRUCT); -}; diff --git a/microsip/Contacts.cpp b/microsip/Contacts.cpp deleted file mode 100644 index 38cfd7cb..00000000 --- a/microsip/Contacts.cpp +++ /dev/null @@ -1,836 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "Contacts.h" -#include "microsip.h" -#include "settings.h" -#include -#include -#include "mainDlg.h" -#include "utf.h" -#include "langpack.h" -#include "CSVFile.h" - -Contacts::Contacts(CWnd* pParent /*=NULL*/) -: CBaseDialog(Contacts::IDD, pParent) -{ - Create (IDD, pParent); -} - -Contacts::~Contacts(void) -{ -} - -BOOL Contacts::OnInitDialog() -{ - CBaseDialog::OnInitDialog(); - - AutoMove(IDC_CONTACTS,0,0,100,100); - AutoMove(IDC_SEARCH_PICTURE,0,100,0,0); - AutoMove(IDC_FILER_VALUE,0,100,100,0); - - TranslateDialog(this->m_hWnd); - - addDlg = new AddDlg(this); - imageList = new CImageList(); - imageList->Create(16,16,ILC_COLOR32,3,3); - imageList->SetBkColor(RGB(255, 255, 255)); - imageList->Add(theApp.LoadIcon(IDI_UNKNOWN)); - imageList->Add(theApp.LoadIcon(IDI_OFFLINE)); - imageList->Add(theApp.LoadIcon(IDI_AWAY)); - imageList->Add(theApp.LoadIcon(IDI_ONLINE)); - imageList->Add(theApp.LoadIcon(IDI_ON_THE_PHONE)); - imageList->Add(theApp.LoadIcon(IDI_BLANK)); - imageList->Add(theApp.LoadIcon(IDI_BUSY)); - imageList->Add(theApp.LoadIcon(IDI_DEFAULT)); - - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - list->SetImageList(imageList,LVSIL_SMALL); - - CRect rect; - list->GetClientRect(rect); - - int defaultWidth = rect.Width() - GetSystemMetrics(SM_CXVSCROLL); - list->InsertColumn(0, Translate(_T("Name")), LVCFMT_LEFT, accountSettings.contactsWidth0 > 0 ? accountSettings.contactsWidth0 : defaultWidth/2); - list->InsertColumn(1, Translate(_T("Info")), LVCFMT_LEFT, accountSettings.contactsWidth1 > 0 ? accountSettings.contactsWidth1 : defaultWidth/2); - list->SetExtendedStyle( list->GetExtendedStyle() | LVS_EX_FULLROWSELECT ); - - ContactsLoad(); - - return TRUE; -} - -void Contacts::OnCreated() -{ - m_SortItemsExListCtrl.SetSortColumn(0,true); -} - -void Contacts::PostNcDestroy() -{ - CBaseDialog::PostNcDestroy(); - if (pj_ready) { - PresenceUnsubsribe(); - } - mainDlg->pageContacts=NULL; - delete imageList; - delete this; -} - -void Contacts::DoDataExchange(CDataExchange* pDX) -{ - CBaseDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_CONTACTS, m_SortItemsExListCtrl); -} - -BEGIN_MESSAGE_MAP(Contacts, CBaseDialog) - ON_NOTIFY(HDN_ENDTRACK, 0, OnEndtrack) - ON_BN_CLICKED(IDOK, OnBnClickedOk) - ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel) - ON_EN_CHANGE(IDC_FILER_VALUE, OnFilterValueChange) - ON_COMMAND(ID_CALL_PICKUP,OnMenuCallPickup) - ON_COMMAND(ID_CALL,OnMenuCall) - ON_COMMAND(ID_CHAT,OnMenuChat) - ON_COMMAND(ID_ADD,OnMenuAdd) - ON_COMMAND(ID_EDIT,OnMenuEdit) - ON_COMMAND(ID_COPY,OnMenuCopy) - ON_COMMAND(ID_DELETE,OnMenuDelete) - ON_COMMAND(ID_IMPORT_GOOGLE,OnMenuImportGoogle) - ON_MESSAGE(WM_CONTEXTMENU,OnContextMenu) - ON_NOTIFY(NM_DBLCLK, IDC_CONTACTS, &Contacts::OnNMDblclkContacts) -#ifdef _GLOBAL_VIDEO - ON_COMMAND(ID_VIDEOCALL,OnMenuCallVideo) -#endif -END_MESSAGE_MAP() - - -BOOL Contacts::PreTranslateMessage(MSG* pMsg) -{ - BOOL catched = FALSE; - if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) { - CEdit* edit = (CEdit*)GetDlgItem(IDC_FILER_VALUE); - if (edit == GetFocus()) { - catched = TRUE; - if (isFiltered()) { - filterReset(); - } - } - } - if (!catched) { - return CBaseDialog::PreTranslateMessage(pMsg); - } else { - return TRUE; - } -} - -void Contacts::OnEndtrack(NMHDR* pNMHDR, LRESULT* pResult) -{ - HD_NOTIFY *phdn = (HD_NOTIFY *)pNMHDR; - int width = phdn->pitem->cxy; - switch (phdn->iItem) { - case 0: - accountSettings.contactsWidth0 = width; - break; - } - mainDlg->AccountSettingsPendingSave(); - *pResult = 0; -} - -void Contacts::OnBnClickedOk() -{ - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - POSITION pos = list->GetFirstSelectedItemPosition(); - if (pos) { - DefaultItemAction(list->GetNextSelectedItem(pos)); - } -} - -void Contacts::DefaultItemAction(int i) -{ - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - Contact *pContact = (Contact *) list->GetItemData(i); - if (pContact->ringing) { - OnMenuCallPickup(); - } else { - MessageDlgOpen(accountSettings.singleMode); - } -} - -void Contacts::OnBnClickedCancel() -{ - mainDlg->ShowWindow(SW_HIDE); -} - -void Contacts::OnFilterValueChange() -{ - ContactsClear(); - ContactsLoad(); -} - -bool Contacts::isFiltered(Contact *pContact) { - CEdit* edit = (CEdit*)GetDlgItem(IDC_FILER_VALUE); - CString str; - edit->GetWindowText(str); - if (!str.IsEmpty()) { - if (!pContact ) { - return true; - } - str.MakeLower(); - CString name = pContact->name; - CString number = pContact->number; - name.MakeLower(); - number.MakeLower(); - if (name.Find(str) ==-1 && number.Find(str) ==-1) { - return true; - } - } - return false; -} - -void Contacts::filterReset() -{ - CEdit* edit = (CEdit*)GetDlgItem(IDC_FILER_VALUE); - edit->SetWindowText(_T("")); -} - -LRESULT Contacts::OnContextMenu(WPARAM wParam,LPARAM lParam) -{ - int x = GET_X_LPARAM(lParam); - int y = GET_Y_LPARAM(lParam); - POINT pt = { x, y }; - RECT rc; - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - POSITION pos = list->GetFirstSelectedItemPosition(); - int selectedItem = -1; - if (pos) { - selectedItem = list->GetNextSelectedItem(pos); - } - if (x!=-1 || y!=-1) { - ScreenToClient(&pt); - GetClientRect(&rc); - if (!PtInRect(&rc, pt)) { - x = y = -1; - } - } else { - if (selectedItem != -1) { - list->GetItemPosition(selectedItem,&pt); - list->ClientToScreen(&pt); - x = 40+pt.x; - y = 8+pt.y; - } else { - ::ClientToScreen((HWND)wParam, &pt); - x = 10+pt.x; - y = 10+pt.y; - } - } - if (x!=-1 || y!=-1) { - CMenu menu; - menu.LoadMenu(IDR_MENU_CONTACT); - CMenu* tracker = menu.GetSubMenu(0); - TranslateMenu(tracker->m_hMenu); - if ( selectedItem != -1 ) { - Contact *pContact = (Contact *) list->GetItemData(selectedItem); - if (pContact->ringing) { - tracker->InsertMenu(ID_CALL,0,ID_CALL_PICKUP,Translate(_T("Call Pickup"))); - } - tracker->EnableMenuItem(ID_CALL, FALSE); -#ifdef _GLOBAL_VIDEO - tracker->EnableMenuItem(ID_VIDEOCALL, FALSE); -#endif - tracker->EnableMenuItem(ID_CHAT, FALSE); - tracker->EnableMenuItem(ID_EDIT, FALSE); - tracker->EnableMenuItem(ID_COPY, FALSE); - tracker->EnableMenuItem(ID_DELETE, FALSE); - } else { - tracker->EnableMenuItem(ID_CALL, TRUE); -#ifdef _GLOBAL_VIDEO - tracker->EnableMenuItem(ID_VIDEOCALL, TRUE); -#endif - tracker->EnableMenuItem(ID_CHAT, TRUE); - tracker->EnableMenuItem(ID_EDIT, TRUE); - tracker->EnableMenuItem(ID_COPY, TRUE); - tracker->EnableMenuItem(ID_DELETE, TRUE); - } - tracker->AppendMenu(0, MF_SEPARATOR); - CMenu importMenu; - importMenu.CreatePopupMenu(); - importMenu.AppendMenu(MF_STRING, ID_IMPORT_GOOGLE, Translate(_T("Google CSV"))); - tracker->AppendMenu(MF_POPUP, (UINT_PTR)importMenu.m_hMenu, Translate(_T("Import"))); - - tracker->TrackPopupMenu( 0, x, y, this ); - return TRUE; - } - return DefWindowProc(WM_CONTEXTMENU,wParam,lParam); -} - -void Contacts::MessageDlgOpen(BOOL isCall, BOOL hasVideo) -{ - if (accountSettings.singleMode && call_get_count_noincoming() && isCall) { - mainDlg->GotoTab(0); - return; - } - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - POSITION pos = list->GetFirstSelectedItemPosition(); - if (pos) { - int i = list->GetNextSelectedItem(pos); - Contact *pContact = (Contact *) list->GetItemData(i); - if (isCall) { - mainDlg->MakeCall(pContact->number, hasVideo); - } else { - mainDlg->MessagesOpen(pContact->number); - } - } -} - -void Contacts::OnNMDblclkContacts(NMHDR *pNMHDR, LRESULT *pResult) -{ - LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR); - if (pNMItemActivate->iItem!=-1) { - DefaultItemAction(pNMItemActivate->iItem); - } - *pResult = 0; -} - -void Contacts::OnMenuCallPickup() -{ - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - POSITION pos = list->GetFirstSelectedItemPosition(); - if (pos) { - int i = list->GetNextSelectedItem(pos); - Contact *pContact = (Contact *) list->GetItemData(i); - mainDlg->messagesDlg->CallMake(_T(_GLOBAL_CALL_PICKUP)+pContact->number); - } -} - -void Contacts::OnMenuCall() -{ - MessageDlgOpen(TRUE); -} - -#ifdef _GLOBAL_VIDEO -void Contacts::OnMenuCallVideo() -{ - MessageDlgOpen(TRUE, TRUE); -} -#endif - -void Contacts::OnMenuChat() -{ - MessageDlgOpen(); -} - -void Contacts::OnMenuAdd() -{ - if (!addDlg->IsWindowVisible()) { - addDlg->ShowWindow(SW_SHOW); - } else { - addDlg->SetForegroundWindow(); - } - addDlg->listIndex = -1; - addDlg->GetDlgItem(IDC_EDIT_NUMBER)->SetWindowText(_T("")); - addDlg->GetDlgItem(IDC_EDIT_NAME)->SetWindowText(_T("")); - ((CButton *)addDlg->GetDlgItem(IDC_PRESENCE))->SetCheck(0); - addDlg->GetDlgItem(IDC_EDIT_NAME)->SetFocus(); -} - -void Contacts::OnMenuEdit() -{ - OnMenuAdd(); - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - POSITION pos = list->GetFirstSelectedItemPosition(); - int i = list->GetNextSelectedItem(pos); - addDlg->listIndex = i; - - Contact *pContact = (Contact *) list->GetItemData(i); - addDlg->GetDlgItem(IDC_EDIT_NUMBER)->SetWindowText(pContact->number); - addDlg->GetDlgItem(IDC_EDIT_NAME)->SetWindowText(pContact->name); - ((CButton *)addDlg->GetDlgItem(IDC_PRESENCE))->SetCheck(pContact->presence); -} - -void Contacts::OnMenuCopy() -{ - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - POSITION pos = list->GetFirstSelectedItemPosition(); - if (pos) { - int i = list->GetNextSelectedItem(pos); - Contact *pContact = (Contact *) list->GetItemData(i); - mainDlg->CopyStringToClipboard(pContact->number); - } -} - -void Contacts::OnMenuDelete() -{ - CList contacts; - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - POSITION pos = list->GetFirstSelectedItemPosition(); - while (pos) { - Contact *pContact = (Contact *) list->GetItemData(list->GetNextSelectedItem(pos)); - contacts.AddTail(pContact->number); - } - if (isFiltered()) { - filterReset(); - } - int count = list->GetItemCount(); - for (int i=0;iGetItemData(i); - if (contacts.Find(pContact->number)) { - ContactDelete(i); - count--; - i--; - } - } - ContactsSave(); -} - -void Contacts::OnMenuImportGoogle() -{ - CFileDialog dlgFile(TRUE, _T("cvs"), 0, OFN_HIDEREADONLY, _T("CSV Files (*.csv)|*.csv|"),this); - if (dlgFile.DoModal() == IDOK) { - bool changed = false; - if (isFiltered()) { - filterReset(); - } - CCSVFile CSVFile; - CSVFile.SetCodePage(CP_UTF8); - if (CSVFile.Open(dlgFile.GetPathName(), CCSVFile::modeRead | CFile::typeText | CFile::shareDenyWrite)) { - CStringArray arr; - int nameIndex = -1, numberIndex = -1; - while (CSVFile.ReadData(arr)) { - if (nameIndex == -1) { - for (int i = 0; i < arr.GetCount(); i++) { - CString s = arr.GetAt(i); - if (nameIndex == -1 && arr.GetAt(i).CompareNoCase(_T("Name")) == 0) { - nameIndex = i; - } - if (numberIndex == -1 && arr.GetAt(i).CompareNoCase(_T("Phone 1 - Value")) == 0) { - numberIndex = i; - } - } - if (nameIndex == -1 || numberIndex == -1) { - AfxMessageBox(_T("Unknown format")); - break; - } - } - else if (arr.GetCount() > numberIndex && arr.GetCount() > nameIndex) { - CString number = arr.GetAt(numberIndex); - CString name = arr.GetAt(nameIndex); - if (!number.IsEmpty() && ContactAdd(number, name, 0, 0, FALSE, TRUE) && !changed) { - changed = true; - } - } - } - CSVFile.Close(); - } - if (changed) { - ContactsSave(); - } - } -} - -void Contacts::ContactDelete(int i) -{ - int deleted = 0; - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - Contact *pContact = (Contact *) list->GetItemData(i); - PresenceUnsubsribeOne(pContact); - list->DeleteItem(i); - delete pContact; -} - -bool Contacts::ContactAdd(CString number, CString name, char presence, char directory, BOOL save, BOOL fromDirectory) -{ - if (save) { - if (isFiltered()) { - filterReset(); - } - } - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - if (fromDirectory || save) { - int count = list->GetItemCount(); - for (int i=0;iGetItemData(i); - CString contactData; - if (pContact->number == number) { - pContact->candidate = FALSE; - bool changed = false; - if (!name.IsEmpty() && name!=pContact->name) { - list->SetItemText(i,0,name); - pContact->name=name; - changed = true; - } - if (presence!=-1 && presence!=pContact->presence) { - pContact->presence=presence; - if (presence>0) { - PresenceSubsribeOne(pContact); - } - changed = true; - } - if (!fromDirectory && directory!=-1 && directory!=pContact->directory) { - pContact->directory=directory; - changed = true; - } - if (save && changed) { - ContactsSave(); - } - return changed; - } - } - } - if (name.IsEmpty()) { - name = number; - } - - Contact *pContact; - bool found = false; - if (pj_ready && isSubscribed) { - pjsua_buddy_id ids[PJSUA_MAX_BUDDIES]; - unsigned count = PJSUA_MAX_BUDDIES; - pjsua_enum_buddies(ids,&count); - for (unsigned i=0;inumber == number) { - found = true; - break; - } - } - } - if (!found) { - pContact = new Contact(); - pContact->image = 7; - } - pContact->number = number; - pContact->name = name; - pContact->presence = presence>0; - pContact->directory = directory>0; - int i = list->InsertItem(LVIF_TEXT|LVIF_PARAM|LVIF_IMAGE,0,name,0,0,pContact->image,(LPARAM)pContact); - //list->SetItemText(i,1,number); - - if (save) { - ContactsSave(); - } - if (save || fromDirectory) { - PresenceSubsribeOne(pContact); - } - return true; -} - -void Contacts::ContactsSave() -{ - if (isFiltered()) { - filterReset(); - } - CXMLFile xmlFile; - CXMLElement* xmlRoot = new CXMLElement(); - xmlRoot->Create(_T("XML:ROOT"), XET_TAG); - CXMLElement* xmlContacts = new CXMLElement(); - xmlContacts->Create(_T("contacts"), XET_TAG); - xmlRoot->AppendChild(xmlContacts); - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - int count = list->GetItemCount(); - CXMLElement* xmlContact; - CXMLElement* xmlAttr; - for (int i=0;iGetItemData(i); - xmlContact = new CXMLElement(); - xmlContact->Create(_T("contact"), XET_TAG); - xmlAttr = new CXMLElement(); - xmlAttr->Create(_T("number"), XET_ATTRIBUTE); - xmlAttr->SetValue(AnsiToUnicode(Utf8EncodeUcs2(XMLEntityEncode(pContact->number))).GetBuffer()); - xmlContact->AppendChild(xmlAttr); - xmlAttr = new CXMLElement(); - xmlAttr->Create(_T("name"), XET_ATTRIBUTE); - xmlAttr->SetValue(AnsiToUnicode(Utf8EncodeUcs2(XMLEntityEncode(pContact->name))).GetBuffer()); - xmlContact->AppendChild(xmlAttr); - xmlAttr = new CXMLElement(); - xmlAttr->Create(_T("presence"), XET_ATTRIBUTE); - xmlAttr->SetValue(pContact->presence?_T("1"):_T("0")); - xmlContact->AppendChild(xmlAttr); - xmlAttr = new CXMLElement(); - xmlAttr->Create(_T("directory"), XET_ATTRIBUTE); - xmlAttr->SetValue(pContact->directory?_T("1"):_T("0")); - xmlContact->AppendChild(xmlAttr); - xmlContacts->AppendChild(xmlContact); - } - xmlFile.SetRoot(xmlRoot); - CString filename = accountSettings.pathRoaming; - filename.Append(_T("Contacts.xml")); - xmlFile.SaveToFile(filename.GetBuffer()); -} - -void Contacts::ContactsClear() -{ - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - list->DeleteAllItems(); -} - -void Contacts::ContactsLoad() -{ - CXMLFile xmlFile; - CString filename = accountSettings.pathRoaming; - filename.Append(_T("Contacts.xml")); - if (xmlFile.LoadFromFile(filename.GetBuffer())) { - CXMLElement *xmlRoot = xmlFile.GetRoot(); - CXMLElement *xmlContacts = xmlRoot->GetFirstChild(); - while (xmlContacts) { - if (xmlContacts->GetElementType() == XET_TAG) { - CXMLElement *xmlContact = xmlContacts->GetFirstChild(); - while (xmlContact) { - if (xmlContact->GetElementType() == XET_TAG) { - CXMLElement *xmlAttr = xmlContact->GetFirstChild(); - CString number; - CString name; - BOOL presence = FALSE; - BOOL directory = FALSE; - CString rab; - while (xmlAttr) { - if (xmlAttr->GetElementType() == XET_ATTRIBUTE) { - CString attrName = xmlAttr->GetElementName(); - if (attrName == _T("number")) { - number = XMLEntityDecode(Utf8DecodeUni(UnicodeToAnsi(xmlAttr->GetValue()))); - } else if (attrName == _T("name")) { - name = XMLEntityDecode(Utf8DecodeUni(UnicodeToAnsi(xmlAttr->GetValue()))); - } else if (attrName == _T("presence")) { - rab = xmlAttr->GetValue(); - presence = rab==_T("1"); - } else if (attrName == _T("directory")) { - rab = xmlAttr->GetValue(); - directory = rab==_T("1"); - } - } - xmlAttr = xmlContact->GetNextChild(); - } - if (!number.IsEmpty()) { - Contact contact; - contact.name = name; - contact.number = number; - if (!isFiltered(&contact)) { - ContactAdd(number, name, presence, directory, FALSE); - } - } - } - xmlContact = xmlContacts->GetNextChild(); - } - } - xmlContacts = xmlRoot->GetNextChild(); - } - } else { - CString key; - CString val; - LPTSTR ptr = val.GetBuffer(255); - int i=0; - while (TRUE) { - key.Format(_T("%d"),i); - if (GetPrivateProfileString(_T("Contacts"), key, NULL, ptr, 256, accountSettings.iniFile)) { - CString number; - CString name; - BOOL presence; - BOOL directory; - ContactDecode(ptr, number, name, presence, directory); - ContactAdd(number, name, presence, directory, FALSE); - } else { - break; - } - i++; - } - WritePrivateProfileSection(_T("Contacts"), NULL, accountSettings.iniFile); - ContactsSave(); - } - m_SortItemsExListCtrl.SortColumn(m_SortItemsExListCtrl.GetSortColumn(),m_SortItemsExListCtrl.IsAscending()); -} - -void Contacts::ContactDecode(CString str, CString &number, CString &name, BOOL &presence, BOOL &fromDirectory) -{ - CString rab; - int begin; - int end; - begin = 0; - end = str.Find(';', begin); - if (end != -1) - { - number=str.Mid(begin, end-begin); - begin = end + 1; - end = str.Find(';', begin); - if (end != -1) - { - name=str.Mid(begin, end-begin); - begin = end + 1; - end = str.Find(';', begin); - if (end != -1) - { - rab=str.Mid(begin, end-begin); - presence = rab == _T("1"); - begin = end + 1; - end = str.Find(';', begin); - if (end != -1) - { - rab=str.Mid(begin, end-begin); - fromDirectory = rab == _T("1"); - } else - { - rab=str.Mid(begin); - fromDirectory = rab == _T("1"); - } - } else - { - rab=str.Mid(begin); - presence = rab == _T("1"); - fromDirectory = FALSE; - } - } else - { - name = str.Mid(begin); - presence = FALSE; - fromDirectory = FALSE; - } - } else - { - number=str; - name = number; - presence = FALSE; - fromDirectory = FALSE; - } -} - -CString Contacts::GetNameByNumber(CString number) -{ - if (isFiltered()) { - filterReset(); - } - - CString name; - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - - CString sipURI = GetSIPURI(number); - int n = list->GetItemCount(); - for (int i=0; iGetItemData(i); - if (GetSIPURI(pContact->number) == sipURI) - { - name = pContact->name; - break; - } - } - return name; -} - -void Contacts::PresenceSubsribeOne(Contact *pContact) -{ - if (isSubscribed && pContact->presence) { - pjsua_buddy_id p_buddy_id; - pjsua_buddy_config buddy_cfg; - pjsua_buddy_config_default(&buddy_cfg); - buddy_cfg.subscribe=PJ_TRUE; - buddy_cfg.uri = StrToPjStr(GetSIPURI(pContact->number)); - buddy_cfg.user_data = (void *)pContact; - pj_status_t status = pjsua_buddy_add(&buddy_cfg, &p_buddy_id); - if (status != PJ_SUCCESS) { - AfxMessageBox(_T("Presence Subscription error: ")+GetErrorMessage(status)); - } - } -} - -void Contacts::PresenceUnsubsribeOne(Contact *pContact) -{ - if (isSubscribed) - { - pjsua_buddy_id ids[PJSUA_MAX_BUDDIES]; - unsigned count = PJSUA_MAX_BUDDIES; - pjsua_enum_buddies(ids,&count); - for (unsigned i=0;iGetItemCount(); - for (int i=0; iGetItemData(i); - PresenceSubsribeOne(pContact); - } - } -} - -void Contacts::PresenceUnsubsribe() -{ - pjsua_buddy_id ids[PJSUA_MAX_BUDDIES]; - unsigned count = PJSUA_MAX_BUDDIES; - pjsua_enum_buddies(ids,&count); - for (unsigned i=0;im_hWnd)) { - CListCtrl *list= (CListCtrl *)GetDlgItem(IDC_CONTACTS); - int n = list->GetItemCount(); - for (int i=0; iSetItem(i, 0, LVIF_IMAGE, 0, 7, 0, 0, 0); - } - } - isSubscribed=FALSE; -} - -void Contacts::SetCanditates() -{ - if (isFiltered()) { - filterReset(); - } - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - int count = list->GetItemCount(); - for (int i=0;iGetItemData(i); - if (pContact->directory) { - pContact->candidate = TRUE; - } - } -} -int Contacts::DeleteCanditates() -{ - if (isFiltered()) { - filterReset(); - } - CListCtrl *list= (CListCtrl*)GetDlgItem(IDC_CONTACTS); - int count = list->GetItemCount(); - int deleted = 0; - for (int i=0;iGetItemData(i); - if (pContact->candidate) { - ContactDelete(i); - count--; - i--; - deleted++; - } - } - return deleted; -} - - diff --git a/microsip/Contacts.h b/microsip/Contacts.h deleted file mode 100644 index a33b6885..00000000 --- a/microsip/Contacts.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#pragma once - -#include "resource.h" -#include "global.h" -#include "AddDlg.h" -#include "BaseDialog.h" -#include "CListCtrl_SortItemsEx.h" - -class Contacts : - public CBaseDialog -{ -public: - Contacts(CWnd* pParent = NULL); // standard constructor - ~Contacts(); - enum { IDD = IDD_CONTACTS }; - - CListCtrl_SortItemsEx m_SortItemsExListCtrl; - - AddDlg* addDlg; - BOOL isSubscribed; - - bool ContactAdd(CString number, CString name, char presence, char directory, BOOL save = FALSE, BOOL fromDirectory = FALSE); - - void ContactDelete(int i); - void ContactsSave(); - void ContactsLoad(); - void ContactsClear(); - bool isFiltered(Contact *pContact = NULL); - void filterReset(); - - void SetCanditates(); - int DeleteCanditates(); - - void UpdateCallButton(); - CString GetNameByNumber(CString number); - void PresenceSubsribeOne(Contact *pContact); - void PresenceUnsubsribeOne(Contact *pContact); - void PresenceSubsribe(); - void PresenceUnsubsribe(); - - void OnCreated(); - -private: - CImageList* imageList; - void ContactDecode(CString str, CString &number, CString &name, BOOL &presence, BOOL &fromDirectory); - void MessageDlgOpen(BOOL isCall = FALSE, BOOL hasVideo = FALSE); - void DefaultItemAction(int i); - -protected: - virtual BOOL OnInitDialog(); - virtual void PostNcDestroy(); - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - DECLARE_MESSAGE_MAP() -public: - afx_msg void OnBnClickedOk(); - afx_msg void OnBnClickedCancel(); - afx_msg void OnFilterValueChange(); - afx_msg void OnMenuCallPickup(); - afx_msg void OnMenuCall(); - afx_msg void OnMenuChat(); - afx_msg void OnMenuAdd(); - afx_msg void OnMenuEdit(); - afx_msg void OnMenuCopy(); - afx_msg void OnMenuDelete(); - afx_msg void OnMenuImportGoogle(); - afx_msg LRESULT OnContextMenu(WPARAM wParam,LPARAM lParam); - afx_msg void OnNMDblclkContacts(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnEndtrack(NMHDR* pNMHDR, LRESULT* pResult); -#ifdef _GLOBAL_VIDEO - afx_msg void OnMenuCallVideo(); -#endif - virtual BOOL PreTranslateMessage(MSG* pMsg); -}; - diff --git a/microsip/Crypto.cpp b/microsip/Crypto.cpp deleted file mode 100644 index f333d5dc..00000000 --- a/microsip/Crypto.cpp +++ /dev/null @@ -1,261 +0,0 @@ -#include "stdafx.h" -#include "Crypto.h" - -// Tell the linker to link the to the Cryptography API. -#pragma comment(lib, "Advapi32.lib") - -using namespace MFC; - -// Constructor, intialises Crypto API. -CCrypto::CCrypto() : m_hCryptProv(NULL), m_hKey(NULL), m_hHash(NULL) -{ - // Create the Crypt context. - if(!::CryptAcquireContext(&m_hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) { - if (::GetLastError() == NTE_BAD_KEYSET) - { - if (!::CryptAcquireContext(&m_hCryptProv, - NULL, - NULL, - PROV_RSA_FULL, - CRYPT_NEWKEYSET)) - { - return; - } - } else { - return; - } - } - - // Create an empty hash object. - if(!::CryptCreateHash(m_hCryptProv, CALG_MD5, 0, 0, &m_hHash)) - return; - - // Memory files are opened automatically on construction, we don't - // explcitly call open. -} - -// Destructor, frees Crypto stuff. -CCrypto::~CCrypto() -{ - // Close the file. - m_file.Close(); - - // Clean up. - if(m_hHash) - ::CryptDestroyHash(m_hHash); - - if(m_hKey) - ::CryptDestroyKey(m_hKey); - - if(m_hCryptProv) - ::CryptReleaseContext(m_hCryptProv, 0); -} - -// Derive a key from a password. -bool CCrypto::DeriveKey(CString strPassword) -{ - // Return failure if we don't have a context or hash. - if(m_hCryptProv == NULL || m_hHash == NULL) - return false; - - // If we already have a hash, trash it. - if(m_hHash) - { - CryptDestroyHash(m_hHash); - m_hHash = NULL; - if(!CryptCreateHash(m_hCryptProv, CALG_MD5, 0, 0, &m_hHash)) - return false; - } - - // If we already have a key, destroy it. - if(m_hKey) - { - ::CryptDestroyKey(m_hKey); - m_hKey = NULL; - } - - // Hash the password. This will have a different result in UNICODE mode, as it - // will hash the UNICODE string (this is by design, allowing for UNICODE passwords, but - // it's important to be aware of this behaviour. - if(!CryptHashData(m_hHash, (const BYTE*)strPassword.GetString(), strPassword.GetLength() * sizeof(TCHAR), 0)) - return false; - - // Create a session key based on the hash of the password. - if(!CryptDeriveKey(m_hCryptProv, CALG_RC2, m_hHash, CRYPT_EXPORTABLE, &m_hKey)) - return false; - - // And we're done. - return true; -} - -bool CCrypto::Encrypt(const CObject& serializable, CByteArray& arData) -{ - // Return failure if we don't have a context or key. - if(m_hCryptProv == NULL || m_hKey == NULL) - return false; - - // Return failure if the object is not serializable. - if(serializable.IsSerializable() == FALSE) - return false; - - // Before we write to the file, trash it. - m_file.SetLength(0); - - // Create a storing archive from the memory file. - CArchive ar(&m_file, CArchive::store); - - // We know that serialzing an object will not change it's data, as we can - // safely use a const cast here. - - // Write the data to the memory file. - const_cast(serializable).Serialize(ar); - - // Close the archive, flushing the write. - ar.Close(); - - // Encrypt the contents of the memory file and store the result in the array. - return InternalEncrypt(arData); -} - -bool CCrypto::Decrypt(const CByteArray& arData, CObject& serializable) -{ - // Return failure if we don't have a context or key. - if(m_hCryptProv == NULL || m_hKey == NULL) - return false; - - // Return failure if the object is not serializable. - if(serializable.IsSerializable() == FALSE) - return false; - - // Decrypt the contents of the array to the memory file. - if(InternalDecrypt(arData) == false) - return false; - - // Create a reading archive from the memory file. - CArchive ar(&m_file, CArchive::load); - - // Read the data from the memory file. - serializable.Serialize(ar); - - // Close the archive. - ar.Close(); - - // And we're done. - return true; -} - -bool CCrypto::Encrypt(const CString& str, CByteArray& arData) -{ - // Return failure if we don't have a context or key. - if(m_hCryptProv == NULL || m_hKey == NULL) - return false; - - // Before we write to the file, trash it. - m_file.SetLength(0); - - // Create a storing archive from the memory file. - CArchive ar(&m_file, CArchive::store); - - // Write the string to the memory file. - ar << str; - - // Close the archive, flushing the write. - ar.Close(); - - // Encrypt the contents of the memory file and store the result in the array. - return InternalEncrypt(arData); -} - -bool CCrypto::Decrypt(const CByteArray& arData, CString& str) -{ - // Return failure if we don't have a context or key. - if(m_hCryptProv == NULL || m_hKey == NULL) - return false; - - // Decrypt the contents of the array to the memory file. - if(InternalDecrypt(arData) == false) - return false; - - // Create a reading archive from the memory file. - CArchive ar(&m_file, CArchive::load); - - // Read the data from the memory file. - ar >> str; - - // Close the archive. - ar.Close(); - - // And we're done. - return true; -} - -bool CCrypto::InternalEncrypt(CByteArray& arDestination) -{ - // Get the length of the data in memory. Increase the capacity to handle the size of the encrypted data. - ULONGLONG uLength = m_file.GetLength(); - ULONGLONG uCapacity = uLength * 2; - m_file.SetLength(uCapacity); - - // Acquire direct access to the memory. - BYTE* pData = m_file.Detach(); - - // We need a DWORD to tell encrypt how much data we're encrypting. - DWORD dwDataLength = static_cast(uLength); - - // Now encrypt the memory file. - if(!::CryptEncrypt(m_hKey, NULL, TRUE, 0, pData, &dwDataLength, static_cast(uCapacity))) - { - // Free the memory we release from the memory file. - delete [] pData; - - return false; - } - - // Assign all of the data we have encrypted to the byte array- make sure anything - // already in the array is trashed first. - arDestination.RemoveAll(); - arDestination.SetSize(static_cast(dwDataLength)); - memcpy(arDestination.GetData(), pData, dwDataLength); - - // Free the memory we release from the memory file. - delete [] pData; - - return true; -} - -bool CCrypto::InternalDecrypt(const CByteArray& arSource) -{ - // Trash the file. - m_file.SetLength(0); - - // Write the contents of the byte array to the memory file. - m_file.Write(arSource.GetData(), static_cast(arSource.GetCount())); - m_file.Flush(); - - // Acquire direct access to the memory file buffer. - BYTE* pData = m_file.Detach(); - - // We need a DWORD to tell decrpyt how much data we're encrypting. - DWORD dwDataLength = static_cast(arSource.GetCount()); - DWORD dwOldDataLength = dwDataLength; - - // Now decrypt the data. - if(!::CryptDecrypt(m_hKey, NULL, TRUE, 0, pData, &dwDataLength)) - { - // Free the memory we release from the memory file. - delete [] pData; - - return false; - } - - // Set the length of the data file, write the decrypted data to it. - m_file.SetLength(dwDataLength); - m_file.Write(pData, dwDataLength); - m_file.Flush(); - m_file.SeekToBegin(); - - // Free the memory we release from the memory file. - delete [] pData; - - return true; -} \ No newline at end of file diff --git a/microsip/Crypto.h b/microsip/Crypto.h deleted file mode 100644 index 6adbecc8..00000000 --- a/microsip/Crypto.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -// Include the standard cryptography header. -#include - - -namespace MFC -{ - // A simple class to wrap the Crypto API. - class CCrypto - { - public: - - // All of the Cryptography API initialisation is done in the - // constructor, so constructing this object is expensive. I recommend having - // only one instance only, and keep it in your application class. - CCrypto(); - virtual ~CCrypto(); - - // These functions are essential to using the crypto object- you must - // have a key from some source or other. - - // Derive a key from a password. - virtual bool DeriveKey(CString strPassword); - - // These functions handle encryption and decryption. - - virtual bool Encrypt(const CObject& serializable, CByteArray& arData); - virtual bool Decrypt(const CByteArray& arData, CObject& serializable); - - virtual bool Encrypt(const CString& str, CByteArray& arData); - virtual bool Decrypt(const CByteArray& arData, CString& str); - - - protected: - - // Encrypt the contents of the memory file and store in the passed array. - virtual bool InternalEncrypt(CByteArray& arDestination); - - // Decrypt the contents of the passed array and store in the memory file. - virtual bool InternalDecrypt(const CByteArray& arSource); - - // Handle to the cryptography provider. - HCRYPTPROV m_hCryptProv; - - // Handle to the cryptography key. - HCRYPTKEY m_hKey; - - // Handle to the hash object. - HCRYPTHASH m_hHash; - - // Internally, the encryption and decryption of data is done with - // a CMemFile intermediate. - CMemFile m_file; - }; -} \ No newline at end of file diff --git a/microsip/Dialer.cpp b/microsip/Dialer.cpp deleted file mode 100644 index c7c153f3..00000000 --- a/microsip/Dialer.cpp +++ /dev/null @@ -1,1175 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "Dialer.h" -#include "global.h" -#include "settings.h" -#include "mainDlg.h" -#include "microsip.h" -#include "Strsafe.h" -#include "langpack.h" - -Dialer::Dialer(CWnd* pParent /*=NULL*/) - : CBaseDialog(Dialer::IDD, pParent) -{ - Create(IDD, pParent); -} - -Dialer::~Dialer(void) -{ -} - -void Dialer::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_DIALER_VOICEMAIL, m_ButtonVoicemail); - DDX_Control(pDX, IDC_VOLUME_INPUT, m_SliderCtrlInput); - DDX_Control(pDX, IDC_VOLUME_OUTPUT, m_SliderCtrlOutput); - DDX_Control(pDX, IDC_KEY_1, m_ButtonDialer1); - DDX_Control(pDX, IDC_KEY_2, m_ButtonDialer2); - DDX_Control(pDX, IDC_KEY_3, m_ButtonDialer3); - DDX_Control(pDX, IDC_KEY_4, m_ButtonDialer4); - DDX_Control(pDX, IDC_KEY_5, m_ButtonDialer5); - DDX_Control(pDX, IDC_KEY_6, m_ButtonDialer6); - DDX_Control(pDX, IDC_KEY_7, m_ButtonDialer7); - DDX_Control(pDX, IDC_KEY_8, m_ButtonDialer8); - DDX_Control(pDX, IDC_KEY_9, m_ButtonDialer9); - DDX_Control(pDX, IDC_KEY_0, m_ButtonDialer0); - DDX_Control(pDX, IDC_KEY_STAR, m_ButtonDialerStar); - DDX_Control(pDX, IDC_KEY_GRATE, m_ButtonDialerGrate); - DDX_Control(pDX, IDC_REDIAL, m_ButtonDialerRedial); - DDX_Control(pDX, IDC_DELETE, m_ButtonDialerDelete); - DDX_Control(pDX, IDC_KEY_PLUS, m_ButtonDialerPlus); - DDX_Control(pDX, IDC_CLEAR, m_ButtonDialerClear); -} - -void Dialer::RebuildShortcuts(bool init) -{ - if (!mainDlg->shortcutsEnabled) { - return; - } - CRect rect; - if (!init) { - mainDlg->GetWindowRect(rect); - mainDlg->SetWindowPos(NULL, 0, 0, mainDlg->windowSize.x, mainDlg->windowSize.y, SWP_NOZORDER | SWP_NOMOVE); - //-- - POSITION pos = shortcutButtons.GetHeadPosition(); - while (pos) { - POSITION posKey = pos; - CButton* button = shortcutButtons.GetNext(pos); - AutoUnmove(button->m_hWnd); - button->DestroyWindow(); - delete button; - shortcutButtons.RemoveAt(posKey); - }; - //-- - } - if (shortcuts.GetCount()) { - CFont* font = this->GetFont(); - CRect shortcutsRect; - GetWindowRect(shortcutsRect); - ScreenToClient(shortcutsRect); - - CRect rectVoicemail; - m_ButtonVoicemail.GetWindowRect(&rectVoicemail); - ScreenToClient(rectVoicemail); - CRect mapRect; - int buttonHeight; - int moveFactor; - int moveFix; - if (mainDlg->shortcutsBottom) { - mapRect.top = 8; - mapRect.left = 4; - MapDialogRect(&mapRect); - shortcutsRect.top = rectVoicemail.bottom + mapRect.top; - buttonHeight = 25; - moveFactor = 0; - } - else { - mapRect.top = 2; - mapRect.bottom = 1; - MapDialogRect(&mapRect); - shortcutsRect.top += mapRect.top; - shortcutsRect.bottom -= mapRect.bottom; - buttonHeight = shortcutsRect.Height() / shortcuts.GetCount(); - shortcutsRect.top = shortcutsRect.top + (shortcutsRect.Height() - buttonHeight * shortcuts.GetCount())/2; - moveFactor = 100 / shortcuts.GetCount(); - } - for (int i = 0; i < shortcuts.GetCount(); i++) { - Shortcut shortcut = shortcuts.GetAt(i); - CButton *button = new CButton(); - if (mainDlg->shortcutsBottom) { - CRect buttonRect; - buttonRect = CRect(shortcutsRect.left + mapRect.left, shortcutsRect.top, shortcutsRect.right - mapRect.left, shortcutsRect.top + buttonHeight); - button->Create(shortcut.label, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP, buttonRect, this, IDC_SHORTCUT_RANGE + i); - AutoMove(button->m_hWnd, 0, 100, 100, 0); - shortcutsRect.top += buttonHeight; - } - else { - button->Create(shortcut.label, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP, CRect(shortcutsRect.right - 138, shortcutsRect.top, shortcutsRect.right - 4, shortcutsRect.top + buttonHeight), this, IDC_SHORTCUT_RANGE + i); - AutoMove(button->m_hWnd, 100, i * moveFactor, 0, moveFactor); - shortcutsRect.top += buttonHeight; - } - button->SetFont(font); - shortcutButtons.AddTail(button); - } - } - if (!init) { - mainDlg->SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(), SWP_NOZORDER | SWP_NOMOVE); - } -} - -BOOL Dialer::OnInitDialog() -{ - CBaseDialog::OnInitDialog(); - - m_hCursorHand = ::LoadCursor(NULL, IDC_HAND); - CFont* font = this->GetFont(); - - RebuildShortcuts(true); - - TranslateDialog(this->m_hWnd); - - RebuildButtons(true); - - UpdateVoicemailButton(false); - - AutoMove(IDC_NUMBER, 0, 0, 100, 0); - - int height = 17; - int height4 = height * 4; - int height2 = height * 2; - int height3 = height * 3; - AutoMove(IDC_KEY_1, 0, 0, 33, height); - AutoMove(IDC_KEY_4, 0, height, 33, height); - AutoMove(IDC_KEY_7, 0, height2, 33, height); - AutoMove(IDC_KEY_STAR, 0, height3, 33, height); - AutoMove(IDC_REDIAL, 0, height4, 33, height); - AutoMove(IDC_DELETE, 0, height4, 33, 17); - - AutoMove(IDC_KEY_2, 33, 0, 34, height); - AutoMove(IDC_KEY_5, 33, height, 34, height); - AutoMove(IDC_KEY_8, 33, height2, 34, height); - AutoMove(IDC_KEY_0, 33, height3, 34, height); - AutoMove(IDC_KEY_PLUS, 33, height4, 34, height); - - AutoMove(IDC_KEY_3, 67, 0, 33, height); - AutoMove(IDC_KEY_6, 67, height, 33, height); - AutoMove(IDC_KEY_9, 67, height2, 33, height); - AutoMove(IDC_KEY_GRATE, 67, height3, 33, height); - AutoMove(IDC_CLEAR, 67, height4, 33, height); - -#ifdef _GLOBAL_VIDEO - AutoMove(IDC_VIDEO_CALL, 0, 85, 14, 15); - AutoMove(IDC_CALL, 14, 85, 72, 15); - AutoMove(IDC_MESSAGE, 86, 85, 14, 15); -#else - AutoMove(IDC_CALL, 0, 85, 84, 15); - AutoMove(IDC_MESSAGE, 84, 85, 16, 15); -#endif - - AutoMove(IDC_HOLD, 0, 85, 14, 15); - AutoMove(IDC_END, 14, 85, 72, 15); - AutoMove(IDC_TRANSFER, 86, 85, 14, 15); - - AutoMove(IDC_BUTTON_MUTE_OUTPUT, 0, 100, 0, 0); - AutoMove(IDC_BUTTON_MUTE_INPUT, 0, 100, 0, 0); - AutoMove(IDC_VOLUME_INPUT, 0, 100, 100, 0); - AutoMove(IDC_VOLUME_OUTPUT, 0, 100, 100, 0); - - AutoMove(IDC_DIALER_VOICEMAIL, 100, 100, 0, 0); - - - DialedLoad(); - - CDC *pDC = GetDC(); - int dpiY = GetDeviceCaps(pDC->m_hDC, LOGPIXELSY); - LOGFONT lf; - font->GetLogFont(&lf); - //-- - m_font_call.CreateFontIndirect(&lf); - //-- - lf.lfHeight = MulDiv(22, dpiY, 96); - m_font.CreateFontIndirect(&lf); - //-- - m_font_number.CreateFontIndirect(&lf); - //-- - ReleaseDC(pDC); - //-- - CComboBox *combobox = (CComboBox*)GetDlgItem(IDC_NUMBER); - combobox->SetWindowPos(NULL, 0, 0, combobox->GetDroppedWidth(), 400, SWP_NOZORDER | SWP_NOMOVE); - combobox->SetFont(&m_font_number); - - - GetDlgItem(IDC_KEY_1)->SetFont(&m_font); - GetDlgItem(IDC_KEY_2)->SetFont(&m_font); - GetDlgItem(IDC_KEY_3)->SetFont(&m_font); - GetDlgItem(IDC_KEY_4)->SetFont(&m_font); - GetDlgItem(IDC_KEY_5)->SetFont(&m_font); - GetDlgItem(IDC_KEY_6)->SetFont(&m_font); - GetDlgItem(IDC_KEY_7)->SetFont(&m_font); - GetDlgItem(IDC_KEY_8)->SetFont(&m_font); - GetDlgItem(IDC_KEY_9)->SetFont(&m_font); - GetDlgItem(IDC_KEY_0)->SetFont(&m_font); - GetDlgItem(IDC_KEY_STAR)->SetFont(&m_font); - GetDlgItem(IDC_KEY_GRATE)->SetFont(&m_font); - GetDlgItem(IDC_KEY_PLUS)->SetFont(&m_font); - GetDlgItem(IDC_CLEAR)->SetFont(&m_font); - GetDlgItem(IDC_REDIAL)->SetFont(&m_font); - GetDlgItem(IDC_DELETE)->SetFont(&m_font); - - GetDlgItem(IDC_CALL)->SetFont(&m_font_call); - GetDlgItem(IDC_END)->SetFont(&m_font_call); - - if (m_ToolTip.Create(this)) { - m_ToolTip.AddTool(&m_ButtonDialerRedial, Translate(_T("Redial"))); - m_ToolTip.AddTool(&m_ButtonDialerDelete, Translate(_T("Backspace"))); - m_ToolTip.AddTool(&m_ButtonDialerClear, Translate(_T("Clear"))); - m_ToolTip.AddTool(&m_ButtonVoicemail, Translate(_T("Voicemail Number"))); - m_ToolTip.Activate(TRUE); - } - - muteOutput = FALSE; - muteInput = FALSE; - - m_SliderCtrlOutput.SetRange(0, 100); - m_SliderCtrlOutput.SetPos(accountSettings.volumeOutput); - - m_SliderCtrlInput.SetRange(0, 100); - m_SliderCtrlInput.SetPos(accountSettings.volumeInput); - - m_hIconMuteOutput = LoadImageIcon(IDI_MUTE_OUTPUT); - ((CButton*)GetDlgItem(IDC_BUTTON_MUTE_OUTPUT))->SetIcon(m_hIconMuteOutput); - m_hIconMutedOutput = LoadImageIcon(IDI_MUTED_OUTPUT); - - m_hIconMuteInput = LoadImageIcon(IDI_MUTE_INPUT); - ((CButton*)GetDlgItem(IDC_BUTTON_MUTE_INPUT))->SetIcon(m_hIconMuteInput); - m_hIconMutedInput = LoadImageIcon(IDI_MUTED_INPUT); - - m_hIconHold = LoadImageIcon(IDI_HOLD); - ((CButton*)GetDlgItem(IDC_HOLD))->SetIcon(m_hIconHold); - m_hIconTransfer = LoadImageIcon(IDI_TRANSFER); - ((CButton*)GetDlgItem(IDC_TRANSFER))->SetIcon(m_hIconTransfer); -#ifdef _GLOBAL_VIDEO - m_hIconVideo = LoadImageIcon(IDI_VIDEO); - ((CButton*)GetDlgItem(IDC_VIDEO_CALL))->SetIcon(m_hIconVideo); -#endif - m_hIconMessage = LoadImageIcon(IDI_MESSAGE); - ((CButton*)GetDlgItem(IDC_MESSAGE))->SetIcon(m_hIconMessage); - - return TRUE; -} - -int Dialer::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (mainDlg->widthAdd || mainDlg->heightAdd) { - SetWindowPos(NULL, 0, 0, lpCreateStruct->cx + mainDlg->widthAdd, lpCreateStruct->cy + mainDlg->heightAdd, SWP_NOMOVE | SWP_NOZORDER); - } - return CBaseDialog::OnCreate(lpCreateStruct); -} - -void Dialer::OnDestroy() -{ - KillTimer(IDT_TIMER_VU_METER); - CBaseDialog::OnDestroy(); -} - -void Dialer::PostNcDestroy() -{ - CBaseDialog::PostNcDestroy(); - delete this; -} - -BEGIN_MESSAGE_MAP(Dialer, CBaseDialog) - ON_BN_CLICKED(IDOK, OnBnClickedOk) - ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel) - ON_WM_SETCURSOR() - ON_BN_CLICKED(IDC_DIALER_DND, &Dialer::OnBnClickedDND) - ON_BN_CLICKED(IDC_DIALER_AA, &Dialer::OnBnClickedAA) - ON_BN_CLICKED(IDC_DIALER_VOICEMAIL, OnBnClickedVoicemail) - ON_BN_CLICKED(IDC_BUTTON_PLUS_INPUT, &Dialer::OnBnClickedPlusInput) - ON_BN_CLICKED(IDC_BUTTON_MINUS_INPUT, &Dialer::OnBnClickedMinusInput) - ON_BN_CLICKED(IDC_BUTTON_PLUS_OUTPUT, &Dialer::OnBnClickedPlusOutput) - ON_BN_CLICKED(IDC_BUTTON_MINUS_OUTPUT, &Dialer::OnBnClickedMinusOutput) - ON_BN_CLICKED(IDC_BUTTON_MUTE_OUTPUT, &Dialer::OnBnClickedMuteOutput) - ON_BN_CLICKED(IDC_BUTTON_MUTE_INPUT, &Dialer::OnBnClickedMuteInput) - ON_COMMAND_RANGE(IDC_SHORTCUT_RANGE, IDC_SHORTCUT_RANGE + 20, &Dialer::OnBnClickedShortcut) - ON_WM_RBUTTONUP() - ON_WM_LBUTTONUP() - ON_WM_MOUSEMOVE() - - ON_BN_CLICKED(IDC_CALL, OnBnClickedCall) -#ifdef _GLOBAL_VIDEO - ON_BN_CLICKED(IDC_VIDEO_CALL, OnBnClickedVideoCall) -#endif - ON_BN_CLICKED(IDC_MESSAGE, OnBnClickedMessage) - ON_BN_CLICKED(IDC_HOLD, OnBnClickedHold) - ON_BN_CLICKED(IDC_TRANSFER, OnBnClickedTransfer) - ON_BN_CLICKED(IDC_END, OnBnClickedEnd) - ON_CBN_EDITCHANGE(IDC_NUMBER, &Dialer::OnCbnEditchangeComboAddr) - ON_CBN_SELCHANGE(IDC_NUMBER, &Dialer::OnCbnSelchangeComboAddr) - - ON_BN_CLICKED(IDC_KEY_1, &Dialer::OnBnClickedKey1) - ON_BN_CLICKED(IDC_KEY_2, &Dialer::OnBnClickedKey2) - ON_BN_CLICKED(IDC_KEY_3, &Dialer::OnBnClickedKey3) - ON_BN_CLICKED(IDC_KEY_4, &Dialer::OnBnClickedKey4) - ON_BN_CLICKED(IDC_KEY_5, &Dialer::OnBnClickedKey5) - ON_BN_CLICKED(IDC_KEY_6, &Dialer::OnBnClickedKey6) - ON_BN_CLICKED(IDC_KEY_7, &Dialer::OnBnClickedKey7) - ON_BN_CLICKED(IDC_KEY_8, &Dialer::OnBnClickedKey8) - ON_BN_CLICKED(IDC_KEY_9, &Dialer::OnBnClickedKey9) - ON_BN_CLICKED(IDC_KEY_STAR, &Dialer::OnBnClickedKeyStar) - ON_BN_CLICKED(IDC_KEY_0, &Dialer::OnBnClickedKey0) - ON_BN_CLICKED(IDC_KEY_GRATE, &Dialer::OnBnClickedKeyGrate) - ON_BN_CLICKED(IDC_REDIAL, &Dialer::OnBnClickedRedial) - ON_BN_CLICKED(IDC_DELETE, &Dialer::OnBnClickedDelete) - ON_BN_CLICKED(IDC_KEY_PLUS, &Dialer::OnBnClickedKeyPlus) - ON_BN_CLICKED(IDC_CLEAR, &Dialer::OnBnClickedClear) - ON_WM_HSCROLL() - ON_WM_CREATE() - ON_WM_DESTROY() - ON_WM_TIMER() -END_MESSAGE_MAP() - -void Dialer::UpdateVoicemailButton(bool hasMail) -{ - if (hasMail) { - m_ButtonVoicemail.LoadBitmaps(IDB_VMAIL, IDB_VMAIL_DOWN, IDB_VMAIL_FOCUS); - } - else { - m_ButtonVoicemail.LoadBitmaps(IDB_VMAIL_GREY, IDB_VMAIL_GREY_DOWN, IDB_VMAIL_GREY_FOCUS); - } - m_ButtonVoicemail.SizeToContent(); - -} - -void Dialer::RebuildButtons(bool init) -{ - m_ButtonVoicemail.ShowWindow(SW_SHOW); - if (IsChild(&m_ButtonDND)) { - m_ToolTip.DelTool(&m_ButtonDND); - m_ButtonDND.DestroyWindow(); - } - if (IsChild(&m_ButtonAA)) { - m_ToolTip.DelTool(&m_ButtonAA); - m_ButtonAA.DestroyWindow(); - } - bool addAA = accountSettings.autoAnswer == _T("button"); - bool addDND = accountSettings.denyIncoming == _T("button"); - if (addAA || addDND) { - CRect mainRect; - if (!init) { - mainDlg->GetWindowRect(mainRect); - mainDlg->SetWindowPos(NULL, 0, 0, mainDlg->windowSize.x, mainDlg->windowSize.y, SWP_NOZORDER | SWP_NOMOVE); - } - - CRect rect; - m_ButtonVoicemail.GetWindowRect(&rect); - ScreenToClient(rect); - rect.top -= 1; - rect.bottom += 2; - rect.left -= 1; - rect.right += 2; - - CRect mapRect; - mapRect.bottom = 2; - MapDialogRect(&mapRect); - int stepPx = mapRect.bottom + rect.Width(); - - rect.left -= stepPx; - rect.right -= stepPx; - - if (addAA) { - m_ButtonAA.Create(Translate(_T("AA")), WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX | BS_PUSHLIKE, rect, this, IDC_DIALER_AA); - m_ButtonAA.SetFont(GetFont()); - m_ButtonAA.SetCheck(accountSettings.AA ? BST_CHECKED : BST_UNCHECKED); - AutoMove(m_ButtonAA.m_hWnd, 100, 100, 0, 0); - m_ToolTip.AddTool(&m_ButtonAA, Translate(_T("Auto Answer"))); - rect.left -= stepPx; - rect.right -= stepPx; - } - if (addDND) { - m_ButtonDND.Create(Translate(_T("DND")), WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX | BS_PUSHLIKE, rect, this, IDC_DIALER_DND); - m_ButtonDND.SetFont(GetFont()); - m_ButtonDND.SetCheck(accountSettings.DND ? BST_CHECKED : BST_UNCHECKED); - AutoMove(m_ButtonDND.m_hWnd, 100, 100, 0, 0); - m_ToolTip.AddTool(&m_ButtonDND, Translate(_T("Do Not Disturb"))); - rect.left -= stepPx; - rect.right -= stepPx; - } - if (!init) { - mainDlg->SetWindowPos(NULL, 0, 0, mainRect.Width(), mainRect.Height(), SWP_NOZORDER | SWP_NOMOVE); - } - } -} - -void Dialer::OnTimer(UINT_PTR TimerVal) -{ - if (TimerVal == IDT_TIMER_VU_METER) { - TimerVuMeter(); - } -} - -BOOL Dialer::PreTranslateMessage(MSG* pMsg) -{ - m_ToolTip.RelayEvent(pMsg); - - BOOL catched = FALSE; - BOOL isEdit = FALSE; - CEdit* edit = NULL; - if (pMsg->message == WM_CHAR || (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)) { - CComboBox *combobox = (CComboBox*)GetDlgItem(IDC_NUMBER); - edit = (CEdit*)FindWindowEx(combobox->m_hWnd, NULL, _T("EDIT"), NULL); - isEdit = !edit || edit == GetFocus(); - } - if (pMsg->message == WM_CHAR) - { - if (pMsg->wParam == 48) - { - if (!isEdit) { - GotoDlgCtrl(GetDlgItem(IDC_KEY_0)); - OnBnClickedKey0(); - catched = TRUE; - } - else { - DTMF(_T("0")); - } - } - else if (pMsg->wParam == 49) - { - if (!isEdit) { - GotoDlgCtrl(GetDlgItem(IDC_KEY_1)); - OnBnClickedKey1(); - catched = TRUE; - } - else { - DTMF(_T("1")); - } - } - else if (pMsg->wParam == 50) - { - if (!isEdit) { - GotoDlgCtrl(GetDlgItem(IDC_KEY_2)); - OnBnClickedKey2(); - catched = TRUE; - } - else { - DTMF(_T("2")); - } - } - else if (pMsg->wParam == 51) - { - if (!isEdit) { - GotoDlgCtrl(GetDlgItem(IDC_KEY_3)); - OnBnClickedKey3(); - catched = TRUE; - } - else { - DTMF(_T("3")); - } - } - else if (pMsg->wParam == 52) - { - if (!isEdit) { - GotoDlgCtrl(GetDlgItem(IDC_KEY_4)); - OnBnClickedKey4(); - catched = TRUE; - } - else { - DTMF(_T("4")); - } - } - else if (pMsg->wParam == 53) - { - if (!isEdit) { - GotoDlgCtrl(GetDlgItem(IDC_KEY_5)); - OnBnClickedKey5(); - catched = TRUE; - } - else { - DTMF(_T("5")); - } - } - else if (pMsg->wParam == 54) - { - if (!isEdit) { - GotoDlgCtrl(GetDlgItem(IDC_KEY_6)); - OnBnClickedKey6(); - catched = TRUE; - } - else { - DTMF(_T("6")); - } - } - else if (pMsg->wParam == 55) - { - if (!isEdit) { - GotoDlgCtrl(GetDlgItem(IDC_KEY_7)); - OnBnClickedKey7(); - catched = TRUE; - } - else { - DTMF(_T("7")); - } - } - else if (pMsg->wParam == 56) - { - if (!isEdit) { - GotoDlgCtrl(GetDlgItem(IDC_KEY_8)); - OnBnClickedKey8(); - catched = TRUE; - } - else { - DTMF(_T("8")); - } - } - else if (pMsg->wParam == 57) - { - if (!isEdit) { - GotoDlgCtrl(GetDlgItem(IDC_KEY_9)); - OnBnClickedKey9(); - catched = TRUE; - } - else { - DTMF(_T("9")); - } - } - else if (pMsg->wParam == 35 || pMsg->wParam == 47) - { - if (!isEdit) { - GotoDlgCtrl(GetDlgItem(IDC_KEY_GRATE)); - OnBnClickedKeyGrate(); - catched = TRUE; - } - else { - DTMF(_T("#")); - } - } - else if (pMsg->wParam == 42) - { - if (!isEdit) { - GotoDlgCtrl(GetDlgItem(IDC_KEY_STAR)); - OnBnClickedKeyStar(); - catched = TRUE; - } - else { - DTMF(_T("*")); - } - } - else if (pMsg->wParam == 43) - { - if (!isEdit) { - GotoDlgCtrl(GetDlgItem(IDC_KEY_PLUS)); - OnBnClickedKeyPlus(); - catched = TRUE; - } - } - else if (pMsg->wParam == 8 || pMsg->wParam == 45) - { - if (!isEdit) - { - GotoDlgCtrl(GetDlgItem(IDC_DELETE)); - OnBnClickedDelete(); - catched = TRUE; - } - } - else if (pMsg->wParam == 46) - { - if (!isEdit) - { - Input(_T("."), TRUE); - catched = TRUE; - } - } - } - else if (pMsg->message == WM_KEYDOWN) { - if (pMsg->wParam == VK_ESCAPE) { - if (!isEdit) { - GotoDlgCtrl(GetDlgItem(IDC_NUMBER)); - catched = TRUE; - } - if (edit) { - CString str; - edit->GetWindowText(str); - if (!str.IsEmpty()) { - Clear(); - catched = TRUE; - } - } - } - } - if (!catched) - { - return CBaseDialog::PreTranslateMessage(pMsg); - } - else { - return TRUE; - } -} - -void Dialer::OnBnClickedOk() -{ - if (accountSettings.singleMode && GetDlgItem(IDC_END)->IsWindowVisible()) { - OnBnClickedEnd(); - } - else { - OnBnClickedCall(); - } -} - -void Dialer::OnBnClickedCancel() -{ - mainDlg->ShowWindow(SW_HIDE); -} - -void Dialer::DTMF(CString digits) -{ - pjsua_call_id call_id = PJSUA_INVALID_ID; - MessagesContact* messagesContact = mainDlg->messagesDlg->GetMessageContact(); - if (messagesContact && messagesContact->callId != -1) { - call_id = messagesContact->callId; - } - msip_call_dial_dtmf(call_id, digits); -} - -void Dialer::Input(CString digits, BOOL disableDTMF) -{ - if (!disableDTMF) { - DTMF(digits); - } - CComboBox *combobox = (CComboBox*)GetDlgItem(IDC_NUMBER); - CEdit* edit = (CEdit*)FindWindowEx(combobox->m_hWnd, NULL, _T("EDIT"), NULL); - if (edit) { - int nLength = edit->GetWindowTextLength(); - edit->SetSel(nLength, nLength); - edit->ReplaceSel(digits); - } -} - -void Dialer::DialedClear() -{ - CComboBox *combobox = (CComboBox*)GetDlgItem(IDC_NUMBER); - combobox->ResetContent(); - combobox->Clear(); -} -void Dialer::DialedLoad() -{ - CComboBox *combobox = (CComboBox*)GetDlgItem(IDC_NUMBER); - CString key; - CString val; - LPTSTR ptr = val.GetBuffer(255); - int i = 0; - while (TRUE) { - key.Format(_T("%d"), i); - if (GetPrivateProfileString(_T("Dialed"), key, NULL, ptr, 256, accountSettings.iniFile)) { - combobox->AddString(ptr); - } - else { - break; - } - i++; - } -} - -void Dialer::DialedSave(CComboBox *combobox) -{ - CString key; - CString val; - WritePrivateProfileString(_T("Dialed"), NULL, NULL, accountSettings.iniFile); - for (int i = 0; i < combobox->GetCount(); i++) - { - int n = combobox->GetLBTextLen(i); - combobox->GetLBText(i, val.GetBuffer(n)); - val.ReleaseBuffer(); - - key.Format(_T("%d"), i); - WritePrivateProfileString(_T("Dialed"), key, val, accountSettings.iniFile); - } -} - -void Dialer::SetNumber(CString number, int callsCount) -{ - CComboBox *combobox = (CComboBox*)GetDlgItem(IDC_NUMBER); - CString old; - combobox->GetWindowText(old); - if (old.IsEmpty() || number.Find(old) != 0) { - combobox->SetWindowText(number); - } - UpdateCallButton(0, callsCount); -} - -void Dialer::UpdateCallButton(BOOL forse, int callsCount) -{ - int len; - if (!forse) { - CComboBox *combobox = (CComboBox*)GetDlgItem(IDC_NUMBER); - len = combobox->GetWindowTextLength(); - } - else { - len = 1; - } - CButton *button = (CButton *)GetDlgItem(IDC_CALL); - bool state = false; - if (accountSettings.singleMode) { - if (callsCount == -1) { - callsCount = call_get_count_noincoming(); - } - if (callsCount) { - if (!GetDlgItem(IDC_END)->IsWindowVisible()) { - button->ShowWindow(SW_HIDE); -#ifdef _GLOBAL_VIDEO - GetDlgItem(IDC_VIDEO_CALL)->ShowWindow(SW_HIDE); -#endif - GetDlgItem(IDC_MESSAGE)->ShowWindow(SW_HIDE); - GetDlgItem(IDC_HOLD)->ShowWindow(SW_SHOW); - GetDlgItem(IDC_TRANSFER)->ShowWindow(SW_SHOW); - GetDlgItem(IDC_END)->ShowWindow(SW_SHOW); - GotoDlgCtrl(GetDlgItem(IDC_END)); - } - } - else { - if (GetDlgItem(IDC_END)->IsWindowVisible()) { - GetDlgItem(IDC_HOLD)->ShowWindow(SW_HIDE); - GetDlgItem(IDC_TRANSFER)->ShowWindow(SW_HIDE); - GetDlgItem(IDC_END)->ShowWindow(SW_HIDE); - button->ShowWindow(SW_SHOW); -#ifdef _GLOBAL_VIDEO - GetDlgItem(IDC_VIDEO_CALL)->ShowWindow(SW_SHOW); -#endif - GetDlgItem(IDC_MESSAGE)->ShowWindow(SW_SHOW); - } - } - state = callsCount || len ? true : false; - - } - else { - state = len ? true : false; - } - button->EnableWindow(state); - -#ifdef _GLOBAL_VIDEO - GetDlgItem(IDC_VIDEO_CALL)->EnableWindow(state); -#endif - GetDlgItem(IDC_MESSAGE)->EnableWindow(state); - - CButton *buttonRedial = (CButton *)GetDlgItem(IDC_REDIAL); - CButton *buttonDelete = (CButton *)GetDlgItem(IDC_DELETE); - if (!state) { - buttonDelete->ShowWindow(SW_HIDE); - buttonRedial->ShowWindow(SW_SHOW); - } - else { - buttonRedial->ShowWindow(SW_HIDE); - buttonDelete->ShowWindow(SW_SHOW); - } -} - -void Dialer::Action(DialerActions action) -{ - CString number; - CComboBox *combobox = (CComboBox*)GetDlgItem(IDC_NUMBER); - combobox->GetWindowText(number); - number.Trim(); - if (!number.IsEmpty()) { - bool res = false; - if (action != ACTION_MESSAGE) { - res = mainDlg->MakeCall(number, action == ACTION_VIDEO_CALL); - } - else { - res = mainDlg->MessagesOpen(number); - } - if (res) { - //-- save dialed in combobox - int pos = combobox->FindStringExact(-1, number); - if (pos == CB_ERR || pos > 0) { - if (pos > 0) { - combobox->DeleteString(pos); - } - else if (combobox->GetCount() >= 10) - { - combobox->DeleteString(combobox->GetCount() - 1); - } - combobox->InsertString(0, number); - combobox->SetCurSel(0); - } - DialedSave(combobox); - if (!accountSettings.singleMode) { - Clear(); - } - //-- end - } - } -} - -void Dialer::Clear(bool update) -{ - CComboBox *combobox = (CComboBox*)GetDlgItem(IDC_NUMBER); - combobox->SetCurSel(-1); - if (update) { - UpdateCallButton(); - } -} - -void Dialer::OnBnClickedCall() -{ - Action(ACTION_CALL); -} - -#ifdef _GLOBAL_VIDEO -void Dialer::OnBnClickedVideoCall() -{ - Action(ACTION_VIDEO_CALL); -} -#endif - -void Dialer::OnBnClickedMessage() -{ - Action(ACTION_MESSAGE); -} - -void Dialer::OnBnClickedHold() -{ - mainDlg->messagesDlg->OnBnClickedHold(); -} - -void Dialer::OnBnClickedTransfer() -{ - if (!mainDlg->transferDlg) { - mainDlg->transferDlg = new Transfer(this); - } - mainDlg->transferDlg->SetAction(MSIP_ACTION_TRANSFER); - mainDlg->transferDlg->SetForegroundWindow(); -} - -void Dialer::OnBnClickedEnd() -{ - MessagesContact* messagesContact = mainDlg->messagesDlg->GetMessageContact(); - if (messagesContact && messagesContact->callId != -1) { - msip_call_end(messagesContact->callId); - } - else { - call_hangup_all_noincoming(); - } -} - -void Dialer::OnCbnEditchangeComboAddr() -{ - UpdateCallButton(); -} - -void Dialer::OnCbnSelchangeComboAddr() -{ - UpdateCallButton(TRUE); -} - -void Dialer::OnBnClickedKey1() -{ - Input(_T("1")); -} - -void Dialer::OnBnClickedKey2() -{ - Input(_T("2")); -} - -void Dialer::OnBnClickedKey3() -{ - Input(_T("3")); -} - -void Dialer::OnBnClickedKey4() -{ - Input(_T("4")); -} - -void Dialer::OnBnClickedKey5() -{ - Input(_T("5")); -} - -void Dialer::OnBnClickedKey6() -{ - Input(_T("6")); -} - -void Dialer::OnBnClickedKey7() -{ - Input(_T("7")); -} - -void Dialer::OnBnClickedKey8() -{ - Input(_T("8")); -} - -void Dialer::OnBnClickedKey9() -{ - Input(_T("9")); -} - -void Dialer::OnBnClickedKeyStar() -{ - Input(_T("*")); -} - -void Dialer::OnBnClickedKey0() -{ - Input(_T("0")); -} - -void Dialer::OnBnClickedKeyGrate() -{ - Input(_T("#")); -} - -void Dialer::OnBnClickedRedial() -{ - if (!accountSettings.lastCallNumber.IsEmpty()) { - mainDlg->MakeCall(accountSettings.lastCallNumber, accountSettings.lastCallHasVideo); - } -} - -void Dialer::OnBnClickedDelete() -{ - CComboBox *combobox = (CComboBox*)GetDlgItem(IDC_NUMBER); - CEdit* edit = (CEdit*)FindWindowEx(combobox->m_hWnd, NULL, _T("EDIT"), NULL); - if (edit) { - int nLength = edit->GetWindowTextLength(); - edit->SetSel(nLength - 1, nLength); - edit->ReplaceSel(_T("")); - } -} - -void Dialer::OnBnClickedKeyPlus() -{ - Input(_T("+"), TRUE); -} - -void Dialer::OnBnClickedClear() -{ - Clear(); -} - -void Dialer::OnLButtonUp(UINT nFlags, CPoint pt) -{ -} - -void Dialer::OnRButtonUp(UINT nFlags, CPoint pt) -{ -} - -void Dialer::OnMouseMove(UINT nFlags, CPoint pt) -{ -} - -void Dialer::OnHScroll(UINT, UINT, CScrollBar* sender) -{ - if (pj_ready) { - int pos; - if (!sender || sender == (CScrollBar*)&m_SliderCtrlOutput) { - if (sender && muteOutput) { - CButton *button = (CButton*)GetDlgItem(IDC_BUTTON_MUTE_OUTPUT); - button->SetCheck(BST_UNCHECKED); - OnBnClickedMuteOutput(); - return; - } - pos = m_SliderCtrlOutput.GetPos(); - //msip_audio_output_set_volume(pos,muteOutput); - msip_audio_conf_set_volume(pos, muteOutput); - accountSettings.volumeOutput = pos; - mainDlg->AccountSettingsPendingSave(); - } - if (!sender || sender == (CScrollBar*)&m_SliderCtrlInput) { - if (sender && muteInput) { - CButton *button = (CButton*)GetDlgItem(IDC_BUTTON_MUTE_INPUT); - button->SetCheck(BST_UNCHECKED); - OnBnClickedMuteInput(); - return; - } - pos = m_SliderCtrlInput.GetPos(); - msip_audio_input_set_volume(pos, muteInput); - accountSettings.volumeInput = pos; - mainDlg->AccountSettingsPendingSave(); - } - } -} - -void Dialer::OnBnClickedMinusInput() -{ - int pos = m_SliderCtrlInput.GetPos(); - if (pos > 0) { - pos -= 5; - if (pos < 0) { - pos = 0; - } - m_SliderCtrlInput.SetPos(pos); - OnHScroll(0, 0, (CScrollBar *)&m_SliderCtrlInput); - } - - -} - -void Dialer::OnBnClickedPlusInput() -{ - int pos = m_SliderCtrlInput.GetPos(); - if (pos < 100) { - pos += 5; - if (pos > 100) { - pos = 100; - } - m_SliderCtrlInput.SetPos(pos); - OnHScroll(0, 0, (CScrollBar *)&m_SliderCtrlInput); - } -} - -void Dialer::OnBnClickedMinusOutput() -{ - int pos = m_SliderCtrlOutput.GetPos(); - if (pos > 0) { - pos -= 5; - if (pos < 0) { - pos = 0; - } - m_SliderCtrlOutput.SetPos(pos); - OnHScroll(0, 0, (CScrollBar *)&m_SliderCtrlOutput); - } -} - -void Dialer::OnBnClickedPlusOutput() -{ - int pos = m_SliderCtrlOutput.GetPos(); - if (pos < 100) { - pos += 5; - if (pos > 100) { - pos = 100; - } - m_SliderCtrlOutput.SetPos(pos); - OnHScroll(0, 0, (CScrollBar *)&m_SliderCtrlOutput); - } -} - -void Dialer::OnBnClickedMuteOutput() -{ - CButton *button = (CButton*)GetDlgItem(IDC_BUTTON_MUTE_OUTPUT); - if (button->GetCheck() == BST_CHECKED) { - button->SetIcon(m_hIconMuteOutput); - muteOutput = FALSE; - OnHScroll(0, 0, NULL); - } - else { - button->SetIcon(m_hIconMutedOutput); - muteOutput = TRUE; - OnHScroll(0, 0, NULL); - } - button->SetCheck(!button->GetCheck()); -} - -void Dialer::OnBnClickedMuteInput() -{ - CButton *button = (CButton*)GetDlgItem(IDC_BUTTON_MUTE_INPUT); - if (button->GetCheck() == BST_CHECKED) { - button->SetIcon(m_hIconMuteInput); - muteInput = FALSE; - OnHScroll(0, 0, NULL); - } - else { - button->SetIcon(m_hIconMutedInput); - muteInput = TRUE; - OnHScroll(0, 0, NULL); - } - button->SetCheck(!button->GetCheck()); -} - -void Dialer::TimerVuMeter() -{ - unsigned tx_level = 0, rx_level = 0; - pjsua_conf_port_id ids[PJSUA_MAX_CONF_PORTS]; - unsigned count = PJSUA_MAX_CONF_PORTS; - if (pjsua_var.state == PJSUA_STATE_RUNNING && pjsua_enum_conf_ports(ids, &count) == PJ_SUCCESS && count > 1) { - for (unsigned i = 0; i < count; i++) { - unsigned tx_level_curr, rx_level_curr; - pjsua_conf_port_info conf_port_info; - if (pjsua_conf_get_port_info(ids[i], &conf_port_info) == PJ_SUCCESS) { - if (pjsua_conf_get_signal_level(ids[i], &tx_level_curr, &rx_level_curr) == PJ_SUCCESS) { - if (conf_port_info.slot_id == 0) { - tx_level = rx_level_curr * (conf_port_info.rx_level_adj > 0 ? 1 : 0); - } - else { - rx_level_curr = conf_port_info.rx_level_adj > 0 ? rx_level_curr : 0; - if (rx_level_curr > rx_level) { - rx_level = rx_level_curr; - } - } - } - } - } - if (!m_SliderCtrlInput.IsActive) m_SliderCtrlInput.IsActive = true; - if (!m_SliderCtrlOutput.IsActive) m_SliderCtrlOutput.IsActive = true; - } - else { - KillTimer(IDT_TIMER_VU_METER); - m_SliderCtrlInput.IsActive = false; - m_SliderCtrlOutput.IsActive = false; - } - //CString s; - //s.Format(_T("tx %d rx %d"),tx_level_max, tx_level_max); - //mainDlg->SetWindowText(s); - m_SliderCtrlInput.SetSelection(0, tx_level / 0.95); - m_SliderCtrlInput.Invalidate(FALSE); - m_SliderCtrlOutput.SetSelection(0, rx_level / 1.15); - m_SliderCtrlOutput.Invalidate(FALSE); -} - -BOOL Dialer::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) -{ - if (pWnd == &m_ButtonVoicemail) { - ::SetCursor(m_hCursorHand); - return TRUE; - } - return CBaseDialog::OnSetCursor(pWnd, nHitTest, message); -} - -void Dialer::OnBnClickedDND() -{ - CButton *button = (CButton*)GetDlgItem(IDC_DIALER_DND); - accountSettings.DND = button->GetCheck() == BST_CHECKED; - mainDlg->PublishStatus(); - accountSettings.SettingsSave(); -} - -void Dialer::OnBnClickedAA() -{ - CButton *button = (CButton*)GetDlgItem(IDC_DIALER_AA); - accountSettings.AA = button->GetCheck() == BST_CHECKED; - accountSettings.SettingsSave(); - mainDlg->UpdateWindowText(); -} - -void Dialer::OnBnClickedVoicemail() -{ - if (accountSettings.accountId && !accountSettings.account.voicemailNumber.IsEmpty()) { - mainDlg->MakeCall(accountSettings.account.voicemailNumber); - } -} - -void Dialer::OnBnClickedShortcut(UINT nID) -{ - int i = nID - IDC_SHORTCUT_RANGE; - mainDlg->ShortcutAction(&shortcuts.GetAt(i)); -} diff --git a/microsip/Dialer.h b/microsip/Dialer.h deleted file mode 100644 index 71378a29..00000000 --- a/microsip/Dialer.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#pragma once - -#include "resource.h" -#include "define.h" -#include "BaseDialog.h" -#include "ButtonDialer.h" -#include "CLevelsSliderCtrl.h" -#include "IconButton.h" - -enum DialerActions { - ACTION_CALL, ACTION_VIDEO_CALL, ACTION_MESSAGE -}; - -class Dialer : - public CBaseDialog -{ - CFont m_font; - CFont m_font_number; - CFont m_font_balance; - CFont m_font_call; - - CButton m_ButtonDND; - CButton m_ButtonAA; - - CButtonDialer m_ButtonDialer1; - CButtonDialer m_ButtonDialer2; - CButtonDialer m_ButtonDialer3; - CButtonDialer m_ButtonDialer4; - CButtonDialer m_ButtonDialer5; - CButtonDialer m_ButtonDialer6; - CButtonDialer m_ButtonDialer7; - CButtonDialer m_ButtonDialer8; - CButtonDialer m_ButtonDialer9; - CButtonDialer m_ButtonDialer0; - CButtonDialer m_ButtonDialerStar; - CButtonDialer m_ButtonDialerGrate; - CButtonDialer m_ButtonDialerDelete; - CButtonDialer m_ButtonDialerPlus; - CButtonDialer m_ButtonDialerClear; - CButtonDialer m_ButtonDialerRedial; - - CLevelsSliderCtrl m_SliderCtrlInput; - CLevelsSliderCtrl m_SliderCtrlOutput; - - HICON m_hIconMuteOutput; - HICON m_hIconMutedOutput; - HICON m_hIconMuteInput; - HICON m_hIconMutedInput; - - BOOL muteOutput; - BOOL muteInput; - - CRect defaultPos; - -public: - CBitmapButton m_ButtonVoicemail; - HICON m_hIconHold; - HICON m_hIconTransfer; -#ifdef _GLOBAL_VIDEO - HICON m_hIconVideo; -#endif - HICON m_hIconMessage; - Dialer(CWnd* pParent = NULL); // standard constructor - ~Dialer(); - enum { IDD = IDD_DIALER }; - - void UpdateVoicemailButton(bool hasMail); - void DTMF(CString digits); - void Input(CString digits, BOOL disableDTMF = FALSE); - void DialedClear(); - void DialedLoad(); - void DialedSave(CComboBox *combobox); - void SetNumber(CString number, int callsCount = -1); - void UpdateCallButton(BOOL forse = FALSE, int callsCount = -1); - void Action(DialerActions action); - void Clear(bool update=true); - - void TimerVuMeter(); - -protected: - CToolTipCtrl m_ToolTip; - HCURSOR m_hCursorHand; - - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - virtual BOOL OnInitDialog(); - virtual void PostNcDestroy(); - BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); - DECLARE_MESSAGE_MAP() - -public: - afx_msg void OnBnClickedOk(); - afx_msg void OnBnClickedCancel(); - afx_msg void OnBnClickedDND(); - afx_msg void OnBnClickedAA(); - afx_msg void OnBnClickedVoicemail(); - - afx_msg void OnBnClickedCall(); -#ifdef _GLOBAL_VIDEO - afx_msg void OnBnClickedVideoCall(); -#endif - afx_msg void OnBnClickedMessage(); - afx_msg void OnBnClickedHold(); - afx_msg void OnBnClickedTransfer(); - afx_msg void OnBnClickedEnd(); - afx_msg void OnCbnEditchangeComboAddr(); - afx_msg void OnCbnSelchangeComboAddr(); - - afx_msg void OnBnClickedPlusInput(); - afx_msg void OnBnClickedMinusInput(); - afx_msg void OnBnClickedPlusOutput(); - afx_msg void OnBnClickedMinusOutput(); - - afx_msg void OnBnClickedMuteOutput(); - afx_msg void OnBnClickedMuteInput(); - afx_msg void OnBnClickedKey1(); - afx_msg void OnBnClickedKey2(); - afx_msg void OnBnClickedKey3(); - afx_msg void OnBnClickedKey4(); - afx_msg void OnBnClickedKey5(); - afx_msg void OnBnClickedKey6(); - afx_msg void OnBnClickedKey7(); - afx_msg void OnBnClickedKey8(); - afx_msg void OnBnClickedKey9(); - afx_msg void OnBnClickedKeyStar(); - afx_msg void OnBnClickedKey0(); - afx_msg void OnBnClickedKeyGrate(); - afx_msg void OnBnClickedKeyPlus(); - afx_msg void OnBnClickedClear(); - afx_msg void OnBnClickedRedial(); - afx_msg void OnBnClickedDelete(); - afx_msg void OnRButtonUp( UINT nFlags, CPoint pt ); - afx_msg void OnLButtonUp( UINT nFlags, CPoint pt ); - afx_msg void OnMouseMove(UINT nFlags, CPoint pt ); - afx_msg void OnHScroll( UINT, UINT, CScrollBar* ); - virtual BOOL PreTranslateMessage(MSG* pMsg); - afx_msg void OnTimer (UINT_PTR TimerVal); - CList shortcutButtons; - void RebuildShortcuts(bool init = false); - afx_msg void OnBnClickedShortcut(UINT nID); - void RebuildButtons(bool init = false); -}; diff --git a/microsip/IconButton.cpp b/microsip/IconButton.cpp deleted file mode 100644 index 2643b053..00000000 --- a/microsip/IconButton.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// CIconButton.cpp : implementation file -// -#include "StdAfx.h" -#include "IconButton.h" - -// CIconButton -IMPLEMENT_DYNAMIC(CIconButton, CButton) -CIconButton::CIconButton() -{ -} - -CIconButton::~CIconButton() -{ -} - diff --git a/microsip/IconButton.h b/microsip/IconButton.h deleted file mode 100644 index 3648af26..00000000 --- a/microsip/IconButton.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "const.h" - -class CIconButton : public CButton -{ - DECLARE_DYNAMIC(CIconButton) -public: - CIconButton(); - virtual ~CIconButton(); -}; diff --git a/microsip/MMNotificationClient.h b/microsip/MMNotificationClient.h deleted file mode 100644 index 40c19cae..00000000 --- a/microsip/MMNotificationClient.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -//----------------------------------------------------------- -// When the status of audio endpoint devices change, the -// MMDevice module calls these methods to notify the client. -//----------------------------------------------------------- - -#include -#include -#include "global.h" - -#define SAFE_RELEASE(punk) \ - if ((punk) != NULL) \ - { (punk)->Release(); (punk) = NULL; } - -class CMMNotificationClient : public IMMNotificationClient -{ - LONG _cRef; - IMMDeviceEnumerator *_pEnumerator; - bool hasCallback; - public: - CMMNotificationClient() : - _cRef(1), - _pEnumerator(NULL), - hasCallback(false) - { - HRESULT hr = S_OK; - CoInitialize(NULL); - if (_pEnumerator == NULL) - { - // Get enumerator for audio endpoint devices. - hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), - NULL, CLSCTX_INPROC_SERVER, - __uuidof(IMMDeviceEnumerator), - (void**)&_pEnumerator); - if (hr != S_OK) { - _pEnumerator = NULL; - } else { - if (_pEnumerator->RegisterEndpointNotificationCallback(this) == S_OK) { - hasCallback = true; - } - } - } - } - - ~CMMNotificationClient() - { - if (hasCallback) { - _pEnumerator->UnregisterEndpointNotificationCallback(this); - } - SAFE_RELEASE(_pEnumerator) - CoUninitialize(); - } - - // IUnknown methods -- AddRef, Release, and QueryInterface - - ULONG STDMETHODCALLTYPE AddRef() - { - return InterlockedIncrement(&_cRef); - } - - ULONG STDMETHODCALLTYPE Release() - { - ULONG ulRef = InterlockedDecrement(&_cRef); - if (0 == ulRef) - { - delete this; - } - return ulRef; - } - - HRESULT STDMETHODCALLTYPE QueryInterface( - REFIID riid, VOID **ppvInterface) - { - if (IID_IUnknown == riid) - { - AddRef(); - *ppvInterface = (IUnknown*)this; - } - else if (__uuidof(IMMNotificationClient) == riid) - { - AddRef(); - *ppvInterface = (IMMNotificationClient*)this; - } - else - { - *ppvInterface = NULL; - return E_NOINTERFACE; - } - return S_OK; - } - - // Callbacks - - HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged( - EDataFlow flow, ERole role, - LPCWSTR pwstrDeviceId) - { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR pwstrDeviceId) - { - return S_OK; - }; - - HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR pwstrDeviceId) - { - return S_OK; - } - - HRESULT STDMETHODCALLTYPE OnDeviceStateChanged( - LPCWSTR pwstrDeviceId, - DWORD dwNewState) - { - CWnd *pMainWnd = AfxGetApp()->m_pMainWnd; - if (pMainWnd) { - ::PostMessage(pMainWnd->m_hWnd, WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, 1); - } - return S_OK; - } - - HRESULT STDMETHODCALLTYPE OnPropertyValueChanged( - LPCWSTR pwstrDeviceId, - const PROPERTYKEY key) - { - return S_OK; - } -}; diff --git a/microsip/MessagesDlg.cpp b/microsip/MessagesDlg.cpp deleted file mode 100644 index f6d0a4f7..00000000 --- a/microsip/MessagesDlg.cpp +++ /dev/null @@ -1,1376 +0,0 @@ -īģŋ/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "atlrx.h" -#include "MessagesDlg.h" -#include "microsip.h" -#include "mainDlg.h" -#include "settings.h" -#include "Transfer.h" -#include "langpack.h" - -static DWORD __stdcall MEditStreamOutCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) -{ - CString sThisWrite; - sThisWrite.GetBufferSetLength(cb); - - CString *psBuffer = (CString *)dwCookie; - - for (int i=0;i psBuffer->GetLength()) cb = psBuffer->GetLength(); - - for (int i = 0; i < cb; i++) - { - *(pbBuff + i) = psBuffer->GetAt(i); - } - - *pcb = cb; - *psBuffer = psBuffer->Mid(cb); - - return 0; -} - -MessagesDlg::MessagesDlg(CWnd* pParent /*=NULL*/) -: CBaseDialog(MessagesDlg::IDD, pParent) -{ - this->m_hWnd = NULL; - Create (IDD, pParent); -} - -MessagesDlg::~MessagesDlg(void) -{ -} - -int MessagesDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (langPack.rtl) { - ModifyStyleEx(0,WS_EX_LAYOUTRTL); - } - return 0; -} - -void MessagesDlg::DoDataExchange(CDataExchange* pDX) -{ - CBaseDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_MESSAGES_TAB, tabComponent); -} - -BOOL MessagesDlg::OnInitDialog() -{ - CBaseDialog::OnInitDialog(); - - AutoMove(IDC_MESSAGES_TAB,0,0,100,0); - AutoMove(IDC_LAST_CALL,100,0,0,0); - AutoMove(IDC_CLOSE_ALL,100,0,0,0); - AutoMove(IDC_ACTIONS,100,0,0,0); - AutoMove(IDC_HOLD,100,0,0,0); - AutoMove(IDC_END,100,0,0,0); - AutoMove(IDC_LIST,0,0,100,80); - AutoMove(IDC_MESSAGE,0,80,100,20); - lastCall = NULL; - tab = &tabComponent; - - HICON m_hIcon = theApp.LoadIcon(IDR_MAINFRAME); - SetIcon(m_hIcon, FALSE); - - imageList.Create(16,16,ILC_COLOR32 | ILC_MASK,7,1); - - imageList.Add(LoadImageIcon(IDI_CALL_OUT)); - imageList.Add(LoadImageIcon(IDI_CALL_IN)); - imageList.Add(LoadImageIcon(IDI_CALL_MISS)); - imageList.Add(LoadImageIcon(IDI_ACTIVE)); - imageList.Add(LoadImageIcon(IDI_ACTIVE_SECURE)); - imageList.Add(LoadImageIcon(IDI_CONFERENCE)); - imageList.Add(LoadImageIcon(IDI_CONFERENCE_SECURE)); - imageList.Add(LoadImageIcon(IDI_MESSAGE_IN)); - imageList.Add(LoadImageIcon(IDI_ON_HOLD)); - imageList.Add(LoadImageIcon(IDI_ON_REMOTE_HOLD)); - imageList.Add(LoadImageIcon(IDI_ON_REMOTE_HOLD_CONFERENCE)); - - tab->SetImageList(&imageList); - - TranslateDialog(this->m_hWnd); - -#ifndef _GLOBAL_VIDEO - GetDlgItem(IDC_VIDEO_CALL)->ShowWindow(SW_HIDE); -#endif - - CRichEditCtrl* richEditList = (CRichEditCtrl*)GetDlgItem(IDC_LIST); - richEditList->SetEventMask(richEditList->GetEventMask() | ENM_MOUSEEVENTS); - richEditList->SetUndoLimit(0); - - CFont* font = this->GetFont(); - LOGFONT lf; - font->GetLogFont(&lf); - lf.lfHeight = 16; - _tcscpy(lf.lfFaceName, _T("Arial")); - fontList.CreateFontIndirect(&lf); - richEditList->SetFont(&fontList); - lf.lfHeight = 18; - fontMessage.CreateFontIndirect(&lf); - - CRichEditCtrl* richEdit = (CRichEditCtrl*)GetDlgItem(IDC_MESSAGE); - richEdit->SetEventMask(richEdit->GetEventMask() | ENM_KEYEVENTS); - richEdit->SetFont(&fontMessage); - - para.cbSize=sizeof(PARAFORMAT2); - para.dwMask = PFM_STARTINDENT | PFM_LINESPACING | PFM_SPACEBEFORE | PFM_SPACEAFTER; - para.dxStartIndent=100; - para.dySpaceBefore=100; - para.dySpaceAfter=0; - para.bLineSpacingRule = 5; - para.dyLineSpacing = 22; - - m_hIconDropDown = LoadImageIcon(IDI_DROPDOWN); - ((CButton*)GetDlgItem(IDC_ACTIONS))->SetIcon(m_hIconDropDown); - - m_hIconHold = LoadImageIcon(IDI_HOLD); - ((CButton*)GetDlgItem(IDC_HOLD))->SetIcon(m_hIconHold); - - menuActions.LoadMenu(IDR_MENU_CALL_ACTIONS); - CMenu *tracker = menuActions.GetSubMenu(0); - TranslateMenu(tracker->m_hMenu); - - MENUITEMINFO mii; - mii.cbSize = sizeof (MENUITEMINFO); - mii.fMask = MIIM_SUBMENU; - - menuAttendedTransfer.CreatePopupMenu(); - mii.hSubMenu = menuAttendedTransfer.m_hMenu; - tracker->SetMenuItemInfo(ID_ATTENDED_TRANSFER,&mii); - - menuMerge.CreatePopupMenu(); - mii.hSubMenu = menuMerge.m_hMenu; - tracker->SetMenuItemInfo(ID_MERGE,&mii); - - return TRUE; -} - -void MessagesDlg::OnDestroy() -{ - mainDlg->messagesDlg = NULL; - CBaseDialog::OnDestroy(); -} - - -void MessagesDlg::PostNcDestroy() -{ - CBaseDialog::PostNcDestroy(); - delete this; -} - -BEGIN_MESSAGE_MAP(MessagesDlg, CBaseDialog) - ON_WM_CREATE() - ON_WM_SYSCOMMAND() - ON_WM_CLOSE() - ON_WM_MOVE() - ON_WM_SIZE() - ON_WM_DESTROY() - ON_COMMAND(ID_CLOSEALLTABS,OnCloseAllTabs) - ON_COMMAND(ID_GOTOLASTTAB,OnGoToLastTab) - ON_COMMAND(ID_COPY,OnCopy) - ON_COMMAND(ID_SELECT_ALL,OnSelectAll) - ON_COMMAND_RANGE(ID_ATTENDED_TRANSFER_RANGE,ID_ATTENDED_TRANSFER_RANGE+99,OnAttendedTransfer) - ON_COMMAND_RANGE(ID_MERGE_RANGE,ID_MERGE_RANGE+99,OnMerge) - ON_COMMAND(IDCANCEL, OnCancel) - ON_BN_CLICKED(IDOK, &MessagesDlg::OnBnClickedOk) - ON_NOTIFY(EN_MSGFILTER, IDC_MESSAGE, &MessagesDlg::OnEnMsgfilterMessage) - ON_NOTIFY(TCN_SELCHANGE, IDC_MESSAGES_TAB, &MessagesDlg::OnTcnSelchangeTab) - ON_NOTIFY(TCN_SELCHANGING, IDC_MESSAGES_TAB, &MessagesDlg::OnTcnSelchangingTab) - ON_MESSAGE(WM_CONTEXTMENU,OnContextMenu) - ON_MESSAGE(UM_CLOSETAB, &MessagesDlg::OnCloseTab) - ON_BN_CLICKED(IDC_CALL_END, &MessagesDlg::OnBnClickedCallEnd) - ON_BN_CLICKED(IDC_VIDEO_CALL, &MessagesDlg::OnBnClickedVideoCall) - ON_BN_CLICKED(IDC_ACTIONS, &MessagesDlg::OnBnClickedActions) - ON_COMMAND(ID_TRANSFER,OnTransfer) - ON_COMMAND(ID_CONFERENCE,OnConference) - ON_COMMAND(ID_SEPARATE,OnSeparate) - ON_COMMAND(ID_DISCONNECT,OnDisconnect) - ON_BN_CLICKED(IDC_HOLD, &MessagesDlg::OnBnClickedHold) - ON_BN_CLICKED(IDC_END, &MessagesDlg::OnBnClickedEnd) - ON_BN_CLICKED(IDC_CLOSE_ALL, &MessagesDlg::OnBnClickedCloseAll) - ON_BN_CLICKED(IDC_LAST_CALL, &MessagesDlg::OnBnClickedLastCall) -END_MESSAGE_MAP() - -void MessagesDlg::OnSysCommand(UINT nID, LPARAM lParam) -{ - if (nID == SC_CLOSE) { - OnCancel(); - return; - } - __super::OnSysCommand(nID, lParam); -} - -LRESULT MessagesDlg::OnContextMenu(WPARAM wParam,LPARAM lParam) -{ - int x = GET_X_LPARAM(lParam); - int y = GET_Y_LPARAM(lParam); - POINT pt = { x, y }; - RECT rc; - if (x!=-1 || y!=-1) { - ScreenToClient(&pt); - GetClientRect(&rc); - if (!PtInRect(&rc, pt)) { - x = y = -1; - } - } else { - ::ClientToScreen((HWND)wParam, &pt); - x = 10+pt.x; - y = 10+pt.y; - } - if (x!=-1 || y!=-1) { - CMenu menu; - menu.LoadMenu(IDR_MENU_TABS); - CMenu* tracker = menu.GetSubMenu(0); - TranslateMenu(tracker->m_hMenu); - tracker->TrackPopupMenu( 0, x, y, this ); - return TRUE; - } - return DefWindowProc(WM_CONTEXTMENU,wParam,lParam); -} - -void MessagesDlg::OnClose() -{ - call_hangup_all_noincoming(); - this->ShowWindow(SW_HIDE); -} - -void MessagesDlg::OnMove(int x, int y) -{ - if (IsWindowVisible() && !IsZoomed() && !IsIconic()) { - CRect cRect; - GetWindowRect(&cRect); - accountSettings.messagesX = cRect.left; - accountSettings.messagesY = cRect.top; - mainDlg->AccountSettingsPendingSave(); - } -} - -void MessagesDlg::OnSize(UINT type, int w, int h) -{ - CBaseDialog::OnSize(type, w, h); - if (this->IsWindowVisible() && type == SIZE_RESTORED) { - CRect cRect; - GetWindowRect(&cRect); - accountSettings.messagesW = cRect.Width(); - accountSettings.messagesH = cRect.Height(); - mainDlg->AccountSettingsPendingSave(); - } -} - -void MessagesDlg::OnCancel() -{ - MessagesContact* messagesContact = GetMessageContact(); - if (messagesContact && messagesContact->callId != -1) { - return; - } - OnGoToLastTab(); - messagesContact = GetMessageContact(); - if (messagesContact && messagesContact->callId != -1) { - return; - } - OnClose(); -} - -void MessagesDlg::OnBnClickedOk() -{ -} - -MessagesContact* MessagesDlg::AddTab(CString number, CString name, BOOL activate, pjsua_call_info *call_info, call_user_data *user_data, BOOL notShowWindow, BOOL ifExists) -{ - MessagesContact* messagesContact; - - SIPURI sipuri; - ParseSIPURI(number, &sipuri); - - //-- incoming call - if (call_info && call_info->role==PJSIP_ROLE_UAS) { - //-- fix wrong domain - if (accountSettings.accountId && account == call_info->acc_id) { - if (IsIP(RemovePort(sipuri.domain))) { - sipuri.domain = accountSettings.account.domain; - } - } - //-- - } - //-- - if (accountSettings.accountId && RemovePort(accountSettings.account.domain) == RemovePort(sipuri.domain)) { - sipuri.domain = accountSettings.account.domain; - } - - number = (sipuri.user.GetLength() ? sipuri.user + _T("@") : _T("")) + sipuri.domain; - - LONG exists = -1; - for (int i=0; i < tab->GetItemCount(); i++) - { - messagesContact = GetMessageContact(i); - - CString compareNumber = messagesContact->number; - if (messagesContact->number == number || compareNumber == number) { - exists=i; - if (call_info) - { - if (messagesContact->callId != -1) { - if (messagesContact->callId != call_info->id) { - if (call_info->state != PJSIP_INV_STATE_DISCONNECTED) { - mainDlg->PostMessage(UM_CALL_ANSWER, (WPARAM)call_info->id, -486); - } - return NULL; - } - } else { - messagesContact->callId = call_info->id; - } - } - break; - } - } - //--name - if (name.IsEmpty()) { - name = mainDlg->pageContacts->GetNameByNumber(number); - if (name.IsEmpty()) { - CString numberLocal = number; - if (sipuri.name.IsEmpty()) { - name = (sipuri.domain == accountSettings.account.domain ? sipuri.user : numberLocal); - } else { - name = sipuri.name + _T(" (") + (sipuri.domain == accountSettings.account.domain ? sipuri.user : numberLocal) + _T(")"); - } - } - } - if (user_data) { - if (!user_data->diversion.IsEmpty()) { - name.Format(_T("%s -> %s"),user_data->diversion,name); - } - } - //--end name - if (exists==-1) { - if (ifExists) { - return NULL; - } - messagesContact = new MessagesContact(); - messagesContact->callId = call_info ? call_info->id : -1; - messagesContact->number = number; - messagesContact->numberParameters = sipuri.parameters; - messagesContact->name = name; - TCITEM item; - item.mask = TCIF_PARAM | TCIF_TEXT; - name.Format(_T(" %s "), name); - item.pszText=name.GetBuffer(); - item.cchTextMax=0; - item.lParam = (LPARAM)messagesContact; - exists = tab->InsertItem(tab->GetItemCount(),&item); - if (tab->GetCurSel() == exists) { - OnChangeTab(call_info, user_data); - } - } else { - if (messagesContact->callId == -1) { - messagesContact->numberParameters = sipuri.parameters; - } - //--update name (diversion header) - if (call_info) { - if (messagesContact->name != name) { - messagesContact->name = name; - if (tab->GetCurSel() == exists) { - SetWindowText(name); - } - TCITEM item; - item.mask = TCIF_TEXT; - name.Format(_T(" %s "), name); - item.pszText=name.GetBuffer(); - item.cchTextMax=0; - tab->SetItem(exists,&item); - } - } - //-- - if (tab->GetCurSel() == exists && call_info) { - UpdateCallButton(messagesContact->callId != -1, call_info); - } - } - //--update tab icon - if (call_info) { - UpdateTabIcon(messagesContact, exists, call_info, user_data); - } - //-- - - //if (tab->GetCurSel() != exists && (activate || !IsWindowVisible())) - if (tab->GetCurSel() != exists && activate) - { - LONG_PTR result; - OnTcnSelchangingTab(NULL, &result); - tab->SetCurSel(exists); - OnChangeTab(call_info, user_data); - } - if (!IsWindowVisible()) { - if (!notShowWindow) - { - if (!accountSettings.hidden) { - ShowWindow(SW_SHOW); - CRichEditCtrl* richEdit = (CRichEditCtrl*)GetDlgItem(IDC_MESSAGE); - GotoDlgCtrl(richEdit); - } - } - } - return messagesContact; -} - -void MessagesDlg::OnChangeTab(pjsua_call_info *p_call_info, call_user_data *user_data) -{ - //tab->HighlightItem(tab->GetCurSel(),FALSE); - MessagesContact* messagesContact = GetMessageContact(); - pjsua_call_info call_info; - if (messagesContact->callId != -1) { - if (!p_call_info) { - if (pjsua_var.state==PJSUA_STATE_RUNNING && pjsua_call_get_info(messagesContact->callId, &call_info) == PJ_SUCCESS) { - p_call_info = &call_info; - } - } - } - if (messagesContact->hasNewMessages) { - messagesContact->hasNewMessages = false; - UpdateTabIcon(messagesContact,tab->GetCurSel(),p_call_info, user_data); - } - SetWindowText(messagesContact->name); - - if (messagesContact->callId != -1) { - UpdateCallButton(TRUE, p_call_info); - if (accountSettings.singleMode - && p_call_info && (p_call_info->role==PJSIP_ROLE_UAC || - (p_call_info->role==PJSIP_ROLE_UAS && - (p_call_info->state == PJSIP_INV_STATE_CONFIRMED - || p_call_info->state == PJSIP_INV_STATE_CONNECTING) - )) - ) { - SIPURI sipuri; - ParseSIPURI(messagesContact->number, &sipuri); - mainDlg->pageDialer->SetNumber(!sipuri.user.IsEmpty() && sipuri.domain == accountSettings.account.domain ? sipuri.user : messagesContact->number, 1); - } - } else { - UpdateCallButton(); - if (accountSettings.singleMode) { - mainDlg->pageDialer->PostMessage(WM_COMMAND,MAKELPARAM(IDC_CLEAR,0),0); - } - } - - CRichEditCtrl* richEditList = (CRichEditCtrl*)GetDlgItem(IDC_LIST); - CString messages = messagesContact->messages; - EDITSTREAM es; - es.dwCookie = (DWORD_PTR) &messages; - es.pfnCallback = MEditStreamInCallback; - richEditList->StreamIn(SF_RTF, es); - richEditList->PostMessage(WM_VSCROLL, SB_BOTTOM, 0); - - CRichEditCtrl* richEdit = (CRichEditCtrl*)GetDlgItem(IDC_MESSAGE); - richEdit->SetWindowText(messagesContact->message); - int nEnd = richEdit->GetTextLengthEx(GTL_NUMCHARS); - richEdit->SetSel(nEnd, nEnd); -} - -void MessagesDlg::OnTcnSelchangeTab(NMHDR *pNMHDR, LRESULT *pResult) -{ - OnChangeTab(); - *pResult = 0; -} - - -void MessagesDlg::OnTcnSelchangingTab(NMHDR *pNMHDR, LRESULT *pResult) -{ - CRichEditCtrl* richEdit = (CRichEditCtrl*)GetDlgItem(IDC_MESSAGE); - CString str; - int len = richEdit->GetWindowTextLength(); - LPTSTR ptr = str.GetBuffer(len); - richEdit->GetWindowText(ptr,len+1); - str.ReleaseBuffer(); - - MessagesContact* messagesContact = GetMessageContact(); - messagesContact->message = str; - *pResult = 0; -} - -LRESULT MessagesDlg::OnCloseTab(WPARAM wParam,LPARAM lParam) -{ - int i=wParam; - CloseTab(i); - return TRUE; -} - -BOOL MessagesDlg::CloseTab(int i, BOOL safe) -{ - int curSel = tab->GetCurSel(); - - MessagesContact* messagesContact = GetMessageContact(i); - if (messagesContact->callId != -1) - { - if (safe) { - return FALSE; - } - msip_call_hangup_fast(messagesContact->callId); - } - delete messagesContact; - tab->DeleteItem(i); - int count = tab->GetItemCount(); - if (!count) { - GetDlgItem(IDC_LIST)->SetWindowText(_T("")); - GetDlgItem(IDC_MESSAGE)->SetWindowText(_T("")); - OnClose(); - } else { - tab->SetCurSel( curSel < count ? curSel: count-1 ); - OnChangeTab(); - } - return TRUE; -} - -pjsua_call_id MessagesDlg::CallMake(CString number, bool hasVideo, pj_status_t *pStatus, call_user_data *user_data) -{ - pjsua_acc_id acc_id; - pj_str_t pj_uri; - if (!SelectSIPAccount(number,acc_id,pj_uri)) { - Account dummy; - *pStatus = accountSettings.AccountLoad(1,&dummy) ? PJSIP_EAUTHACCDISABLED : PJSIP_EAUTHACCNOTFOUND; - return PJSUA_INVALID_ID; - } - if (accountSettings.singleMode) { - call_hangup_all_noincoming(); - } -#ifdef _GLOBAL_VIDEO - if (hasVideo) { - mainDlg->createPreviewWin(); - } -#endif - - msip_set_sound_device(msip_audio_output); - - pjsua_call_id call_id; - - pjsua_call_setting call_setting; - pjsua_call_setting_default(&call_setting); - call_setting.flag = 0; - call_setting.vid_cnt=hasVideo ? 1 : 0; - - pjsua_msg_data msg_data; - pjsua_msg_data_init(&msg_data); - - /* testing autoanswer - pjsip_generic_string_hdr subject; - pj_str_t hvalue, hname; - //hname = pj_str("X-AUTOANSWER"); - //hvalue = pj_str("TRUE"); - hname = pj_str("Call-Info"); - hvalue = pj_str("answer-after=5"); - pjsip_generic_string_hdr_init2 (&subject, &hname, &hvalue); - pj_list_push_back(&msg_data.hdr_list, &subject); - //*/ - - pj_status_t status = pjsua_call_make_call( - acc_id, - &pj_uri, - &call_setting, - user_data, - &msg_data, - &call_id); - if (pStatus) { - *pStatus = status; - } - return status == PJ_SUCCESS ? call_id : PJSUA_INVALID_ID; -} - -void MessagesDlg::CallStart(bool hasVideo, call_user_data *user_data) -{ - MessagesContact* messagesContact = GetMessageContact(); - pj_status_t status = PJSIP_EINVALIDREQURI; - pjsua_call_id call_id = PJSUA_INVALID_ID; - call_id = CallMake(messagesContact->number + messagesContact->numberParameters,hasVideo, &status, user_data); - if (call_id!=PJSUA_INVALID_ID) { - if (user_data) { - user_data->call_id = call_id; - } - messagesContact->callId = call_id; - UpdateCallButton(TRUE); - } else { - if (status != PJ_ERESOLVE) { - CString message = GetErrorMessage(status); - AddMessage(messagesContact,message); - if (accountSettings.singleMode) { - AfxMessageBox(message); - } - } - } -} - -void MessagesDlg::OnBnClickedCallEnd() -{ - MessagesContact* messagesContact = GetMessageContact(); - if (messagesContact && messagesContact->callId == -1) - { - CallStart(); - } -} - -void MessagesDlg::OnEndCall(pjsua_call_info *call_info) -{ - for (int i = 0; i < tab->GetItemCount(); i++) - { - MessagesContact* messagesContact = GetMessageContact(i); - if (messagesContact->callId == call_info->id) - { - lastCall = messagesContact; - messagesContact->callId = -1; - if (tab->GetCurSel()==i) - { - UpdateCallButton(FALSE, call_info); - } - break; - } - } -} - -void MessagesDlg::UpdateCallButton(BOOL active, pjsua_call_info *call_info) -{ - GetDlgItem(IDC_CALL_END)->ShowWindow(active? SW_HIDE : SW_SHOW); - GetDlgItem(IDC_END)->ShowWindow(!active? SW_HIDE : SW_SHOW); -#ifdef _GLOBAL_VIDEO - GetDlgItem(IDC_VIDEO_CALL)->ShowWindow(active? SW_HIDE : SW_SHOW); -#endif - UpdateHoldButton(call_info); - if (!active) { - if (mainDlg->transferDlg) { - mainDlg->transferDlg->OnClose(); - } - ::SendMessage(m_hWnd,WM_CANCELMODE,0,0); - } -} - -void MessagesDlg::UpdateHoldButton(pjsua_call_info *call_info) -{ - MessagesContact* messagesContact = GetMessageContact(); - if (!messagesContact) { - return; - } - bool hasActions = false; - bool hasHold = false; - bool onHold = false; - CButton* buttonActions = (CButton*)GetDlgItem(IDC_ACTIONS); - CButton* buttonHold = (CButton*)GetDlgItem(IDC_HOLD); - CButton* buttonHoldDialer = (CButton*)mainDlg->pageDialer->GetDlgItem(IDC_HOLD); - CButton* buttonTransferDialer = (CButton*)mainDlg->pageDialer->GetDlgItem(IDC_TRANSFER); - if (messagesContact->callId != -1 && call_info) { - if (messagesContact->callId != call_info->id) { - return; - } - if (call_info->state == PJSIP_INV_STATE_EARLY || - call_info->state == PJSIP_INV_STATE_CONNECTING || - call_info->state == PJSIP_INV_STATE_CONFIRMED) { - hasActions = true; - if (call_info->state == PJSIP_INV_STATE_CONFIRMED) { - hasHold = true; - if (call_info->media_cnt>0) { - if (call_info->media_status == PJSUA_CALL_MEDIA_LOCAL_HOLD - || call_info->media_status == PJSUA_CALL_MEDIA_NONE) { - onHold = true; - } - } - } - } - } - //-- - if (hasActions) { - buttonActions->ShowWindow(SW_SHOW); - buttonTransferDialer->EnableWindow(TRUE); - } else { - buttonActions->ShowWindow(SW_HIDE); - buttonTransferDialer->EnableWindow(FALSE); - } - //-- - if (hasHold) { - buttonHold->ShowWindow(SW_SHOW); - buttonHoldDialer->EnableWindow(TRUE); - } else { - buttonHold->ShowWindow(SW_HIDE); - buttonHoldDialer->EnableWindow(FALSE); - } - //-- - if (onHold) { - buttonHold->SetCheck(TRUE); - buttonHoldDialer->SetCheck(TRUE); - } else { - buttonHold->SetCheck(FALSE); - buttonHoldDialer->SetCheck(FALSE); - } - //-- -} - -bool MessagesDlg::CallCheck() -{ - if (!accountSettings.singleMode || !call_get_count_noincoming()) - { - MessagesContact* messagesContact = GetMessageContact(); - if (!messagesContact || messagesContact->callId == -1) - { - return true; - } - } else { - mainDlg->GotoTab(0); - } - return false; -} - -void MessagesDlg::Call(BOOL hasVideo, CString commands) -{ - if (CallCheck()) { - if (mainDlg->missed) { - mainDlg->missed = false; - } - call_user_data *user_data = new call_user_data(PJSUA_INVALID_ID); - user_data->commands = commands; - CallStart(hasVideo, user_data); - } -} - -void MessagesDlg::AddMessage(MessagesContact* messagesContact, CString message, int type, BOOL blockForeground) -{ - CTime tm = CTime::GetCurrentTime(); - - if (type == MSIP_MESSAGE_TYPE_SYSTEM) { - if ( messagesContact->lastSystemMessage == message && messagesContact->lastSystemMessageTime > tm.GetTime()-2) { - messagesContact->lastSystemMessageTime = tm; - return; - } - messagesContact->lastSystemMessage = message; - messagesContact->lastSystemMessageTime = tm; - } else if (!messagesContact->lastSystemMessage.IsEmpty()) { - messagesContact->lastSystemMessage.Empty(); - } - - if (IsWindowVisible() && !blockForeground) { - SetForegroundWindow(); - } - CRichEditCtrl richEdit; - MessagesContact* messagesContactSelected = GetMessageContact(); - - CRichEditCtrl *richEditList = (CRichEditCtrl *)GetDlgItem(IDC_LIST); - if (messagesContactSelected != messagesContact) { - CRect rect; - rect.left = 0; - rect.top = 0; - rect.right = 300; - rect.bottom = 300; - richEdit.Create(ES_MULTILINE | ES_READONLY | ES_NUMBER | WS_VSCROLL, rect, this, NULL); - richEdit.SetFont(&fontList); - - CString messages = messagesContact->messages; - EDITSTREAM es; - es.dwCookie = (DWORD_PTR) &messages; - es.pfnCallback = MEditStreamInCallback; - richEdit.StreamIn(SF_RTF, es); - - richEditList = &richEdit; - } - - if (messagesContact->messages.IsEmpty()) { - richEditList->SetSel(0,-1); - richEditList->SetParaFormat(para); - } - - COLORREF color; - CString name; - if (type==MSIP_MESSAGE_TYPE_LOCAL) { - color = RGB (0,0,0); - if (!accountSettings.account.displayName.IsEmpty()) { - name = accountSettings.account.displayName; - } - } else if (type==MSIP_MESSAGE_TYPE_REMOTE) { - color = RGB (21,101,206); - name = messagesContact->name; - int pos = name.Find(_T(" (")); - if (pos==-1) { - pos = name.Find(_T("@")); - } - if (pos!=-1) { - name = name.Mid(0,pos); - } - } - - int nBegin; - CHARFORMAT cf; - CString str; - - CString time = tm.Format(_T("%X")); - - nBegin = richEditList->GetTextLengthEx(GTL_NUMCHARS); - richEditList->SetSel(nBegin, nBegin); - str.Format(_T("[%s] "),time); - richEditList->ReplaceSel( str ); - cf.dwMask = CFM_BOLD | CFM_COLOR | CFM_SIZE; - cf.crTextColor = RGB (131,131,131); - cf.dwEffects = 0; - cf.yHeight = 160; - richEditList->SetSel(nBegin,-1); - richEditList->SetSelectionCharFormat(cf); - - if (type != MSIP_MESSAGE_TYPE_SYSTEM) { - cf.yHeight = 200; - } - if (name.GetLength()) { - nBegin = richEditList->GetTextLengthEx(GTL_NUMCHARS); - richEditList->SetSel(nBegin, nBegin); - richEditList->ReplaceSel( name + _T(": ")); - cf.dwMask = CFM_BOLD | CFM_COLOR | CFM_SIZE; - cf.crTextColor = color; - cf.dwEffects = CFE_BOLD; - richEditList->SetSel(nBegin,-1); - richEditList->SetSelectionCharFormat(cf); - } - - nBegin = richEditList->GetTextLengthEx(GTL_NUMCHARS); - richEditList->SetSel(nBegin, nBegin); - richEditList->ReplaceSel(message+_T("\r\n")); - cf.dwMask = CFM_BOLD | CFM_COLOR | CFM_SIZE; - - cf.crTextColor = type == MSIP_MESSAGE_TYPE_SYSTEM ? RGB (131, 131, 131) : color; - cf.dwEffects = 0; - - richEditList->SetSel(nBegin,-1); - richEditList->SetSelectionCharFormat(cf); - - int selectedIndex = -1; - if (messagesContactSelected == messagesContact) { - richEditList->PostMessage(WM_VSCROLL, SB_BOTTOM, 0); - selectedIndex = tab->GetCurSel(); - } else { - if (type == MSIP_MESSAGE_TYPE_REMOTE) { - messagesContact->hasNewMessages = true; - UpdateTabIcon(messagesContact); - } - /* - for (int i = 0; i < tab->GetItemCount(); i++) { - if (messagesContact == GetMessageContact(i)) - { - tab->HighlightItem(i, TRUE); - break; - } - } - */ - } - str=_T(""); - EDITSTREAM es; - es.dwCookie = (DWORD_PTR) &str; - es.pfnCallback = MEditStreamOutCallback; - richEditList->StreamOut(SF_RTF, es); - messagesContact->messages=str; -} - -void MessagesDlg::OnEnMsgfilterMessage(NMHDR *pNMHDR, LRESULT *pResult) -{ - MSGFILTER *pMsgFilter = reinterpret_cast(pNMHDR); - - if (pMsgFilter->msg == WM_CHAR) { - if ( pMsgFilter->wParam == VK_RETURN ) { - CRichEditCtrl* richEdit = (CRichEditCtrl*)GetDlgItem(IDC_MESSAGE); - CString message; - int len = richEdit->GetWindowTextLength(); - LPTSTR ptr = message.GetBuffer(len); - richEdit->GetWindowText(ptr,len+1); - message.ReleaseBuffer(); - message.Trim(); - if (message.GetLength()) { - MessagesContact* messagesContact = GetMessageContact(); - if (SendInstantMessage (messagesContact,message) ) { - richEdit->SetWindowText(_T("")); - GotoDlgCtrl(richEdit); - AddMessage(messagesContact, message, MSIP_MESSAGE_TYPE_LOCAL); - if (accountSettings.localDTMF) { - mainDlg->onPlayerPlay(MSIP_SOUND_MESSAGE_OUT,0); - } - } - } - *pResult= 1; - return; - } - } - *pResult = 0; -} - -BOOL MessagesDlg::SendInstantMessage(MessagesContact* messagesContact, CString message, CString number) -{ - message.Trim(); - if (message.GetLength()) { - pjsua_acc_id acc_id; - pj_str_t pj_uri; - pj_status_t status; - if (SelectSIPAccount(messagesContact ? messagesContact->number + messagesContact->numberParameters : number, acc_id, pj_uri)) { - pj_str_t pj_message = StrToPjStr(message); - status = pjsua_im_send(acc_id, &pj_uri, NULL, &pj_message, NULL, NULL); - } - else { - Account dummy; - status = accountSettings.AccountLoad(1, &dummy) ? PJSIP_EAUTHACCDISABLED : PJSIP_EAUTHACCNOTFOUND; - } - if (status != PJ_SUCCESS) { - if (messagesContact) { - CString message = GetErrorMessage(status); - AddMessage(messagesContact, message); - } - } - else { - return TRUE; - } - } - return FALSE; -} - -MessagesContact* MessagesDlg::GetMessageContact(int i) -{ - if (i ==-1) { - i = tab->GetCurSel(); - } - if (i != -1) { - TCITEM item; - item.mask = TCIF_PARAM; - tab->GetItem(i, &item); - return (MessagesContact*) item.lParam; - } - return NULL; -} -void MessagesDlg::OnBnClickedVideoCall() -{ - CallStart(true); -} - -void MessagesDlg::CallAction(int action, CString number) -{ - MessagesContact* messagesContactSelected = mainDlg->messagesDlg->GetMessageContact(); - if (!messagesContactSelected || messagesContactSelected->callId == -1) { - return; - } - number.Trim(); - if (!number.IsEmpty()) { - pj_str_t pj_uri = StrToPjStr(GetSIPURI(number, true)); - call_user_data *user_data; - user_data = (call_user_data *)pjsua_call_get_user_data(messagesContactSelected->callId); - if (action == MSIP_ACTION_TRANSFER) { - if (!user_data || !user_data->inConference) { - pjsua_call_xfer(messagesContactSelected->callId, &pj_uri, NULL); - } - } - if (action == MSIP_ACTION_INVITE) { - MessagesContact *messagesContact = mainDlg->messagesDlg->AddTab(FormatNumber(number), _T(""), TRUE, NULL, NULL, TRUE); - if (messagesContact->callId == -1) { - pjsua_call_info call_info; - pjsua_call_get_info(messagesContactSelected->callId, &call_info); - msip_call_unhold(&call_info); - if (!user_data) { - user_data = new call_user_data(messagesContactSelected->callId); - pjsua_call_set_user_data(messagesContactSelected->callId, user_data); - } - user_data->inConference = true; - - user_data = new call_user_data(PJSUA_INVALID_ID); - user_data->inConference = true; - mainDlg->messagesDlg->CallStart(false, user_data); - } - } - } -} - -void MessagesDlg::OnBnClickedHold() -{ - MessagesContact* messagesContact = GetMessageContact(); - if (!messagesContact || messagesContact->callId==-1) { - return; - } - pjsua_call_info call_info; - pjsua_call_get_info(messagesContact->callId,&call_info); - if (call_info.state == PJSIP_INV_STATE_CONFIRMED) { - if (call_info.media_status == PJSUA_CALL_MEDIA_LOCAL_HOLD || call_info.media_status == PJSUA_CALL_MEDIA_NONE) { - msip_call_unhold(&call_info); - } else { - msip_call_hold(&call_info); - } - } -} - -void MessagesDlg::OnBnClickedActions() -{ - MessagesContact* messagesContact = GetMessageContact(); - if (!messagesContact || messagesContact->callId==-1) { - return; - } - CMenu *tracker = menuActions.GetSubMenu(0); - pjsua_call_info call_info; - if (pjsua_call_get_info(messagesContact->callId, &call_info) != PJ_SUCCESS) { - return; - } - call_user_data *user_data = (call_user_data *) pjsua_call_get_user_data(messagesContact->callId); - bool inConference = user_data && user_data->inConference; - //-- transfer - tracker->EnableMenuItem(ID_TRANSFER,!inConference?0:MF_GRAYED); - //-- attended transfer & merge - while (menuAttendedTransfer.DeleteMenu(0, MF_BYPOSITION)); - while (menuMerge.DeleteMenu(0, MF_BYPOSITION)); - pjsua_call_id call_ids[PJSUA_MAX_CALLS]; - unsigned calls_count = PJSUA_MAX_CALLS; - int pos = 0; - int posMerge = 0; - pjsua_call_id mergeConferenceAddedId = PJSUA_INVALID_ID; - if (pjsua_enum_calls ( call_ids, &calls_count)==PJ_SUCCESS) { - for (unsigned i = 0; i < calls_count; ++i) { - if (call_ids[i] != messagesContact->callId) { - pjsua_call_info call_info_curr; - pjsua_call_get_info(call_ids[i], &call_info_curr); - call_user_data *user_data_curr = (call_user_data *) pjsua_call_get_user_data(call_ids[i]); - bool inConferenceCurr = user_data_curr && user_data_curr->inConference; - CString str; - //--attended transfer - if (call_info_curr.role == PJSIP_ROLE_UAS || call_info_curr.state == PJSIP_INV_STATE_CONFIRMED) { - SIPURI sipuri_curr; - ParseSIPURI(PjToStr(&call_info_curr.remote_info, TRUE), &sipuri_curr); - str = !sipuri_curr.name.IsEmpty()?sipuri_curr.name:(!sipuri_curr.user.IsEmpty()?sipuri_curr.user:(sipuri_curr.domain)); - if (!inConference && !inConferenceCurr) { - menuAttendedTransfer.InsertMenu(pos, MF_BYPOSITION, ID_ATTENDED_TRANSFER_RANGE+pos, str); - MENUITEMINFO mii; - mii.cbSize = sizeof (MENUITEMINFO); - mii.fMask = MIIM_DATA; - mii.dwItemData = call_ids[i]; - menuAttendedTransfer.SetMenuItemInfo(pos,&mii,TRUE); - pos++; - } - } - //--merge - if (call_info.state == PJSIP_INV_STATE_CONFIRMED && call_info_curr.state == PJSIP_INV_STATE_CONFIRMED) { - if (!inConference || !inConferenceCurr) { - if (!inConferenceCurr || mergeConferenceAddedId==PJSUA_INVALID_ID) { - MENUITEMINFO mii; - mii.cbSize = sizeof (MENUITEMINFO); - mii.fMask = MIIM_DATA; - mii.dwItemData = call_ids[i]; - if (inConferenceCurr) { - str = Translate(_T("Conference")); - mergeConferenceAddedId = call_ids[i]; - } - menuMerge.InsertMenu(posMerge, MF_BYPOSITION, ID_MERGE_RANGE+posMerge, str); - menuMerge.SetMenuItemInfo(posMerge,&mii,TRUE); - posMerge++; - } - } - } - //-- - } - } - } - tracker->EnableMenuItem(ID_ATTENDED_TRANSFER,menuAttendedTransfer.GetMenuItemCount()?0:MF_GRAYED); - if (!inConference && mergeConferenceAddedId!=PJSUA_INVALID_ID && menuMerge.GetMenuItemCount()>1) { - // only 1 conference allowed, remove all regular calls - while (menuMerge.DeleteMenu(0, MF_BYPOSITION)); - MENUITEMINFO mii; - mii.cbSize = sizeof (MENUITEMINFO); - mii.fMask = MIIM_DATA; - mii.dwItemData = mergeConferenceAddedId; - menuMerge.InsertMenu(0, MF_BYPOSITION, ID_MERGE_RANGE, Translate(_T("Conference"))); - menuMerge.SetMenuItemInfo(0,&mii,TRUE); - } - tracker->EnableMenuItem(ID_MERGE,menuMerge.GetMenuItemCount()?0:MF_GRAYED); - //-- invite in conference - tracker->EnableMenuItem(ID_CONFERENCE,call_info.state==PJSIP_INV_STATE_CONFIRMED&&(inConference||mergeConferenceAddedId==PJSUA_INVALID_ID)?0:MF_GRAYED); - //-- separate & disconnect - tracker->EnableMenuItem(ID_SEPARATE,inConference?0:MF_GRAYED); - tracker->EnableMenuItem(ID_DISCONNECT,inConference?0:MF_GRAYED); - //-- - CPoint point; - GetCursorPos(&point); - tracker->TrackPopupMenu( 0, point.x, point.y, this ); -} - -void MessagesDlg::OnTransfer() -{ - if (!mainDlg->transferDlg) { - mainDlg->transferDlg = new Transfer(this); - } - mainDlg->transferDlg->SetAction(MSIP_ACTION_TRANSFER); - mainDlg->transferDlg->SetForegroundWindow(); -} - -void MessagesDlg::OnAttendedTransfer(UINT nID) -{ - int pos = nID - ID_ATTENDED_TRANSFER_RANGE; - MENUITEMINFO mii; - mii.cbSize = sizeof (MENUITEMINFO); - mii.fMask = MIIM_DATA; - menuAttendedTransfer.GetMenuItemInfo(pos, &mii, TRUE); - pjsua_call_id call_id = mii.dwItemData; - - MessagesContact* messagesContact = GetMessageContact(); - if (!messagesContact || messagesContact->callId == -1) { - return; - } - if (!pjsua_call_is_active(call_id)) { - return; - } - pjsua_call_xfer_replaces(messagesContact->callId,call_id,0,0); -} - -void MessagesDlg::OnConference() -{ - if (!mainDlg->transferDlg) { - mainDlg->transferDlg = new Transfer(this); - } - mainDlg->transferDlg->SetAction(MSIP_ACTION_INVITE); - mainDlg->transferDlg->SetForegroundWindow(); -} - -void MessagesDlg::OnMerge(UINT nID) -{ - int pos = nID - ID_MERGE_RANGE; - MENUITEMINFO mii; - mii.cbSize = sizeof (MENUITEMINFO); - mii.fMask = MIIM_DATA; - menuMerge.GetMenuItemInfo(pos, &mii, TRUE); - pjsua_call_id call_id = mii.dwItemData; - - MessagesContact* messagesContact = GetMessageContact(); - if (!messagesContact || messagesContact->callId == -1) { - return; - } - if (!pjsua_call_is_active(call_id)) { - return; - } - call_user_data *user_data; - user_data = (call_user_data *) pjsua_call_get_user_data(messagesContact->callId); - if (!user_data) { - user_data = new call_user_data(messagesContact->callId); - pjsua_call_set_user_data(messagesContact->callId,user_data); - } - user_data->inConference = true; - - user_data = (call_user_data *) pjsua_call_get_user_data(call_id); - if (!user_data) { - user_data = new call_user_data(messagesContact->callId); - pjsua_call_set_user_data(messagesContact->callId,user_data); - } - user_data->inConference = true; - - pjsua_call_info call_info; - if (pjsua_call_get_info(call_id, &call_info) != PJ_SUCCESS) { - return; - } - msip_conference_join(&call_info); - msip_call_unhold(&call_info); -} - -void MessagesDlg::OnSeparate() -{ - MessagesContact* messagesContact = GetMessageContact(); - if (!messagesContact || messagesContact->callId==-1) { - return; - } - pjsua_call_info call_info; - if (pjsua_call_get_info(messagesContact->callId, &call_info) != PJ_SUCCESS) { - return; - } - msip_conference_leave(&call_info); - msip_call_unhold(&call_info); -} - -void MessagesDlg::OnDisconnect() -{ - MessagesContact* messagesContact = GetMessageContact(); - if (!messagesContact || messagesContact->callId == -1) { - return; - } - msip_call_hangup_fast(messagesContact->callId); -} - -void MessagesDlg::OnBnClickedEnd() -{ - MessagesContact* messagesContact = GetMessageContact(); - if (!messagesContact || messagesContact->callId==-1) { - return; - } - msip_call_end(messagesContact->callId); -} - -void MessagesDlg::OnCloseAllTabs() -{ - int i = 0; - while (i < tab->GetItemCount()) { - if (CloseTab(i,TRUE)) { - i = 0; - } else { - i++; - } - } -} - -void MessagesDlg::OnGoToLastTab() -{ - int i = 0; - BOOL found = FALSE; - int lastCallIndex = -1; - while (i < tab->GetItemCount()) { - MessagesContact* messagesContact = GetMessageContact(i); - if (messagesContact->callId != -1) { - found = TRUE; - if (tab->GetCurSel() != i) { - LONG_PTR result; - OnTcnSelchangingTab(NULL, &result); - tab->SetCurSel(i); - OnChangeTab(); - break; - } - } - if (messagesContact == lastCall) { - lastCallIndex = i; - } - i++; - } - if (!found && lastCallIndex!=-1) { - if (tab->GetCurSel() != lastCallIndex) { - LONG_PTR result; - OnTcnSelchangingTab(NULL, &result); - tab->SetCurSel(lastCallIndex); - OnChangeTab(); - } - } -} - -int MessagesDlg::GetCallDuration(pjsua_call_id *call_id) -{ - int duration = -1; - pjsua_call_info call_info; - int i = 0; - while (i < tab->GetItemCount()) { - MessagesContact* messagesContact = GetMessageContact(i); - if (messagesContact->callId != -1) { - if (pjsua_var.state==PJSUA_STATE_RUNNING && pjsua_call_get_info(messagesContact->callId, &call_info)==PJ_SUCCESS) { - if (call_info.state == PJSIP_INV_STATE_CONFIRMED) { - duration = call_info.connect_duration.sec; - *call_id = messagesContact->callId; - } - } - } - i++; - } - return duration; -} - -void MessagesDlg::OnCopy() -{ - CRichEditCtrl* richEditList = (CRichEditCtrl*)GetDlgItem(IDC_LIST); - richEditList->Copy(); -} - -void MessagesDlg::OnSelectAll() -{ - CRichEditCtrl* richEditList = (CRichEditCtrl*)GetDlgItem(IDC_LIST); - richEditList->SetSel(0,-1); -} - -void MessagesDlg::OnBnClickedCloseAll() -{ - OnCloseAllTabs(); -} - -void MessagesDlg::OnBnClickedLastCall() -{ - OnGoToLastTab(); -} - -void MessagesDlg::UpdateTabIcon(MessagesContact* messagesContact, int tabIndex, pjsua_call_info *p_call_info, call_user_data *user_data) -{ - if (tabIndex==-1) { - for (int i = 0; i < tab->GetItemCount(); i++) { - if (messagesContact == GetMessageContact(i)) { - tabIndex = i; - break; - } - } - } - if (tabIndex==-1) { - return; - } - int icon = -1; - if (messagesContact->hasNewMessages) { - icon = MSIP_TAB_ICON_MESSAGE_IN; - } else if (p_call_info) { - //----------------- - switch (p_call_info->state) { - case PJSIP_INV_STATE_NULL: - case PJSIP_INV_STATE_DISCONNECTED: - if (p_call_info->role == PJSIP_ROLE_UAS && !p_call_info->connect_duration.sec && !p_call_info->connect_duration.msec) { - icon = MSIP_TAB_ICON_CALL_MISS; - } - break; - case PJSIP_INV_STATE_CONFIRMED: - if (p_call_info->media_status == PJSUA_CALL_MEDIA_LOCAL_HOLD || p_call_info->media_status == PJSUA_CALL_MEDIA_NONE) { - icon = MSIP_TAB_ICON_ON_HOLD; - } else { - if (!user_data) { - user_data = (call_user_data *) pjsua_call_get_user_data(p_call_info->id); - } - if (p_call_info->media_status == PJSUA_CALL_MEDIA_REMOTE_HOLD) { - if (user_data && user_data->inConference) { - icon = MSIP_TAB_ICON_ON_REMOTE_HOLD_CONFERENCE; - } else { - icon = MSIP_TAB_ICON_ON_REMOTE_HOLD; - } - } else { - if (user_data && user_data->inConference) { - if (user_data->srtp == MSIP_SRTP) { - icon = MSIP_TAB_ICON_CONFERENCE_SECURE; - } else { - icon = MSIP_TAB_ICON_CONFERENCE; - } - } else { - if (user_data && user_data->srtp == MSIP_SRTP) { - icon = MSIP_TAB_ICON_ACTIVE_SECURE; - } else { - icon = MSIP_TAB_ICON_ACTIVE; - } - } - } - } - break; - default: - if (p_call_info->role == PJSIP_ROLE_UAS) { - icon = MSIP_TAB_ICON_CALL_IN; - } else { - icon = MSIP_TAB_ICON_CALL_OUT; - } - break; - } - //----------------- - } - TCITEM item; - item.mask = TCIF_IMAGE; - item.iImage = icon; - tab->SetItem(tabIndex,&item); -} diff --git a/microsip/MessagesDlg.h b/microsip/MessagesDlg.h deleted file mode 100644 index 97534a78..00000000 --- a/microsip/MessagesDlg.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#pragma once - -#include "resource.h" -#include "global.h" -#include "ClosableTabCtrl.h" -#include "BaseDialog.h" - -#include -#include - -enum { - MSIP_TAB_ICON_CALL_OUT, - MSIP_TAB_ICON_CALL_IN, - MSIP_TAB_ICON_CALL_MISS, - MSIP_TAB_ICON_ACTIVE, - MSIP_TAB_ICON_ACTIVE_SECURE, - MSIP_TAB_ICON_CONFERENCE, - MSIP_TAB_ICON_CONFERENCE_SECURE, - MSIP_TAB_ICON_MESSAGE_IN, - MSIP_TAB_ICON_ON_HOLD, - MSIP_TAB_ICON_ON_REMOTE_HOLD, - MSIP_TAB_ICON_ON_REMOTE_HOLD_CONFERENCE -}; - -class MessagesDlg : - public CBaseDialog -{ - CFont fontList; - CFont fontMessage; - PARAFORMAT2 para; - CClosableTabCtrl tabComponent; - CImageList imageList; -public: - - MessagesDlg(CWnd* pParent = NULL); // standard constructor - ~MessagesDlg(); - enum { IDD = IDD_MESSAGES }; - - MessagesContact* AddTab(CString number, CString name = CString(), BOOL activate = FALSE, pjsua_call_info *call_info = NULL, call_user_data *user_data = NULL, BOOL notShowWindow = FALSE, BOOL ifExists = FALSE); - void OnChangeTab(pjsua_call_info *p_call_info = NULL, call_user_data *user_data = NULL); - void OnEndCall(pjsua_call_info *call_info); - bool CallCheck(); - void Call(BOOL hasVideo = FALSE, CString commands=_T("")); - pjsua_call_id CallMake(CString number, bool hasVideo = false, pj_status_t *pStatus = NULL, call_user_data *user_data = NULL); - void CallStart(bool hasVideo = false, call_user_data *user_data = NULL); - void AddMessage(MessagesContact* messagesContact, CString message, int type = MSIP_MESSAGE_TYPE_SYSTEM, BOOL blockForeground = FALSE); - MessagesContact* GetMessageContact(int i = -1); - int GetCallDuration(pjsua_call_id *call_id = NULL); - BOOL SendInstantMessage(MessagesContact* messagesContact, CString message, CString number = _T("")); - void UpdateHoldButton(pjsua_call_info *call_info); - void UpdateTabIcon(MessagesContact* messagesContact, int tabIndex=-1, pjsua_call_info *call_info=NULL, call_user_data *user_data = NULL); - void CallAction(int action, CString number); - - CClosableTabCtrl* tab; - MessagesContact* lastCall; - - HICON m_hIconDropDown; - HICON m_hIconHold; - -private: - void UpdateCallButton(BOOL active = FALSE, pjsua_call_info *call_info = NULL); - BOOL CloseTab(int i, BOOL safe = FALSE); - - CMenu menuActions; - CMenu menuAttendedTransfer; - CMenu menuMerge; - -protected: - afx_msg void OnDestroy(); - virtual BOOL OnInitDialog(); - virtual void PostNcDestroy(); - virtual void DoDataExchange(CDataExchange* pDX); - DECLARE_MESSAGE_MAP() -public: - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnClose(); - afx_msg void OnMove(int x, int y); - afx_msg void OnSize(UINT type, int w, int h); - afx_msg void OnCancel(); - afx_msg void OnBnClickedOk(); - afx_msg void OnSysCommand(UINT nID, LPARAM lParam); - afx_msg LRESULT OnContextMenu(WPARAM wParam,LPARAM lParam); - afx_msg void OnEnMsgfilterMessage(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnTcnSelchangeTab(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnTcnSelchangingTab(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg LRESULT OnCloseTab(WPARAM wParam,LPARAM lParam); - afx_msg void OnBnClickedCallEnd(); - afx_msg void OnBnClickedVideoCall(); - afx_msg void OnBnClickedActions(); - afx_msg void OnBnClickedHold(); - afx_msg void OnBnClickedEnd(); - afx_msg void OnCloseAllTabs(); - afx_msg void OnGoToLastTab(); - afx_msg void OnBnClickedCloseAll(); - afx_msg void OnBnClickedLastCall(); - afx_msg void OnCopy(); - afx_msg void OnSelectAll(); - - afx_msg void OnTransfer(); - afx_msg void OnAttendedTransfer(UINT nID); - afx_msg void OnConference(); - afx_msg void OnMerge(UINT nID); - afx_msg void OnSeparate(); - afx_msg void OnDisconnect(); -}; \ No newline at end of file diff --git a/microsip/ModelessMessageBox.cpp b/microsip/ModelessMessageBox.cpp deleted file mode 100644 index 20a8732a..00000000 --- a/microsip/ModelessMessageBox.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "StdAfx.h" -#include "ModelessMessageBox.h" - -void ModelessMessageBox( HWND hWnd /*= NULL*/, LPCTSTR lpText /*= L""*/, LPCTSTR lpCaption /*= L""*/, UINT uType /*= MB_OK */ ) -{ - _ModelessMessageBox::Show(hWnd /*= NULL*/, - lpText/* = L""*/, - lpCaption /*= L""*/, - uType/* = MB_OK*/ - ); -} \ No newline at end of file diff --git a/microsip/ModelessMessageBox.h b/microsip/ModelessMessageBox.h deleted file mode 100644 index 7a11099b..00000000 --- a/microsip/ModelessMessageBox.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -/******************************************************************** -created: 2008/11/23 -created: 23:11:2008 11:16 -filename: ModelessMessageBox.h -file path: -file base: ModelessMessageBox -file ext: h -author: Shay - -purpose: Creating a message box not on the stack, without -Stopping the code flow. -Using thread and message box data on the heap. -usage: ModelessMessageBox(NULL, sEvent, L"Debug events form menu", MB_OK); - -*********************************************************************/ -class _ModelessMessageBox -{ -protected: - struct MessageData - { - HWND hWnd; - CString lpText; - CString lpCaption; - UINT uType; - }; - static DWORD WINAPI DoMessageBoxThreadProc(LPVOID lpParameter) - { - if(lpParameter == NULL) - return 1L; - MessageData * pData= static_cast(lpParameter); - if (NULL == pData ) - return 1L; - //else - ::MessageBox(pData->hWnd, pData->lpText, pData->lpCaption, pData->uType); - delete pData; - return 0L; - - } - -public: - - static void Show( HWND hWnd = NULL, - LPCTSTR lpText = _T(""), - LPCTSTR lpCaption = _T(""), - UINT uType = MB_OK - ) - { - - MessageData * pMessageData = new MessageData; - - pMessageData->hWnd= hWnd; - pMessageData->lpText = lpText; - pMessageData->lpCaption = lpCaption; - pMessageData->uType = uType; - LPDWORD threadId = 0; - CreateThread(NULL, 0, DoMessageBoxThreadProc, pMessageData/*(LPVOID)&m_messageData*/, 0, threadId); - } - -}; - -void ModelessMessageBox(HWND hWnd = NULL, - LPCTSTR lpText = _T(""), - LPCTSTR lpCaption = _T(""), - UINT uType = MB_OK - ); diff --git a/microsip/Preview.cpp b/microsip/Preview.cpp deleted file mode 100644 index 8191b4d8..00000000 --- a/microsip/Preview.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "Preview.h" - -#ifdef _GLOBAL_VIDEO - -#include "langpack.h" -#include "mainDlg.h" -#include "settings.h" - -Preview::~Preview(void) -{ -} - -int Preview::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (langPack.rtl) { - ModifyStyleEx(0,WS_EX_LAYOUTRTL); - } - return 0; -} - -Preview::Preview(CWnd* pParent) -{ - CString strClass = AfxRegisterWndClass( - CS_HREDRAW|CS_VREDRAW, - 0, - (HBRUSH)COLOR_GRAYTEXT - ); - CreateEx(WS_EX_TOPMOST, strClass, Translate(_T("Local Video")), - WS_CAPTION | WS_POPUPWINDOW | WS_MINIMIZEBOX, - CRect(0, 0, 640, 480), - AfxGetMainWnd(), NULL); - widx = PJMEDIA_VID_DEFAULT_CAPTURE_DEV; -} - -BEGIN_MESSAGE_MAP(Preview, CWnd) - ON_WM_CREATE() - ON_WM_CLOSE() - ON_WM_DESTROY() -END_MESSAGE_MAP() - -void Preview::OnClose() -{ - DestroyWindow(); -} - -void Preview::OnDestroy() -{ - mainDlg->previewWin = NULL; - if (pj_ready) { - pjsua_vid_preview_stop(widx); - } - CWnd::OnDestroy(); -} - -void Preview::PostNcDestroy() -{ - CWnd::PostNcDestroy(); - delete this; -} - -void Preview::Start(int id) -{ - pjsua_vid_win_info wi; - pjsua_vid_win_id wid = pjsua_vid_preview_get_win(widx); - if (wid != PJSUA_INVALID_ID) { - if (widx != id) { - pjsua_vid_preview_stop(widx); - } else { - return; - } - } - widx = id; - - pjsua_vid_preview_param pre_param; - pj_status_t status; - const pjmedia_coord pos = {0, 0}; - - pjsua_vid_preview_param_default(&pre_param); - pre_param.show = PJ_FALSE; - status = pjsua_vid_preview_start(widx, &pre_param); - if (status != PJ_SUCCESS) { - OnClose(); - return; - } - wid = pjsua_vid_preview_get_win(widx); - pjsua_vid_win_get_info(wid, &wi); - - CRect rcClient, rcWind; - POINT ptDiff; - GetClientRect(&rcClient); - GetWindowRect(&rcWind); - ptDiff.x = (rcWind.right - rcWind.left) - rcClient.right; - ptDiff.y = (rcWind.bottom - rcWind.top) - rcClient.bottom; - CRect screenRect; - SystemParametersInfo(SPI_GETWORKAREA,0,&screenRect,0); - //int w = wi.size.w + ptDiff.x; - //int h = wi.size.h + ptDiff.y; - int w = 320 + ptDiff.x; - int h = 240 + ptDiff.y; - int x = screenRect.Width() - w; - int y = ptDiff.y - 6; - SetWindowPos(NULL, x, y, w, h, SWP_NOZORDER|SWP_SHOWWINDOW); - - pjsua_vid_win_set_pos(wid,&pos); - - pjsua_vid_win_set_show(wid, PJ_TRUE); - - const pjmedia_rect_size size = {320, 240}; - pjsua_vid_win_set_size( wid, &size); - - ::SetParent((HWND)wi.hwnd.info.win.hwnd,this->m_hWnd); -} -#endif \ No newline at end of file diff --git a/microsip/Preview.h b/microsip/Preview.h deleted file mode 100644 index 13d48f65..00000000 --- a/microsip/Preview.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#pragma once - -#include "const.h" - -#ifdef _GLOBAL_VIDEO - -#include "resource.h" -#include -#include - -class Preview: public CWnd -{ -public: - Preview(CWnd* pParent = NULL); - ~Preview(); - void Start(int id); -private: - pjmedia_vid_dev_index widx; -protected: - afx_msg void OnDestroy(); - virtual void PostNcDestroy(); - DECLARE_MESSAGE_MAP() - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnClose(); -}; - -#endif \ No newline at end of file diff --git a/microsip/Resource.h b/microsip/Resource.h deleted file mode 100644 index fc625d5f..00000000 --- a/microsip/Resource.h +++ /dev/null @@ -1,376 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by main.rc -// - -#include "const.h" - -#define IDD_MAIN 102 -#define IDS_STATUSBAR 103 -#define IDS_STATUSBAR2 104 -#define IDR_MAINFRAME 127 -#define IDI_ICON1 128 -#define IDR_MENU_CONTACT 129 -#define IDR_MENU_MESSAGES 130 -#define IDR_MENU_TABS 131 -#define IDD_ACCOUNT 133 -#define IDD_ACCOUNT_CUSTOM 134 -#define IDD_ACCOUNT_PIN 135 -#define IDD_ACCOUNT_REG 136 -#define IDD_ADD 137 -#define IDD_BUTTONS 138 -#define IDD_CALLS 139 -#define IDD_CONFERNCE 140 -#define IDD_CONTACTS 141 -#define IDD_DIALER 142 -#define IDD_MESSAGES 143 -#define IDD_REG_STEP1 144 -#define IDD_REG_STEP2 145 -#define IDD_REG_STEP3 146 -#define IDD_RINGIN 147 -#define IDD_SETTINGS 148 -#define IDD_TRANSFER 149 -#define IDI_ACTIVE 150 -#define IDI_AWAY 152 -#define IDI_BLANK 153 -#define IDI_BUSY 154 -#define IDI_CALL_IN 155 -#define IDI_CALL_MISS 156 -#define IDI_CALL_OUT 157 -#define IDI_CLOSE 158 -#define IDI_CLOSE_2 159 -#define IDI_DEFAULT 160 -#define IDI_END 161 -#define IDI_EXIT 162 -#define IDI_HOLD 163 -#define IDI_INACTIVE 164 -#define IDI_LOGO 165 -#define IDI_MESSAGE 166 -#define IDI_MUTE 167 -#define IDI_MUTE_INPUT 168 -#define IDI_MUTE_OUTPUT 169 -#define IDI_MUTED 170 -#define IDI_MUTED_INPUT 171 -#define IDI_MUTED_OUTPUT 172 -#define IDI_OFFLINE 173 -#define IDI_ONLINE 174 -#define IDI_TRAY 176 -#define IDI_UNKNOWN 177 -#define IDI_VIDEO 178 -#define IDB_DOWNARROW 179 -#define IDB_UPARROW 180 -#define IDI_SEARCH 181 -#define IDI_CLEAR 182 -#define IDT_LANGPACK 183 -#define IDI_SECURE 184 -#define IDI_ACTIVE_SECURE 185 -#define IDI_CONFERENCE_SECURE 186 -#define IDI_CONFERENCE 187 -#define IDI_DROPDOWN 188 -#define IDR_MENU_CALL_ACTIONS 189 -#define IDI_MESSAGE_IN 190 -#define IDI_ON_HOLD 191 -#define IDI_ON_REMOTE_HOLD 192 -#define IDI_ON_REMOTE_HOLD_CONFERENCE 193 -#define IDD_CHANGE_PASSWORD 194 -#define IDD_SHORTCUTS 195 -#define IDI_TRANSFER 196 -#define IDI_MAIN_PHONE 197 -#define IDI_MAIN_LOGS 198 -#define IDI_MAIN_CONTACTS 199 -#define IDI_MAIN_SHORTCUTS 200 -#define IDI_MENU 201 -#define IDI_ON_THE_PHONE 202 -#define IDD_CLI_CERT 203 -#define IDB_VMAIL 204 -#define IDB_VMAIL_FOCUS 205 -#define IDB_VMAIL_DOWN 206 -#define IDB_VMAIL_GREY 207 -#define IDB_VMAIL_GREY_FOCUS 208 -#define IDB_VMAIL_GREY_DOWN 209 -#define IDB_DELETE 210 -#define IDI_MISSED 211 - -#define IDC_ANSWER 1000 -#define IDC_ATTENDED_TRANSFER 1001 -#define IDC_BALANCE 1006 -#define IDC_BUTTON_AR 1011 -#define IDC_BUTTON_CN 1012 -#define IDC_BUTTON_EN 1013 -#define IDC_BUTTON_FLOOR 1014 -#define IDC_BUTTON_FR 1015 -#define IDC_BUTTON_HAND 1016 -#define IDC_BUTTON_MUTE 1017 -#define IDC_BUTTON_MUTE_INPUT 1018 -#define IDC_BUTTON_MUTE_OUTPUT 1019 -#define IDC_BUTTON_RU 1020 -#define IDC_BUTTON_SP 1021 -#define IDC_CALL 1022 -#define IDC_CALL_END 1023 -#define IDC_CALL_SKYPE 1024 -#define IDC_CALLER_ADDR 1025 -#define IDC_CALLER_NAME 1026 -#define IDC_CALLS 1027 -#define IDC_CLEAR 1028 -#define IDC_CLOSE_ALL 1029 -#define IDC_CONTACTS 1030 -#define IDC_DECLINE 1032 -#define IDC_DELETE 1035 -#define IDC_EDIT_API_ID 1042 -#define IDC_EDIT_AUTHID 1043 -#define IDC_EDIT_CONFERENCE_CODE 1044 -#define IDC_EDIT_DISPLAYNAME 1045 -#define IDC_EDIT_DOMAIN 1046 -#define IDC_EDIT_NAME 1047 -#define IDC_EDIT_NUMBER 1048 -#define IDC_EDIT_PASSWORD 1049 -#define IDC_EDIT_PORT 1050 -#define IDC_EDIT_PROXY 1051 -#define IDC_EDIT_SERVER 1052 -#define IDC_EDIT_USERNAME 1053 -#define IDC_END 1055 -#define IDC_HOLD 1057 -#define IDC_ICE 1058 -#define IDC_IGNORE 1059 -#define IDC_KEY_0 1060 -#define IDC_KEY_1 1061 -#define IDC_KEY_2 1062 -#define IDC_KEY_3 1063 -#define IDC_KEY_4 1064 -#define IDC_KEY_5 1065 -#define IDC_KEY_6 1066 -#define IDC_KEY_7 1067 -#define IDC_KEY_8 1068 -#define IDC_KEY_9 1069 -#define IDC_KEY_GRATE 1070 -#define IDC_KEY_PLUS 1071 -#define IDC_KEY_STAR 1072 -#define IDC_LAST_CALL 1073 -#define IDC_LIST 1074 -#define IDC_MESSAGE 1076 -#define IDC_NUMBER 1078 -#define IDC_PRESENCE 1079 -#define IDC_PROFILE 1081 -#define IDC_PUBLIC_ADDR 1082 -#define IDC_PUBLISH 1083 -#define IDC_REG_CODE 1084 -#define IDC_REG_COUNTRY 1085 -#define IDC_REG_EMAIL 1086 -#define IDC_REG_NUMBER 1087 -#define IDC_REG_PASS1 1088 -#define IDC_REG_PASS2 1089 -#define IDC_REMEMBER_PASSWORD 1090 -#define IDC_REWRITE 1091 -#define IDC_SRTP 1098 -#define IDC_SYSLINK_ACCOUNT_LINK 1100 -#define IDC_SYSLINK_AUTHID 1101 -#define IDC_SYSLINK_DELETE 1103 -#define IDC_SYSLINK_DISPLAY_PASSWORD 1109 -#define IDC_SYSLINK_DOMAIN 1110 -#define IDC_SYSLINK_ENCRYPTION 1113 -#define IDC_SYSLINK_ICE 1115 -#define IDC_SYSLINK_LOCAL_PORT 1117 -#define IDC_SYSLINK_NAME 1118 -#define IDC_SYSLINK_PASSWORD 1119 -#define IDC_SYSLINK_PREFIX 1120 -#define IDC_SYSLINK_PUBLIC_ADDRESS 1121 -#define IDC_SYSLINK_PUBLISH_PRESENCE 1122 -#define IDC_SYSLINK_REG 1123 -#define IDC_SYSLINK_REWRITE 1124 -#define IDC_SYSLINK_SIP_PROXY 1127 -#define IDC_SYSLINK_SIP_SERVER 1128 -#define IDC_SYSLINK_TRANSPORT 1131 -#define IDC_SYSLINK_USERNAME 1132 -#define IDC_TRANSFER 1135 -#define IDC_TRANSPORT 1136 -#define IDC_VIDEO 1140 -#define IDC_VIDEO_CALL 1141 -#define IDC_VOLUME_INPUT 1143 -#define IDC_VOLUME_OUTPUT 1144 -#define IDC_BALANCE_URL 1147 -#define IDC_FILER_VALUE 1148 -#define IDC_FILER 1149 -#define IDC_SEARCH_PICTURE 1150 -#define IDC_FILTER_RESET 1151 -#define IDC_ACCOUNT_LABEL 1152 -#define IDC_ACCOUNT_WELCOME2 1153 -#define IDC_CONFERENCE_INVITE 1158 -#define IDC_ACTIONS 1159 -#define IDC_EDIT_PASSWORD_OLD 1160 -#define IDC_EDIT_PASSWORD_NEW 1161 -#define IDC_EDIT_PASSWORD_CONFIRM 1162 -#define IDC_VOICEMAIL 1166 -#define IDC_SESSION_TIMER 1167 -#define IDC_SYSLINK_SESSION_TIMER 1168 -#define IDC_EDIT_VOICEMAIL 1172 -#define IDC_SYSLINK_VOICEMAIL 1173 -#define IDC_BUTTON_PLUS_INPUT 1174 -#define IDC_BUTTON_MINUS_INPUT 1175 -#define IDC_BUTTON_PLUS_OUTPUT 1176 -#define IDC_BUTTON_MINUS_OUTPUT 1177 -#define IDC_SHORTCUT_RANGE 1178 -#define IDC_LOGO 1199 -#define IDC_REDIAL 1200 -#define IDC_ACCOUNT_REMOVE 1201 - -#define IDC_MAIN_TAB 1000 -#define IDC_MAIN_MENU 1001 -#define IDC_MAIN_PHONE 1002 -#define IDC_MAIN_LOGS 1003 -#define IDC_MAIN_CONTACTS 1004 -#define IDC_MAIN_STUB 1005 - -#define IDC_DIALER_VOICEMAIL 1000 -#define IDC_DIALER_AA 1001 -#define IDC_DIALER_DND 1002 -#define IDC_DIALER_USERNAME 1003 -#define IDC_DIALER_RELOGIN 1004 - -#define IDC_MESSAGES_TAB 1000 - -#define IDC_SETTINGS_CUSTOM_INI 1000 -#define IDC_SETTINGS_BROWSE_INI 1001 -#define IDC_SETTINGS_DEFAULT_INI 1002 -#define IDC_SETTINGS_RINGING_SOUND 1003 -#define IDC_SETTINGS_BROWSE 1004 -#define IDC_SETTINGS_DEFAULT 1005 -#define IDC_SETTINGS_RING 1006 -#define IDC_SETTINGS_SPEAKERS 1007 -#define IDC_SETTINGS_MICROPHONE 1008 -#define IDC_SETTINGS_MIC_AMPLIF 1009 -#define IDC_SETTINGS_SW_ADJUST 1010 -#define IDC_SETTINGS_AUDIO_CODECS_ALL 1011 -#define IDC_SETTINGS_AUDIO_CODECS 1012 -#define IDC_SETTINGS_SPIN_MODIFY 1013 -#define IDC_SETTINGS_SPIN_ORDER 1014 -#define IDC_SETTINGS_VAD 1015 -#define IDC_SETTINGS_EC 1016 -#define IDC_SETTINGS_FORCE_CODEC 1017 -#define IDC_SETTINGS_VID_CAP_DEV 1018 -#define IDC_SETTINGS_PREVIEW 1019 -#define IDC_SETTINGS_VIDEO_CODEC 1020 -#define IDC_SETTINGS_VIDEO_H264 1021 -#define IDC_SETTINGS_VIDEO_H263 1022 -#define IDC_SETTINGS_VIDEO_VP8 1023 -#define IDC_SETTINGS_VIDEO_BITRATE 1024 -#define IDC_SETTINGS_DTMF_METHOD 1027 -#define IDC_SETTINGS_AUTO_ANSWER 1028 -#define IDC_SETTINGS_DENY_INCOMING 1029 -#define IDC_SETTINGS_DIRECTORY 1030 -#define IDC_SETTINGS_STUN_CHECKBOX 1031 -#define IDC_SETTINGS_STUN 1032 -#define IDC_SETTINGS_MEDIA_BUTTONS 1033 -#define IDC_SETTINGS_LOCAL_DTMF 1034 -#define IDC_SETTINGS_ENABLE_LOG 1035 -#define IDC_SETTINGS_SINGLE_MODE 1036 -#define IDC_SETTINGS_ENABLE_LOCAL 1037 -#define IDC_SETTINGS_ANSWER_BOX_RANDOM 1038 -#define IDC_SETTINGS_CRASH_REPORT 1039 -#define IDC_SETTINGS_UPDATES_INTERVAL 1040 -#define IDC_SETTINGS_BRING_TO_FRONT 1042 -#define IDC_SETTINGS_RPORT 1043 -#define IDC_SETTINGS_SOURCE_PORT 1044 -#define IDC_SETTINGS_RTP_PORT_MIN 1045 -#define IDC_SETTINGS_RTP_PORT_MAX 1046 -#define IDC_SETTINGS_UNREG_ON_AWAY 1047 -#define IDC_SETTINGS_NO_SAVE_ACCOUNT 1048 -#define IDC_SETTINGS_DNS_SRV 1050 -#define IDC_SETTINGS_HELP_RINGING_SOUND 2000 -#define IDC_SETTINGS_HELP_MIC_AMPLIF 2001 -#define IDC_SETTINGS_HELP_SW_ADJUST 2002 -#define IDC_SETTINGS_HELP_AUDIO_CODECS 2003 -#define IDC_SETTINGS_HELP_VAD 2004 -#define IDC_SETTINGS_HELP_EC 2005 -#define IDC_SETTINGS_HELP_FORCE_CODEC 2006 -#define IDC_SETTINGS_HELP_VIDEO 2008 -#define IDC_SETTINGS_HELP_PORTS 2009 -#define IDC_SETTINGS_HELP_DNS_SRV 2007 -#define IDC_SETTINGS_HELP_STUN_SERVER 2014 -#define IDC_SETTINGS_HELP_DTMF_METHOD 2010 -#define IDC_SETTINGS_HELP_AUTO_ANSWER 2011 -#define IDC_SETTINGS_HELP_DENY_INCOMING 2012 -#define IDC_SETTINGS_HELP_DIRECTORY 2013 -#define IDC_SETTINGS_HELP_MEDIA_BUTTONS 2015 -#define IDC_SETTINGS_HELP_LOCAL_DTMF 2016 -#define IDC_SETTINGS_HELP_ENABLE_LOG 2017 -#define IDC_SETTINGS_HELP_SINGLE_MODE 2018 -#define IDC_SETTINGS_HELP_DISABLE_LOCAL 2019 -#define IDC_SETTINGS_HELP_ANSWER_BOX_RANDOM 2020 -#define IDC_SETTINGS_HELP_CRASH_REPORT 2021 -#define IDC_SETTINGS_HELP_BRING_TO_FRONT 2022 - -#define IDC_SHORTCUTS_EDIT_SHORTCUT1_LABEL 1000 -#define IDC_SHORTCUTS_EDIT_SHORTCUT1_NUMBER 1001 -#define IDC_SHORTCUTS_COMBO_SHORTCUT1_TYPE 1002 -#define IDC_SHORTCUTS_EDIT_SHORTCUT2_LABEL 1003 -#define IDC_SHORTCUTS_EDIT_SHORTCUT2_NUMBER 1004 -#define IDC_SHORTCUTS_COMBO_SHORTCUT2_TYPE 1005 -#define IDC_SHORTCUTS_EDIT_SHORTCUT3_LABEL 1006 -#define IDC_SHORTCUTS_EDIT_SHORTCUT3_NUMBER 1007 -#define IDC_SHORTCUTS_COMBO_SHORTCUT3_TYPE 1008 -#define IDC_SHORTCUTS_EDIT_SHORTCUT4_LABEL 1009 -#define IDC_SHORTCUTS_EDIT_SHORTCUT4_NUMBER 1010 -#define IDC_SHORTCUTS_COMBO_SHORTCUT4_TYPE 1011 -#define IDC_SHORTCUTS_EDIT_SHORTCUT5_LABEL 1012 -#define IDC_SHORTCUTS_EDIT_SHORTCUT5_NUMBER 1013 -#define IDC_SHORTCUTS_COMBO_SHORTCUT5_TYPE 1014 -#define IDC_SHORTCUTS_EDIT_SHORTCUT6_LABEL 1015 -#define IDC_SHORTCUTS_EDIT_SHORTCUT6_NUMBER 1016 -#define IDC_SHORTCUTS_COMBO_SHORTCUT6_TYPE 1017 -#define IDC_SHORTCUTS_EDIT_SHORTCUT7_LABEL 1018 -#define IDC_SHORTCUTS_EDIT_SHORTCUT7_NUMBER 1019 -#define IDC_SHORTCUTS_COMBO_SHORTCUT7_TYPE 1020 -#define IDC_SHORTCUTS_EDIT_SHORTCUT8_LABEL 1021 -#define IDC_SHORTCUTS_EDIT_SHORTCUT8_NUMBER 1022 -#define IDC_SHORTCUTS_COMBO_SHORTCUT8_TYPE 1023 -#define IDC_SHORTCUTS_ENABLE 1072 -#define IDC_SHORTCUTS_BOTTOM 1073 - -#define ID_ACCOUNT_ADD 32771 -#define ID_CHANGE_PASSWORD 32772 -#define ID_MENU_PROVISIONING 32773 -#define ID_ALWAYS_MINIMIZED 32774 -#define ID_ADD 32775 -#define ID_ALWAYS_ON_TOP 32776 -#define ID_CALL 32777 -#define ID_CALL_PICKUP 32778 -#define ID_CHAT 32779 -#define ID_CLOSEALLTABS 32780 -#define ID_COPY 32781 -#define ID_DELETE 32782 -#define ID_EDIT 32783 -#define ID_EXIT 32784 -#define ID_GOTOLASTTAB 32785 -#define ID_LOG 32786 -#define ID_MENU_ADDL 32787 -#define ID_SELECT_ALL 32788 -#define ID_SETTINGS 32789 -#define ID_VIDEOCALL 32790 -#define ID_MENU_WEBSITE 32791 -#define ID_TRANSFER 32792 -#define ID_ATTENDED_TRANSFER 32793 -#define ID_CONFERENCE 32794 -#define ID_SEPARATE 32795 -#define ID_MERGE 32796 -#define ID_DISCONNECT 32797 -#define ID_SHORTCUTS 32798 -#define ID_MENU_HELP 32799 -#define ID_MENU_SERVERS 32800 -#define ID_IMPORT 32801 -#define ID_IMPORT_GOOGLE 32802 -#define ID_ACCOUNT_CHANGE_RANGE 40000 -#define ID_ACCOUNT_EDIT_RANGE 40100 -#define ID_ATTENDED_TRANSFER_RANGE 40200 -#define ID_MERGE_RANGE 40300 -#define ID_CUSTOM_RANGE 40400 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 212 -#define _APS_NEXT_COMMAND_VALUE 32803 -#define _APS_NEXT_CONTROL_VALUE 1202 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/microsip/RinginDlg.cpp b/microsip/RinginDlg.cpp deleted file mode 100644 index 06cfdb15..00000000 --- a/microsip/RinginDlg.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "RinginDlg.h" -#include "langpack.h" -#include "mainDlg.h" -#include "settings.h" - -#include -#include - -using namespace MSIP; - -RinginDlg::RinginDlg(CWnd* pParent /*=NULL*/) - : CBaseDialog(RinginDlg::IDD, pParent) -{ - Create (IDD, pParent); -} - -RinginDlg::~RinginDlg(void) -{ -} - -int RinginDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (langPack.rtl) { - ModifyStyleEx(0,WS_EX_LAYOUTRTL); - } - return 0; -} - -BOOL CALLBACK MyInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) -{ - MONITORINFOEX iMonitor; - iMonitor.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(hMonitor, &iMonitor); - if (iMonitor.dwFlags == DISPLAY_DEVICE_MIRRORING_DRIVER) { - return true; - } else { - reinterpret_cast< std::vector* >(dwData)->push_back(hMonitor); - return true; - } -} - -BOOL RinginDlg::OnInitDialog() { - CBaseDialog::OnInitDialog(); - - TranslateDialog(this->m_hWnd); - - CFont* font = this->GetFont(); - LOGFONT lf; - font->GetLogFont(&lf); - - lf.lfHeight = 12; - m_font_ignore.CreateFontIndirect(&lf); - GetDlgItem(IDC_IGNORE)->SetFont(&m_font_ignore); - GetDlgItem(IDC_IGNORE)->EnableWindow(FALSE); - - lf.lfHeight = 24; - lf.lfWeight = FW_BOLD; - m_font.CreateFontIndirect(&lf); - GetDlgItem(IDC_CALLER_NAME)->SetFont(&m_font); - - GetDlgItem(IDC_CALLER_ADDR)->ModifyStyleEx(WS_EX_CLIENTEDGE,0,SWP_NOSIZE|SWP_FRAMECHANGED); - int x,y; - if (accountSettings.randomAnswerBox) { - CRect ringinRect; - GetWindowRect(&ringinRect); - std::vector hMonitorArray; - EnumDisplayMonitors(NULL, NULL, &MyInfoEnumProc, reinterpret_cast(&hMonitorArray)); - std::random_shuffle ( hMonitorArray.begin(), hMonitorArray.end() ); - std::vector::iterator it = hMonitorArray.begin(); - HMONITOR hMonitor = *it; - MONITORINFO mi; - mi.cbSize = sizeof(MONITORINFO); - GetMonitorInfo(hMonitor,&mi); - x = mi.rcWork.left + ( (mi.rcWork.right-mi.rcWork.left) -ringinRect.Width()) * rand() / RAND_MAX; - y = mi.rcWork.top + ( (mi.rcWork.bottom-mi.rcWork.top) -ringinRect.Height()) * rand() / RAND_MAX; - } else { - if (mainDlg->ringinDlgs.GetCount()) - { - CRect rect; - mainDlg->ringinDlgs.GetAt(mainDlg->ringinDlgs.GetCount()-1)->GetWindowRect(&rect); - x=rect.left+22; - y=rect.top+22; - } else { - if (accountSettings.ringinX || accountSettings.ringinY) { - CRect screenRect; - GetScreenRect(&screenRect); - CRect rect; - GetWindowRect(&rect); - int maxLeft = screenRect.right-rect.Width(); - if (accountSettings.ringinX>maxLeft) { - x = maxLeft; - } else { - x = accountSettings.ringinX < screenRect.left ? screenRect.left : accountSettings.ringinX; - } - int maxTop = screenRect.bottom-rect.Height(); - if (accountSettings.ringinY>maxTop) { - y = maxTop; - } else { - y = accountSettings.ringinY < screenRect.top ? screenRect.top : accountSettings.ringinY; - } - } else { - CRect ringinRect; - GetWindowRect(&ringinRect); - CRect primaryScreenRect; - SystemParametersInfo(SPI_GETWORKAREA,0,&primaryScreenRect,0); - x = (primaryScreenRect.Width()-ringinRect.Width())/2; - y = (primaryScreenRect.Height()-ringinRect.Height())/2; - } - } - } - - SetWindowPos(NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); - - if (accountSettings.bringToFrontOnIncoming) { - if (!accountSettings.silent) { - if (mainDlg->IsWindowVisible()) { - if (mainDlg->IsIconic()) { - mainDlg->ShowWindow(SW_RESTORE); - } - else { - mainDlg->ShowWindow(SW_HIDE); - mainDlg->ShowWindow(SW_MINIMIZE); - mainDlg->ShowWindow(SW_RESTORE); - } - } - ShowWindow(SW_SHOWNORMAL); - SetForegroundWindow(); - } - } - else { - if (mainDlg->IsWindowVisible()) { - ShowWindow(SW_SHOWNORMAL); - } - } - return 0; -} - -BEGIN_MESSAGE_MAP(RinginDlg, CBaseDialog) - ON_WM_CREATE() - ON_WM_CLOSE() - ON_WM_TIMER() - ON_WM_MOVE() - ON_WM_SHOWWINDOW() - ON_BN_CLICKED(IDOK, &RinginDlg::OnBnClickedOk) - ON_BN_CLICKED(IDCANCEL, &RinginDlg::OnBnClickedCancel) - ON_BN_CLICKED(IDC_ANSWER, &RinginDlg::OnBnClickedAudio) - ON_BN_CLICKED(IDC_DECLINE, &RinginDlg::OnBnClickedDecline) - ON_BN_CLICKED(IDC_VIDEO, &RinginDlg::OnBnClickedVideo) -END_MESSAGE_MAP() - -void RinginDlg::OnClose() -{ - Close(); -} - -void RinginDlg::Close(BOOL accept) -{ - int count = mainDlg->ringinDlgs.GetCount(); - for (int i = 0; i < count; i++ ) - { - if ( call_id == mainDlg->ringinDlgs.GetAt(i)->call_id) - { - if (!accept) { - mainDlg->UpdateWindowText(_T("-")); - } - if (count==1) { - mainDlg->PlayerStop(); - } - mainDlg->ringinDlgs.RemoveAt(i); - DestroyWindow(); - break; - } - } -} - -void RinginDlg::OnBnClickedOk() -{ -} - -void RinginDlg::OnBnClickedCancel() -{ - Close(); -} - -void RinginDlg::OnBnClickedDecline() -{ - pjsua_call_info call_info; - pjsua_call_get_info(call_id,&call_info); - if (pjsua_call_hangup(call_id, 0, NULL, NULL) == PJ_SUCCESS) { - mainDlg->callIdIncomingIgnore = PjToStr(&call_info.call_id); - } - Close(); -} - -void RinginDlg::OnBnClickedAudio() -{ - CallAccept(); -} - -void RinginDlg::OnBnClickedVideo() -{ - CallAccept(TRUE); -} - -void RinginDlg::CallAccept(BOOL hasVideo) -{ - mainDlg->onCallAnswer((WPARAM)call_id, (LPARAM)hasVideo); - //Close(TRUE); -} - -void RinginDlg::OnShowWindow(BOOL bShow, UINT nStatus) -{ - SetTimer(IDT_TIMER_INIT_RINGIN,1000,NULL); -} - -void RinginDlg::OnTimer (UINT_PTR TimerVal) -{ - if (TimerVal == IDT_TIMER_INIT_RINGIN) - { - KillTimer(IDT_TIMER_INIT_RINGIN); - } -} - -void RinginDlg::OnMove(int x, int y) -{ - if (IsWindowVisible() && !IsZoomed() && !IsIconic()) { - CRect cRect; - GetWindowRect(&cRect); - accountSettings.ringinX = cRect.left; - accountSettings.ringinY = cRect.top; - mainDlg->AccountSettingsPendingSave(); - } -} diff --git a/microsip/RinginDlg.h b/microsip/RinginDlg.h deleted file mode 100644 index adc3f1b6..00000000 --- a/microsip/RinginDlg.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#pragma once - -#include "resource.h" - -#include -#include -#include "BaseDialog.h" - -class RinginDlg: public CBaseDialog -{ -public: - RinginDlg(CWnd* pParent = NULL); // standard constructor - ~RinginDlg(); - enum { IDD = IDD_RINGIN }; - pjsua_call_id call_id; - CFont m_font; - bool remoteHasVideo; - CFont m_font_ignore; - void CallAccept(BOOL hasVideo = FALSE); -private: - void Close(BOOL accept = FALSE); -protected: - virtual BOOL OnInitDialog(); - DECLARE_MESSAGE_MAP() -public: - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnClose(); - afx_msg void OnTimer (UINT_PTR TimerVal); - afx_msg void OnShowWindow(BOOL bShow, UINT nStatus); - afx_msg void OnBnClickedOk(); - afx_msg void OnBnClickedCancel(); - afx_msg void OnBnClickedAudio(); - afx_msg void OnBnClickedVideo(); - afx_msg void OnBnClickedDecline(); - afx_msg void OnMove(int x, int y); -}; diff --git a/microsip/SettingsDlg.cpp b/microsip/SettingsDlg.cpp deleted file mode 100644 index dd147678..00000000 --- a/microsip/SettingsDlg.cpp +++ /dev/null @@ -1,771 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "SettingsDlg.h" -#include "mainDlg.h" -#include "settings.h" -#include "Preview.h" -#include "langpack.h" - -SettingsDlg::SettingsDlg(CWnd* pParent /*=NULL*/) - : CDialog(SettingsDlg::IDD, pParent) -{ - Create(IDD, pParent); -} - -SettingsDlg::~SettingsDlg(void) -{ -} - -int SettingsDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (langPack.rtl) { - ModifyStyleEx(0, WS_EX_LAYOUTRTL); - } - return 0; -} - -BOOL SettingsDlg::OnInitDialog() -{ - CComboBox *combobox; - CComboBox *combobox2; - unsigned count; - int i; - CString str; - - CDialog::OnInitDialog(); - - TranslateDialog(this->m_hWnd); - - GetDlgItem(IDC_SETTINGS_RINGING_SOUND)->SetWindowText(accountSettings.ringingSound); - - pjmedia_aud_dev_info aud_dev_info[128]; - count = 128; - pjsua_enum_aud_devs(aud_dev_info, &count); - - combobox = (CComboBox*)GetDlgItem(IDC_SETTINGS_MICROPHONE); - combobox->AddString(Translate(_T("Default"))); - combobox->SetCurSel(0); - - for (unsigned i = 0; i < count; i++) - { - if (aud_dev_info[i].input_count) { - CString audDevName(aud_dev_info[i].name); - combobox->AddString(audDevName); - if (!accountSettings.audioInputDevice.Compare(audDevName)) - { - combobox->SetCurSel(combobox->GetCount() - 1); - } - } - } - combobox = (CComboBox*)GetDlgItem(IDC_SETTINGS_SPEAKERS); - combobox->AddString(Translate(_T("Default"))); - combobox->SetCurSel(0); - combobox2 = (CComboBox*)GetDlgItem(IDC_SETTINGS_RING); - combobox2->AddString(Translate(_T("Default"))); - combobox2->SetCurSel(0); - for (unsigned i = 0; i < count; i++) - { - if (aud_dev_info[i].output_count) { - CString audDevName(aud_dev_info[i].name); - combobox->AddString(audDevName); - combobox2->AddString(audDevName); - if (!accountSettings.audioOutputDevice.Compare(audDevName)) - { - combobox->SetCurSel(combobox->GetCount() - 1); - } - if (!accountSettings.audioRingDevice.Compare(audDevName)) - { - combobox2->SetCurSel(combobox->GetCount() - 1); - } - } - } - - ((CButton*)GetDlgItem(IDC_SETTINGS_MIC_AMPLIF))->SetCheck(accountSettings.micAmplification); - ((CButton*)GetDlgItem(IDC_SETTINGS_SW_ADJUST))->SetCheck(accountSettings.swLevelAdjustment); - - pjsua_codec_info codec_info[64]; - CListBox *listbox; - listbox = (CListBox*)GetDlgItem(IDC_SETTINGS_AUDIO_CODECS_ALL); - CListBox *listbox2; - listbox2 = (CListBox*)GetDlgItem(IDC_SETTINGS_AUDIO_CODECS); - - CList disabledCodecsList; - count = 64; - pjsua_enum_codecs(codec_info, &count); - for (unsigned i = 0; i < count; i++) - { - POSITION pos = mainDlg->audioCodecList.Find( - PjToStr(&codec_info[i].codec_id) - ); - CString key = mainDlg->audioCodecList.GetNext(pos); - CString value = mainDlg->audioCodecList.GetNext(pos); - if (codec_info[i].priority - && (!accountSettings.audioCodecs.IsEmpty() || StrStr(_T(_GLOBAL_CODECS_ENABLED), key)) - ) { - listbox2->AddString(value); - } - else { - disabledCodecsList.AddTail(key); - } - } - POSITION pos = mainDlg->audioCodecList.GetHeadPosition(); - while (pos) { - CString key = mainDlg->audioCodecList.GetNext(pos); - CString value = mainDlg->audioCodecList.GetNext(pos); - if (disabledCodecsList.Find(key)) { - listbox->AddString(value); - } - } - - ((CButton*)GetDlgItem(IDC_SETTINGS_VAD))->SetCheck(accountSettings.vad); - ((CButton*)GetDlgItem(IDC_SETTINGS_EC))->SetCheck(accountSettings.ec); - ((CButton*)GetDlgItem(IDC_SETTINGS_FORCE_CODEC))->SetCheck(accountSettings.forceCodec); - -#ifdef _GLOBAL_VIDEO - combobox = (CComboBox*)GetDlgItem(IDC_SETTINGS_VID_CAP_DEV); - combobox->AddString(Translate(_T("Default"))); - combobox->SetCurSel(0); - pjmedia_vid_dev_info vid_dev_info[64]; - count = 64; - pjsua_vid_enum_devs(vid_dev_info, &count); - for (unsigned i = 0; i < count; i++) - { - if (vid_dev_info[i].fmt_cnt && (vid_dev_info[i].dir == PJMEDIA_DIR_ENCODING || vid_dev_info[i].dir == PJMEDIA_DIR_ENCODING_DECODING)) - { - CString vidDevName(vid_dev_info[i].name); - combobox->AddString(vidDevName); - if (!accountSettings.videoCaptureDevice.Compare(vidDevName)) - { - combobox->SetCurSel(combobox->GetCount() - 1); - } - } - } - - combobox = (CComboBox*)GetDlgItem(IDC_SETTINGS_VIDEO_CODEC); - combobox->AddString(Translate(_T("Default"))); - combobox->SetCurSel(0); - count = 64; - pjsua_vid_enum_codecs(codec_info, &count); - for (unsigned i = 0; i < count; i++) - { - combobox->AddString(PjToStr(&codec_info[i].codec_id)); - if (!accountSettings.videoCodec.Compare(PjToStr(&codec_info[i].codec_id))) - { - combobox->SetCurSel(combobox->GetCount() - 1); - } - } - - ((CButton*)GetDlgItem(IDC_SETTINGS_VIDEO_H264))->SetCheck(accountSettings.videoH264); - ((CButton*)GetDlgItem(IDC_SETTINGS_VIDEO_H263))->SetCheck(accountSettings.videoH263); - ((CButton*)GetDlgItem(IDC_SETTINGS_VIDEO_VP8))->SetCheck(accountSettings.videoVP8); - if (!accountSettings.videoBitrate) { - const pj_str_t codec_id = { "H264", 4 }; - pjmedia_vid_codec_param param; - pjsua_vid_codec_get_param(&codec_id, ¶m); - accountSettings.videoBitrate = param.enc_fmt.det.vid.max_bps / 1000; - } - str.Format(_T("%d"), accountSettings.videoBitrate); - GetDlgItem(IDC_SETTINGS_VIDEO_BITRATE)->SetWindowText(str); - -#endif - - ((CButton*)GetDlgItem(IDC_SETTINGS_RPORT))->SetCheck(accountSettings.rport); - str.Format(_T("%d"), accountSettings.sourcePort); - GetDlgItem(IDC_SETTINGS_SOURCE_PORT)->SetWindowText(str); - str.Format(_T("%d"), accountSettings.rtpPortMin); - GetDlgItem(IDC_SETTINGS_RTP_PORT_MIN)->SetWindowText(str); - str.Format(_T("%d"), accountSettings.rtpPortMax); - GetDlgItem(IDC_SETTINGS_RTP_PORT_MAX)->SetWindowText(str); - - ((CButton*)GetDlgItem(IDC_SETTINGS_DNS_SRV))->SetCheck(accountSettings.dnsSrv); - - GetDlgItem(IDC_SETTINGS_STUN)->SetWindowText(accountSettings.stun); - ((CButton*)GetDlgItem(IDC_SETTINGS_STUN_CHECKBOX))->SetCheck(accountSettings.enableSTUN); - - combobox = (CComboBox*)GetDlgItem(IDC_SETTINGS_DTMF_METHOD); - combobox->AddString(Translate(_T("Auto"))); - combobox->AddString(Translate(_T("In-band"))); - combobox->AddString(Translate(_T("RFC2833"))); - combobox->AddString(Translate(_T("SIP-INFO"))); - combobox->SetCurSel(accountSettings.DTMFMethod); - - combobox = (CComboBox*)GetDlgItem(IDC_SETTINGS_AUTO_ANSWER); - combobox->AddString(Translate(_T("No"))); - autoAnswerValues.Add(_T("")); - combobox->AddString(Translate(_T("Control Button"))); - autoAnswerValues.Add(_T("button")); - combobox->AddString(Translate(_T("SIP Header"))); - autoAnswerValues.Add(_T("header")); - combobox->AddString(Translate(_T("All Calls"))); - autoAnswerValues.Add(_T("all")); - combobox->SetCurSel(0); - for (i = 0; i < autoAnswerValues.GetCount(); i++) { - if (accountSettings.autoAnswer == autoAnswerValues.GetAt(i)) { - combobox->SetCurSel(i); - break; - } - } - - combobox = (CComboBox*)GetDlgItem(IDC_SETTINGS_DENY_INCOMING); - combobox->AddString(Translate(_T("No"))); - denyIncomingValues.Add(_T("")); - combobox->AddString(Translate(_T("Control Button"))); - denyIncomingValues.Add(_T("button")); - combobox->AddString(Translate(_T("Different User"))); - denyIncomingValues.Add(_T("user")); - combobox->AddString(Translate(_T("Different Domain"))); - denyIncomingValues.Add(_T("domain")); - combobox->AddString(Translate(_T("Different User or Domain"))); - denyIncomingValues.Add(_T("userdomain")); - combobox->AddString(Translate(_T("Different Remote Domain"))); - denyIncomingValues.Add(_T("remotedomain")); - combobox->AddString(Translate(_T("All Calls"))); - denyIncomingValues.Add(_T("all")); - combobox->SetCurSel(0); - for (i = 0; i < denyIncomingValues.GetCount(); i++) { - if (accountSettings.denyIncoming == denyIncomingValues.GetAt(i)) { - combobox->SetCurSel(i); - break; - } - } - - GetDlgItem(IDC_SETTINGS_DIRECTORY)->SetWindowText(accountSettings.usersDirectory); - ((CButton*)GetDlgItem(IDC_SETTINGS_MEDIA_BUTTONS))->SetCheck(accountSettings.enableMediaButtons); - ((CButton*)GetDlgItem(IDC_SETTINGS_LOCAL_DTMF))->SetCheck(accountSettings.localDTMF); - ((CButton*)GetDlgItem(IDC_SETTINGS_SINGLE_MODE))->SetCheck(accountSettings.singleMode); - ((CButton*)GetDlgItem(IDC_SETTINGS_ENABLE_LOG))->SetCheck(accountSettings.enableLog); - ((CButton*)GetDlgItem(IDC_SETTINGS_BRING_TO_FRONT))->SetCheck(accountSettings.bringToFrontOnIncoming); - ((CButton*)GetDlgItem(IDC_SETTINGS_ANSWER_BOX_RANDOM))->SetCheck(accountSettings.randomAnswerBox); - ((CButton*)GetDlgItem(IDC_SETTINGS_ENABLE_LOCAL))->SetCheck(accountSettings.enableLocalAccount); - - combobox = (CComboBox*)GetDlgItem(IDC_SETTINGS_UPDATES_INTERVAL); - combobox->AddString(Translate(_T("Daily"))); - combobox->AddString(Translate(_T("Weekly"))); - combobox->AddString(Translate(_T("Monthly"))); - combobox->AddString(Translate(_T("Quarterly"))); - combobox->AddString(Translate(_T("Never"))); - if (accountSettings.updatesInterval == _T("daily")) - { - i = 0; - } - else if (accountSettings.updatesInterval == _T("monthly")) - { - i = 2; - } - else if (accountSettings.updatesInterval == _T("quarterly")) - { - i = 3; - } - else if (accountSettings.updatesInterval == _T("never")) - { - i = 4; - } - else - { - i = 1; - } - combobox->SetCurSel(i); - - return TRUE; -} - -void SettingsDlg::OnDestroy() -{ - mainDlg->settingsDlg = NULL; - CDialog::OnDestroy(); -} - -void SettingsDlg::PostNcDestroy() -{ - CDialog::PostNcDestroy(); - delete this; -} - -BEGIN_MESSAGE_MAP(SettingsDlg, CDialog) - ON_WM_CREATE() - ON_WM_CLOSE() - ON_WM_DESTROY() - ON_BN_CLICKED(IDCANCEL, &SettingsDlg::OnBnClickedCancel) - ON_BN_CLICKED(IDOK, &SettingsDlg::OnBnClickedOk) - ON_MESSAGE(UM_UPDATE_SETTINGS, &SettingsDlg::OnUpdateSettings) - ON_WM_VKEYTOITEM() - ON_NOTIFY(UDN_DELTAPOS, IDC_SETTINGS_SPIN_MODIFY, &SettingsDlg::OnDeltaposSpinModify) - ON_NOTIFY(UDN_DELTAPOS, IDC_SETTINGS_SPIN_ORDER, &SettingsDlg::OnDeltaposSpinOrder) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_RINGING_SOUND, &SettingsDlg::OnNMClickSyslinkRingingSound) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_MIC_AMPLIF, &SettingsDlg::OnNMClickSyslinkMicAmplif) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_SW_ADJUST, &SettingsDlg::OnNMClickSyslinkSwAdjust) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_DTMF_METHOD, &SettingsDlg::OnNMClickSyslinkDTMFMethod) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_AUTO_ANSWER, &SettingsDlg::OnNMClickSyslinkAutoAnswer) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_DENY_INCOMING, &SettingsDlg::OnNMClickSyslinkDenyIncoming) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_DIRECTORY, &SettingsDlg::OnNMClickSyslinkDirectory) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_DNS_SRV, &SettingsDlg::OnNMClickSyslinkDnsSrv) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_STUN_SERVER, &SettingsDlg::OnNMClickSyslinkStunServer) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_MEDIA_BUTTONS, &SettingsDlg::OnNMClickSyslinkMediaButtons) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_LOCAL_DTMF, &SettingsDlg::OnNMClickSyslinkLocalDTMF) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_SINGLE_MODE, &SettingsDlg::OnNMClickSyslinkSingleMode) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_VAD, &SettingsDlg::OnNMClickSyslinkVAD) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_EC, &SettingsDlg::OnNMClickSyslinkEC) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_FORCE_CODEC, &SettingsDlg::OnNMClickSyslinkForceCodec) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_VIDEO, &SettingsDlg::OnNMClickSyslinkVideo) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_PORTS, &SettingsDlg::OnNMClickSyslinkPorts) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_AUDIO_CODECS, &SettingsDlg::OnNMClickSyslinkAudioCodecs) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_ENABLE_LOG, &SettingsDlg::OnNMClickSyslinkEnableLog) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_BRING_TO_FRONT, &SettingsDlg::OnNMClickSyslinkBringToFrontOnIncoming) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_ANSWER_BOX_RANDOM, &SettingsDlg::OnNMClickSyslinkRandomAnswerBox) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_DISABLE_LOCAL, &SettingsDlg::OnNMClickSyslinkEnableLocal) - ON_NOTIFY(NM_CLICK, IDC_SETTINGS_HELP_CRASH_REPORT, &SettingsDlg::OnNMClickSyslinkCrashReport) -#ifdef _GLOBAL_VIDEO - ON_BN_CLICKED(IDC_SETTINGS_PREVIEW, &SettingsDlg::OnBnClickedPreview) -#endif - ON_BN_CLICKED(IDC_SETTINGS_BROWSE, &SettingsDlg::OnBnClickedBrowse) - ON_EN_CHANGE(IDC_SETTINGS_RINGING_SOUND, &SettingsDlg::OnEnChangeRingingSound) - ON_BN_CLICKED(IDC_SETTINGS_DEFAULT, &SettingsDlg::OnBnClickedDefault) -END_MESSAGE_MAP() - - -void SettingsDlg::OnClose() -{ - DestroyWindow(); -} - -void SettingsDlg::OnBnClickedCancel() -{ - OnClose(); -} - -void SettingsDlg::OnBnClickedOk() -{ - this->ShowWindow(SW_HIDE); - mainDlg->PJDestroy(); - PostMessage(UM_UPDATE_SETTINGS, 0, 0); -} - -LRESULT SettingsDlg::OnUpdateSettings(WPARAM wParam, LPARAM lParam) -{ - CString str; - - CComboBox *combobox; - int i; - - GetDlgItem(IDC_SETTINGS_MICROPHONE)->GetWindowText(accountSettings.audioInputDevice); - if (accountSettings.audioInputDevice == Translate(_T("Default"))) - { - accountSettings.audioInputDevice = _T(""); - } - - GetDlgItem(IDC_SETTINGS_SPEAKERS)->GetWindowText(accountSettings.audioOutputDevice); - if (accountSettings.audioOutputDevice == Translate(_T("Default"))) - { - accountSettings.audioOutputDevice = _T(""); - } - - GetDlgItem(IDC_SETTINGS_RING)->GetWindowText(accountSettings.audioRingDevice); - if (accountSettings.audioRingDevice == Translate(_T("Default"))) - { - accountSettings.audioRingDevice = _T(""); - } - - accountSettings.micAmplification = ((CButton*)GetDlgItem(IDC_SETTINGS_MIC_AMPLIF))->GetCheck(); - accountSettings.swLevelAdjustment = ((CButton*)GetDlgItem(IDC_SETTINGS_SW_ADJUST))->GetCheck(); - - bool hasStereo = false; - accountSettings.audioCodecs = _T(""); - CListBox *listbox2; - listbox2 = (CListBox*)GetDlgItem(IDC_SETTINGS_AUDIO_CODECS); - for (unsigned i = 0; i < listbox2->GetCount(); i++) - { - CString value; - listbox2->GetText(i, value); - POSITION pos = mainDlg->audioCodecList.Find(value); - if (pos) { - mainDlg->audioCodecList.GetPrev(pos); - CString key = mainDlg->audioCodecList.GetPrev(pos); - accountSettings.audioCodecs += key + _T(" "); - if (!hasStereo && key.Right(2) == _T("/2") && key.Left(4) != _T("opus")) { - hasStereo = true; - } - } - } - accountSettings.audioCodecs.Trim(); - if (hasStereo && accountSettings.ec) { - AfxMessageBox(_T("Echo Canceler enabled. Stereo will be converted to Mono.")); - } - - accountSettings.vad = ((CButton*)GetDlgItem(IDC_SETTINGS_VAD))->GetCheck(); - accountSettings.ec = ((CButton*)GetDlgItem(IDC_SETTINGS_EC))->GetCheck(); - accountSettings.forceCodec = ((CButton*)GetDlgItem(IDC_SETTINGS_FORCE_CODEC))->GetCheck(); - -#ifdef _GLOBAL_VIDEO - GetDlgItem(IDC_SETTINGS_VID_CAP_DEV)->GetWindowText(accountSettings.videoCaptureDevice); - if (accountSettings.videoCaptureDevice == Translate(_T("Default"))) - { - accountSettings.videoCaptureDevice = _T(""); - } - - GetDlgItem(IDC_SETTINGS_VIDEO_CODEC)->GetWindowText(accountSettings.videoCodec); - if (accountSettings.videoCodec == Translate(_T("Default"))) - { - accountSettings.videoCodec = _T(""); - } - accountSettings.videoH264 = ((CButton*)GetDlgItem(IDC_SETTINGS_VIDEO_H264))->GetCheck(); - accountSettings.videoH263 = ((CButton*)GetDlgItem(IDC_SETTINGS_VIDEO_H263))->GetCheck(); - accountSettings.videoVP8 = ((CButton*)GetDlgItem(IDC_SETTINGS_VIDEO_VP8))->GetCheck(); - GetDlgItem(IDC_SETTINGS_VIDEO_BITRATE)->GetWindowText(str); - accountSettings.videoBitrate = _wtoi(str); -#endif - - accountSettings.rport = ((CButton*)GetDlgItem(IDC_SETTINGS_RPORT))->GetCheck(); - GetDlgItem(IDC_SETTINGS_SOURCE_PORT)->GetWindowText(str); - accountSettings.sourcePort = _wtoi(str); - GetDlgItem(IDC_SETTINGS_RTP_PORT_MIN)->GetWindowText(str); - accountSettings.rtpPortMin = _wtoi(str); - GetDlgItem(IDC_SETTINGS_RTP_PORT_MAX)->GetWindowText(str); - accountSettings.rtpPortMax = _wtoi(str); - - accountSettings.dnsSrv = ((CButton*)GetDlgItem(IDC_SETTINGS_DNS_SRV))->GetCheck(); - - GetDlgItem(IDC_SETTINGS_STUN)->GetWindowText(accountSettings.stun); - accountSettings.stun.Trim(); - accountSettings.enableSTUN = ((CButton*)GetDlgItem(IDC_SETTINGS_STUN_CHECKBOX))->GetCheck(); - - combobox = (CComboBox*)GetDlgItem(IDC_SETTINGS_DTMF_METHOD); - accountSettings.DTMFMethod = combobox->GetCurSel(); - - combobox = (CComboBox*)GetDlgItem(IDC_SETTINGS_AUTO_ANSWER); - accountSettings.autoAnswer = autoAnswerValues.GetAt(combobox->GetCurSel()); - - combobox = (CComboBox*)GetDlgItem(IDC_SETTINGS_DENY_INCOMING); - accountSettings.denyIncoming = denyIncomingValues.GetAt(combobox->GetCurSel()); - - GetDlgItem(IDC_SETTINGS_DIRECTORY)->GetWindowText(accountSettings.usersDirectory); - accountSettings.usersDirectory.Trim(); - accountSettings.enableMediaButtons = ((CButton*)GetDlgItem(IDC_SETTINGS_MEDIA_BUTTONS))->GetCheck(); - accountSettings.localDTMF = ((CButton*)GetDlgItem(IDC_SETTINGS_LOCAL_DTMF))->GetCheck(); - accountSettings.singleMode = ((CButton*)GetDlgItem(IDC_SETTINGS_SINGLE_MODE))->GetCheck(); - accountSettings.enableLog = ((CButton*)GetDlgItem(IDC_SETTINGS_ENABLE_LOG))->GetCheck(); - accountSettings.bringToFrontOnIncoming = ((CButton*)GetDlgItem(IDC_SETTINGS_BRING_TO_FRONT))->GetCheck(); - accountSettings.randomAnswerBox = ((CButton*)GetDlgItem(IDC_SETTINGS_ANSWER_BOX_RANDOM))->GetCheck(); - - GetDlgItem(IDC_SETTINGS_RINGING_SOUND)->GetWindowText(accountSettings.ringingSound); - - accountSettings.enableLocalAccount = ((CButton*)GetDlgItem(IDC_SETTINGS_ENABLE_LOCAL))->GetCheck(); - - combobox = (CComboBox*)GetDlgItem(IDC_SETTINGS_UPDATES_INTERVAL); - i = combobox->GetCurSel(); - switch (i) { - case 0: - accountSettings.updatesInterval = _T("daily"); - break; - case 2: - accountSettings.updatesInterval = _T("monthly"); - break; - case 3: - accountSettings.updatesInterval = _T("quarterly"); - break; - case 4: - accountSettings.updatesInterval = _T("never"); - break; - default: - accountSettings.updatesInterval = _T(""); - } - - accountSettings.SettingsSave(); - mainDlg->pageDialer->RebuildButtons(); - mainDlg->PJCreate(); - mainDlg->PJAccountAdd(); - - OnClose(); - return 0; -} - -void SettingsDlg::OnBnClickedBrowse() -{ - CFileDialog dlgFile(TRUE, _T("wav"), 0, OFN_NOCHANGEDIR, _T("WAV Files (*.wav)|*.wav|")); - if (dlgFile.DoModal() == IDOK) { - CString cwd; - LPTSTR ptr = cwd.GetBuffer(MAX_PATH); - ::GetCurrentDirectory(MAX_PATH, ptr); - cwd.ReleaseBuffer(); - if (cwd.MakeLower() + _T("\\") + dlgFile.GetFileName().MakeLower() == dlgFile.GetPathName().MakeLower()) { - GetDlgItem(IDC_SETTINGS_RINGING_SOUND)->SetWindowText(dlgFile.GetFileName()); - } - else { - GetDlgItem(IDC_SETTINGS_RINGING_SOUND)->SetWindowText(dlgFile.GetPathName()); - } - } -} - -void SettingsDlg::OnEnChangeRingingSound() -{ - CString str; - GetDlgItem(IDC_SETTINGS_RINGING_SOUND)->GetWindowText(str); - GetDlgItem(IDC_SETTINGS_DEFAULT)->EnableWindow(str.GetLength() > 0); -} - -void SettingsDlg::OnBnClickedDefault() -{ - GetDlgItem(IDC_SETTINGS_RINGING_SOUND)->SetWindowText(_T("")); -} - -int SettingsDlg::OnVKeyToItem(UINT nKey, CListBox* pListBox, UINT nIndex) -{ - CListBox *listbox = (CListBox*)GetDlgItem(IDC_SETTINGS_AUDIO_CODECS_ALL); - CListBox *listbox2 = (CListBox*)GetDlgItem(IDC_SETTINGS_AUDIO_CODECS); - if (pListBox == listbox && listbox->GetCurSel()!=-1) { - if (nKey == 32) { - //add - NMUPDOWN NMUpDown; - NMUpDown.iDelta = -1; - LRESULT lResult; - OnDeltaposSpinModify((NMHDR*)&NMUpDown, &lResult); - return -2; - } - } - if (pListBox == listbox2 && listbox2->GetCurSel() != -1) { - if (nKey == 46) { - //remove - NMUPDOWN NMUpDown; - NMUpDown.iDelta = 1; - LRESULT lResult; - OnDeltaposSpinModify((NMHDR*)&NMUpDown, &lResult); - return -2; - } - } - return -1; -} - -void SettingsDlg::OnDeltaposSpinModify(NMHDR *pNMHDR, LRESULT *pResult) -{ - LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); - CListBox *listbox; - listbox = (CListBox*)GetDlgItem(IDC_SETTINGS_AUDIO_CODECS_ALL); - CListBox *listbox2; - listbox2 = (CListBox*)GetDlgItem(IDC_SETTINGS_AUDIO_CODECS); - if (pNMUpDown->iDelta == -1) { - //add - int selected = listbox->GetCurSel(); - if (selected != LB_ERR) - { - CString str; - listbox->GetText(selected, str); - listbox2->AddString(str); - listbox->DeleteString(selected); - listbox->SetCurSel(selected < listbox->GetCount() ? selected : selected - 1); - } - } - else { - //remove - int selected = listbox2->GetCurSel(); - if (selected != LB_ERR) - { - CString str; - listbox2->GetText(selected, str); - listbox->AddString(str); - listbox2->DeleteString(selected); - listbox2->SetCurSel(selected < listbox2->GetCount() ? selected : selected - 1); - } - } - *pResult = 0; -} -void SettingsDlg::OnDeltaposSpinOrder(NMHDR *pNMHDR, LRESULT *pResult) -{ - LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); - CListBox *listbox2; - listbox2 = (CListBox*)GetDlgItem(IDC_SETTINGS_AUDIO_CODECS); - int selected = listbox2->GetCurSel(); - if (selected != LB_ERR) - { - CString str; - listbox2->GetText(selected, str); - if (pNMUpDown->iDelta == -1) { - //up - if (selected > 0) - { - listbox2->DeleteString(selected); - listbox2->InsertString(selected - 1, str); - listbox2->SetCurSel(selected - 1); - } - } - else { - //down - if (selected < listbox2->GetCount() - 1) - { - listbox2->DeleteString(selected); - listbox2->InsertString(selected + 1, str); - listbox2->SetCurSel(selected + 1); - } - } - } - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkRingingSound(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("ringingSound")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkMicAmplif(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("microphoneAmplification")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkSwAdjust(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("softwareLevelAdjustment")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkDTMFMethod(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("DTMFMethod")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkAutoAnswer(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("autoAnswer")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkDenyIncoming(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("denyIncoming")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkDirectory(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("directory")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkDnsSrv(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("dnsSrv")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkStunServer(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("stunServer")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkMediaButtons(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("handleMediaButtons")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkLocalDTMF(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("soundEvents")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkSingleMode(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("singleMode")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkVAD(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("vad")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkEC(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("ec")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkForceCodec(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("forceCodec")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkVideo(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("video")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkPorts(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("ports")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkAudioCodecs(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("audioCodecs")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkEnableLog(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("log")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkBringToFrontOnIncoming(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("bringToFrontOnIncoming")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkRandomAnswerBox(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("randomAnswerBox")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkEnableLocal(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("enableLocal")); - *pResult = 0; -} - -void SettingsDlg::OnNMClickSyslinkCrashReport(NMHDR *pNMHDR, LRESULT *pResult) -{ - OpenHelp(_T("crashReport")); - *pResult = 0; -} - -#ifdef _GLOBAL_VIDEO -void SettingsDlg::OnBnClickedPreview() -{ - CComboBox *combobox; - combobox = (CComboBox*)GetDlgItem(IDC_SETTINGS_VID_CAP_DEV); - CString name; - combobox->GetWindowText(name); - if (!mainDlg->previewWin) { - mainDlg->previewWin = new Preview(mainDlg); - } - mainDlg->previewWin->Start(mainDlg->VideoCaptureDeviceId(name)); -} -#endif - - diff --git a/microsip/SettingsDlg.h b/microsip/SettingsDlg.h deleted file mode 100644 index 35d8f0f1..00000000 --- a/microsip/SettingsDlg.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#pragma once - -#include "resource.h" -#include "global.h" - -class SettingsDlg : - public CDialog -{ -public: - SettingsDlg(CWnd* pParent = NULL); // standard constructor - ~SettingsDlg(); - enum { IDD = IDD_SETTINGS }; - -protected: - CStringArray autoAnswerValues; - CStringArray denyIncomingValues; - - virtual BOOL OnInitDialog(); - afx_msg void OnDestroy(); - virtual void PostNcDestroy(); - DECLARE_MESSAGE_MAP() -public: - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnClose(); - afx_msg void OnBnClickedCancel(); - afx_msg void OnBnClickedOk(); - afx_msg LRESULT OnUpdateSettings(WPARAM wParam,LPARAM lParam); - afx_msg void OnDeltaposSpinModify(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg int OnVKeyToItem(UINT, CListBox*, UINT); - afx_msg void OnDeltaposSpinOrder(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkSingleMode(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkRingingSound(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkMicAmplif(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkSwAdjust(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkVAD(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkEC(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkForceCodec(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkAudioCodecs(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkVideo(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkPorts(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkDnsSrv(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkStunServer(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkDTMFMethod(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkAutoAnswer(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkDenyIncoming(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkDirectory(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkMediaButtons(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkLocalDTMF(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkEnableLog(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkBringToFrontOnIncoming(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkRandomAnswerBox(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkEnableLocal(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickSyslinkCrashReport(NMHDR *pNMHDR, LRESULT *pResult); -#ifdef _GLOBAL_VIDEO - afx_msg void OnBnClickedPreview(); -#endif - afx_msg void OnBnClickedBrowse(); - afx_msg void OnEnChangeRingingSound(); - afx_msg void OnBnClickedDefault(); -}; - diff --git a/microsip/ShortcutsDlg.cpp b/microsip/ShortcutsDlg.cpp deleted file mode 100644 index f4db7b54..00000000 --- a/microsip/ShortcutsDlg.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "ShortcutsDlg.h" -#include "mainDlg.h" -#include "settings.h" -#include "langpack.h" - -ShortcutsDlg::ShortcutsDlg(CWnd* pParent /*=NULL*/) -: CDialog(ShortcutsDlg::IDD, pParent) -{ - Create (IDD, pParent); -} - -ShortcutsDlg::~ShortcutsDlg(void) -{ -} - -int ShortcutsDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (langPack.rtl) { - ModifyStyleEx(0,WS_EX_LAYOUTRTL); - } - return 0; -} - -BOOL ShortcutsDlg::OnInitDialog() -{ - CDialog::OnInitDialog(); - - TranslateDialog(this->m_hWnd); - - ((CButton*)GetDlgItem(IDC_SHORTCUTS_ENABLE))->SetCheck(accountSettings.enableShortcuts); - ((CButton*)GetDlgItem(IDC_SHORTCUTS_BOTTOM))->SetCheck(accountSettings.shortcutsBottom); - - CComboBox *combobox; - for (int i=0; i<_GLOBAL_SHORTCUTS_QTY; i++) { - combobox= (CComboBox*)GetDlgItem(IDC_SHORTCUTS_COMBO_SHORTCUT1_TYPE+i*3); - combobox->AddString(Translate(_T("Call"))); -#ifdef _GLOBAL_VIDEO - combobox->AddString(Translate(_T("Video Call"))); -#endif - combobox->AddString(Translate(_T("Message"))); - combobox->AddString(Translate(_T("DTMF"))); - combobox->AddString(Translate(_T("Call Transfer"))); - combobox->SetCurSel(0); - } - - for (int i=0;(i<_GLOBAL_SHORTCUTS_QTY && iSetWindowText(shortcut.label); - GetDlgItem(IDC_SHORTCUTS_EDIT_SHORTCUT1_NUMBER+i*3)->SetWindowText(shortcut.number); - int n = shortcut.type; -#ifndef _GLOBAL_VIDEO - if (n > 0) { - n--; - } -#endif - ((CComboBox*)GetDlgItem(IDC_SHORTCUTS_COMBO_SHORTCUT1_TYPE+i*3))->SetCurSel(n); - } - return TRUE; -} - -void ShortcutsDlg::OnDestroy() -{ - mainDlg->shortcutsDlg = NULL; - CDialog::OnDestroy(); -} - -void ShortcutsDlg::PostNcDestroy() -{ - CDialog::PostNcDestroy(); - delete this; -} - -BEGIN_MESSAGE_MAP(ShortcutsDlg, CDialog) - ON_WM_CREATE() - ON_WM_CLOSE() - ON_WM_DESTROY() - ON_BN_CLICKED(IDCANCEL, &ShortcutsDlg::OnBnClickedCancel) - ON_BN_CLICKED(IDOK, &ShortcutsDlg::OnBnClickedOk) -END_MESSAGE_MAP() - - -void ShortcutsDlg::OnClose() -{ - DestroyWindow(); -} - -void ShortcutsDlg::OnBnClickedCancel() -{ - OnClose(); -} - -void ShortcutsDlg::OnBnClickedOk() -{ - this->ShowWindow(SW_HIDE); - shortcuts.RemoveAll(); - for (int i=0; i<_GLOBAL_SHORTCUTS_QTY; i++) { - Shortcut shortcut; - GetDlgItem(IDC_SHORTCUTS_EDIT_SHORTCUT1_LABEL+i*3)->GetWindowText(shortcut.label); - GetDlgItem(IDC_SHORTCUTS_EDIT_SHORTCUT1_NUMBER+i*3)->GetWindowText(shortcut.number); - int n = ((CComboBox*)GetDlgItem(IDC_SHORTCUTS_COMBO_SHORTCUT1_TYPE + i * 3))->GetCurSel(); - if (n >=0 && !shortcut.label.IsEmpty() && !shortcut.number.IsEmpty()) { -#ifndef _GLOBAL_VIDEO - if (n > 0) { - n++; - } -#endif - shortcut.type = (msip_shortcut_type)n; - shortcuts.Add(shortcut); - } - } - ShortcutsSave(); - mainDlg->pageDialer->RebuildShortcuts(); - - bool enabled = ((CButton*)GetDlgItem(IDC_SHORTCUTS_ENABLE))->GetCheck(); - bool bottom = ((CButton*)GetDlgItem(IDC_SHORTCUTS_BOTTOM))->GetCheck(); - - if (mainDlg->shortcutsEnabled!=enabled - || - mainDlg->shortcutsBottom!=bottom - ) { - AfxMessageBox(Translate(_T("You need to restart application for the changes to take effect."))); - accountSettings.enableShortcuts=enabled; - accountSettings.shortcutsBottom = bottom; - accountSettings.SettingsSave(); - } - OnClose(); -} - diff --git a/microsip/ShortcutsDlg.h b/microsip/ShortcutsDlg.h deleted file mode 100644 index fa68b5d5..00000000 --- a/microsip/ShortcutsDlg.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#pragma once - -#include "resource.h" -#include "global.h" - -class ShortcutsDlg : - public CDialog -{ -public: - ShortcutsDlg(CWnd* pParent = NULL); // standard constructor - ~ShortcutsDlg(); - enum { IDD = IDD_SHORTCUTS }; - -protected: - virtual BOOL OnInitDialog(); - afx_msg void OnDestroy(); - virtual void PostNcDestroy(); - DECLARE_MESSAGE_MAP() -public: - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnClose(); - afx_msg void OnBnClickedCancel(); - afx_msg void OnBnClickedOk(); -}; - diff --git a/microsip/StdioFileEx.cpp b/microsip/StdioFileEx.cpp deleted file mode 100644 index 81d2cd92..00000000 --- a/microsip/StdioFileEx.cpp +++ /dev/null @@ -1,1114 +0,0 @@ -// StdioFileEx.cpp: implementation of the CStdioFileEx class. -// -// Version 1.1 23 August 2003. Incorporated fixes from Dennis Jeryd. -// Version 1.3 19 February 2005. Incorporated fixes from Howard J Oh and some of my own. -// Version 1.4 26 February 2005. Fixed stupid screw-up in code from 1.3. -// Version 1.5 18 November 2005. - Incorporated fixes from Andy Goodwin. -// - Allows code page to be specified for reading/writing -// - Properly calculates multibyte buffer size instead of -// assuming lstrlen(s). -// - Should handle UTF8 properly. -// Version 1.6 19 July 2007. - ReadString incorrectly removed \r or \n characters -// immediately preceding line breaks. -// Fixed tab problem in these comments! (Perry). -// Made GetMultiByteStringFromUnicodeString input string const -// (Perry). -// Avoided double conversion if code page not set. -// (Konrad Windszus). -// Fixed ASSERT in GetUnicodeStringFromMultiByteString -// (Konrad Windszus). -// Maximum line length restriction removed. Lines of any length -// can now be read thanks to C.B. Falconer's fggets (fgoodgets), -// ably assisted by Ana Sayfa and Dave Kondrad. -// Substantial code reorganisation and tidying. -// Use of strlen/lstrlen eliminated. Conversion functions always used -// to calculate required buffers. -// Serious, systematic tests are now included with the code. -// Options included to switch off BOM writing and alter the Unicode -// filler char. -// BOM is only stripped off if actually there. -// UTF-8 BOM is now read and written. UTF-8 conversion works. -// -// Copyright David Pritchard 2003-2007. davidpritchard@ctv.es -// -// You can use this class freely, but please keep my ego happy -// by leaving this comment in place. -// -////////////////////////////////////////////////////////////////////// - -#include "stdafx.h" -#include "StdioFileEx.h" -#include "ggets.h" - -#ifdef _DEBUG -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#define new DEBUG_NEW -#endif - -const unsigned char UTF8_BOM[] = { unsigned char(0xEF), unsigned char(0xBB), unsigned char(0xBF) }; - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -// Add this flag to write in Unicode. For the moment, out of range of all the Visual Studio 2005 flags -/*static*/ const UINT CStdioFileEx::modeWriteUnicode = 0x200000; - -CStdioFileEx::CStdioFileEx() : - m_bCheckFilePos(true), - m_bIsUnicodeText(false), - m_nFileCodePage(-1), - m_cUnicodeFillerChar(sDEFAULT_UNICODE_FILLER_CHAR), - m_bWriteBOM(true), // By default, write the BOM - CStdioFile() -{ -} - -// Set the code page for reading/writing -void CStdioFileEx::SetCodePage(IN const UINT nCodePage) -{ - m_nFileCodePage = (int)nCodePage; -} - -// Set the Unicode filler char - the char written when no conversion is possible for the target multibyte char set -void CStdioFileEx::SetFillerChar(IN const char cFiller) -{ - m_cUnicodeFillerChar = cFiller; -} - -// Determines whether the byte-order-mark is written at the start of a Unicode file -void CStdioFileEx::SetWriteBOM(IN const bool bWrite) -{ - m_bWriteBOM = bWrite; -} - -// Determines whether we try to interpret this file as Unicode -//void CStdioFileEx::SetUnicode(IN const bool bIsUnicode) -//{ -// m_bIsUnicodeText = bIsUnicode; -//} - -BOOL CStdioFileEx::Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError /*=NULL*/) -{ - // Process any Unicode stuff. This no longer checks for the Unicode BOM. We do this on - // opening for efficiency. - ProcessFlags(nOpenFlags); - - BOOL bOK = CStdioFile::Open(lpszFileName, nOpenFlags, pError); - - if (bOK) - { - // If we are reading, see if it has a BOM. I tried making the Unicode-ness independent of the BOM (i.e. allowed the file to - // be identified as Unicode by the caller, with the BOM just being used as a check, or thrown away). - // But for some reason it wouldn't work. I'll no doubt try again at some point. -// if (!(nOpenFlags & CFile::modeCreate) && (nOpenFlags & CFile::modeRead || nOpenFlags & CFile::modeReadWrite)) - if (!(nOpenFlags & CFile::modeCreate) && !(nOpenFlags & CFile::modeWrite)) - { - wchar_t cBOMTest; - wchar_t cBOM = nUNICODE_BOM; - - Read(&cBOMTest, sizeof(wchar_t)); - // Reset to start of file - SeekToBegin(); - - // If the first characters are NOT a BOM, reset to start of file - m_bIsUnicodeText = (wmemcmp(&cBOMTest, &cBOM, 1) == 0); - if (!m_bIsUnicodeText) { - char *pChar = (char *)&cBOMTest; - if (*(pChar + 1) == 0) { - m_bIsUnicodeText = true; - } - } - m_bCheckFilePos = true; - } - } - - return bOK; -} - -BOOL CStdioFileEx::ReadString(CString& rString) -{ - ASSERT(m_pStream != NULL); - - BOOL bReadData = FALSE; - LPTSTR lpsz; - int nLen = 0; - - // If at position 0, discard byte-order mark before reading. To optimise reading, we only - // check this when the m_bCheckFilePos is set (this avoids a call to ftell every time we - // read a line) - if (m_bCheckFilePos && GetPosition() == 0) - { - m_bReadBOM = false; - - // Look for Unicode BOM - if (m_bIsUnicodeText) - { - wchar_t cBOMTest; - wchar_t cBOM = nUNICODE_BOM; - Read(&cBOMTest, sizeof(wchar_t)); - // If the first characters are NOT a BOM, reset to start of file - if (wmemcmp(&cBOMTest, &cBOM, 1) != 0) - { - SeekToBegin(); - ASSERT(GetPosition() == 0); - } - else - { - // Set read BOM flag - m_bReadBOM = true; - } - } - // Look for UTF8 BOM - else if (CP_UTF8 == m_nFileCodePage) - { - BYTE arrUTF8BOMTest[sizeof(UTF8_BOM)]; - Read(arrUTF8BOMTest, sizeof(arrUTF8BOMTest)); - - // If the first characters are NOT a BOM, reset to start of file - if (memcmp(&arrUTF8BOMTest, UTF8_BOM, sizeof(arrUTF8BOMTest)) != 0) - { - SeekToBegin(); - ASSERT(GetPosition() == 0); - } - else - { - // Set read BOM flag - m_bReadBOM = true; - } - } - } - - // Read Unicode line or multibyte line (implementations - // differ depending on the compilation) - if (m_bIsUnicodeText) - { - bReadData = ReadUnicodeLine(rString); - } - else - { - bReadData = ReadMultiByteLine(rString); - } - - // Then remove end-of-line character as necessary. - // fggets keeps the end-of-line confusion level at maximum by stripping the \n - // from the end of lines, but leaving the \r. Grrrr. - // Remember that you could quite legitimately have a \r or \n at the end of - // your line before the actual \r\n line break. - if (bReadData) - { - // Copied from FileTxt.cpp but adapted to use of fgets - nLen = rString.GetLength(); - - lpsz = rString.GetBuffer(0); - - // Strip \r from the end - if (nLen != 0 && (lpsz[nLen - 1] == _T('\r'))) - { - rString.GetBufferSetLength(nLen - 1); - } - - rString.ReleaseBuffer(); - - // Now we've moved on in the file, don't bother to check any more unless the - // file pointer is moved - m_bCheckFilePos = false; - } - - return bReadData; -} - -/*virtual*/ LPTSTR CStdioFileEx::ReadString(LPTSTR lpsz, UINT nMax) -{ - // Can't really provide compatible behaviour at the moment, so no Unicode handling. - ASSERT(false); - - return CStdioFile::ReadString(lpsz, nMax); -} - - -// -------------------------------------------------------------------------------------------- -// -// CStdioFileEx::WriteString() -// -// -------------------------------------------------------------------------------------------- -// Returns: void -// Parameters: LPCTSTR lpsz -// -// Purpose: Writes string to file either in Unicode or multibyte, depending on whether the caller specified the -// CStdioFileEx::modeWriteUnicode flag. Override of base class function. -// Notes: If writing in Unicode we need to: -// a) Write the Byte-order-mark at the beginning of the file -// b) Write all strings in byte-mode -// - If we were compiled in Unicode, we need to convert Unicode to multibyte if -// we want to write in multibyte -// - If we were compiled in multi-byte, we need to convert multibyte to Unicode if -// we want to write in Unicode. -// Exceptions: None. -// -void CStdioFileEx::WriteString(LPCTSTR lpsz) -{ - // Write Byte Order Mark if needed - if (m_bWriteBOM && (!m_pStream || GetPosition() == 0)) - { - // If writing Unicode and at the start of the file, need to write byte mark - if (m_nFlags & CStdioFileEx::modeWriteUnicode) - { - // If at position 0, write byte-order mark before writing anything else - wchar_t cBOM = (wchar_t)nUNICODE_BOM; - CFile::Write(&cBOM, sizeof(wchar_t)); - } - // Fix by philfar - // http://www.codeproject.com/file/stdiofileex.asp?forumid=15472&select=1805024&df=100#xx1805024xx - // otherwise, if we are writing UTF-8 and at the start of the file, need to write UTF-8 byte mark - else if (m_nFileCodePage == CP_UTF8) - { - // If at position 0, write byte-order mark before writing anything else - CFile::Write(UTF8_BOM, sizeof(UTF8_BOM)); - } - } - - // If writing Unicode... - if (m_nFlags & CStdioFileEx::modeWriteUnicode) - { - WriteUnicodeLine(lpsz); - } - // Else write multibyte/ANSI - else - { - WriteMultiByteLine(lpsz); - } -} - -UINT CStdioFileEx::ProcessFlags(UINT& nOpenFlags) -{ - m_bIsUnicodeText = false; - - // If we have writeUnicode we must have write or writeRead as well -#ifdef _DEBUG - if (nOpenFlags & CStdioFileEx::modeWriteUnicode) - { - ASSERT(nOpenFlags & CFile::modeWrite || nOpenFlags & CFile::modeReadWrite); - } -#endif - - // Konrad Windszus 05/04/2006: handle case of writing to Unicode (obviously always Unicode) - if (nOpenFlags & CStdioFileEx::modeWriteUnicode) - { - m_bIsUnicodeText = true; - } - - // Always use binary mode, for any type of writing - if (nOpenFlags & CFile::typeText) - { - nOpenFlags ^= CFile::typeText; - } - nOpenFlags |= CFile::typeBinary; - - m_nFlags = nOpenFlags; - - return nOpenFlags; -} - -// -------------------------------------------------------------------------------------------- -// -// CStdioFileEx::IsFileUnicode() -// -// -------------------------------------------------------------------------------------------- -// Returns: bool -// Parameters: const CString& sFilePath -// -// Purpose: Determines whether a file is Unicode by reading the first character and detecting -// whether it's the Unicode byte marker. -// Notes: None. -// Exceptions: None. -// -/*static*/ bool CStdioFileEx::IsFileUnicode(const CString& sFilePath) -{ - CFile file; - bool bIsUnicode = false; - wchar_t cFirstChar; - CFileException exFile; - - // Open file in binary mode and read first character - if (file.Open(sFilePath, CFile::typeBinary | CFile::modeRead, &exFile)) - { - // If byte is Unicode byte-order marker, let's say it's Unicode - if (file.Read(&cFirstChar, sizeof(wchar_t)) > 0 && cFirstChar == (wchar_t)nUNICODE_BOM) - { - bIsUnicode = true; - } - - file.Close(); - } - else - { - // Handle error here if you like - } - - return bIsUnicode; -} - -// Rough character count. Likely to be way out for multibyte files using non-western -// code pages. Anybody got a better method? -STDIOEXLONG CStdioFileEx::GetCharCount() -{ - int nCharSize; - ULONGLONG nByteCount, nCharCount = 0; - - if (m_pStream) - { - // Get size of chars in file - nCharSize = m_bIsUnicodeText ? sizeof(wchar_t) : sizeof(char); - - // If Unicode, remove byte order mark from count - nByteCount = GetLength(); - - if (m_bIsUnicodeText) - { - nByteCount = nByteCount - sizeof(wchar_t); - } - - // Calc chars - nCharCount = (nByteCount / nCharSize); - } - - return nCharCount; -} - -/*virtual*/ STDIOEXLONG CStdioFileEx::Seek(LONGLONG lOff, UINT nFrom) -{ - // Note that we should check the file position on the next read - m_bCheckFilePos = true; - - return CStdioFile::Seek(lOff, nFrom); -} - - -// Get the current users code page -UINT CStdioFileEx::GetCurrentLocaleCodePage() -{ - _TCHAR szLocalCodePage[10]; - UINT nLocaleCodePage = 0; - int nLocaleChars = ::GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE, szLocalCodePage, 10); - - // If OK - if (nLocaleChars > 0) - { - nLocaleCodePage = (UINT)_ttoi(szLocalCodePage); - ASSERT(nLocaleCodePage > 0); - } - else - { - ASSERT(false); - } - - // O means either: no ANSI code page (Unicode-only locale?) or failed to get locale - // In the case of Unicode-only locales, what do multibyte apps do? Answers on a postcard. - return nLocaleCodePage; -} - -// -------------------------------------------------------------------------------------------- -// -// CStdioFileEx::GetUnicodeStringFromMultiByteString() -// -// -------------------------------------------------------------------------------------------- -// Returns: int - number of chars written -// Parameters: LPCSTR szMultiByteString (IN) Multi-byte input string -// wchar_t* szUnicodeString (OUT) Unicode outputstring -// size_t nUnicodeBufferSize (IN) Size of Unicode output buffer in chars -// UINT nCodePage (IN) Code page used to perform conversion -// Default = CP_ACP (Get local code page). -// -// Purpose: Gets a Unicode string from a MultiByte string. -// Notes: None. -// Exceptions: None. -// -int CStdioFileEx::GetUnicodeStringFromMultiByteString(IN LPCSTR szMultiByteString, OUT wchar_t* szUnicodeString, IN const size_t nUnicodeBufferSize, IN UINT nCodePage) -{ - int nCharsWritten = 0; - - if (szUnicodeString && szMultiByteString) - { - // If no code page specified, take default for system - if (nCodePage == (UINT)-1) - { - nCodePage = GetACP(); - } - - try - { - // Zero out buffer first - memset((void*)szUnicodeString, '\0', sizeof(wchar_t) * nUnicodeBufferSize); - - // When converting to UTF8, don't set any flags (see Q175392). - nCharsWritten = MultiByteToWideChar((UINT)nCodePage, (nCodePage == CP_UTF8 ? - 0 : MB_PRECOMPOSED), szMultiByteString, -1, szUnicodeString, (int)nUnicodeBufferSize); - } - catch (...) - { - // Level 4 compile says this is unreachable code in VS2005. I guess MultiByteToWideChar doesn't throw exceptions. -// TRACE(_T("Controlled exception in MultiByteToWideChar!\n")); - } - } - else - { - ASSERT(false); - } - - // Konrad Windszus 29/3/2006: ASSERT in wrong place! - // Should have at least the terminator (right?) - ASSERT(nCharsWritten > 0); - - // Now fix nCharsWritten to exclude \0 terminator - if (nCharsWritten > 0) - { - nCharsWritten--; - } - - return nCharsWritten; -} - -// -------------------------------------------------------------------------------------------- -// -// CStdioFileEx::GetRequiredUnicodeLengthFromMultiByteString() -// -// -------------------------------------------------------------------------------------------- -// Returns: int - number of chars needed -// Parameters: LPCSTR szMultiByteString (IN) Multi-byte input string -// UINT nCodePage (IN) Code page of input string -// Default = CP_ACP (local code page). -// -// Purpose: Gets the length required, in wchar_t values (chars) to convert a MultiByte string to a Unicode string. -// Notes: None. -// Exceptions: None. -// -/*static*/ int CStdioFileEx::GetRequiredUnicodeLengthFromMultiByteString(IN LPCSTR szMultiByteString, IN UINT nCodePage /*=CP_ACP OPTIONAL*/) -{ - int nCharsNeeded = 0; - - if (szMultiByteString) - { - // If no code page specified, take default for system - if (nCodePage == (UINT)-1) - { - nCodePage = GetACP(); - } - - try - { - // When converting to UTF8, don't set any flags (see Q175392). - nCharsNeeded = MultiByteToWideChar((UINT)nCodePage, (nCodePage == CP_UTF8 ? - 0 : MB_PRECOMPOSED), - szMultiByteString, - -1, // Get the function to work out the length - NULL, // No output buffer needed - 0 // Ask to be told how many chars we need (includes space for terminator) - ); - } - catch (...) - { - // Level 4 compile says this is unreachable code in VS2005. I guess MultiByteToWideChar doesn't throw exceptions. -// TRACE(_T("Controlled exception in MultiByteToWideChar!\n")); - } - } - else - { - ASSERT(false); - } - - // Konrad Windszus 29/3/2006: ASSERT in wrong place! - // Should have at least the terminator (right?). The value returned by MultiByteToWideChar includes the terminator. - ASSERT(nCharsNeeded > 0); - - return nCharsNeeded; -} - -// -------------------------------------------------------------------------------------------- -// -// CStdioFileEx::GetNewUnicodeStringFromMultiByteString() -// -// -------------------------------------------------------------------------------------------- -// Returns: int - number of chars written (0 means error) -// Parameters: LPCSTR szMultiByteString (IN) Multi-byte input string -// CTemplateSmartPtrArray& -// spUnicodeString (IN/OUT) Smart pointer containing default buffer (or NULL) -// on input, and pointing to buffer used for conversion -// on output. A newly allocated buffer will be automatically -// deleted when the smart ptr object is destroyed. -// This allows a default buffer to be declared and used for -// most strings. Dynamic allocation is only performed when -// the default buffer would not be large enough. -// int nDefaultBufferSize (IN) Size of default buffer in smart ptr (may be 0). -// UINT nCodePage (IN) Code page used to perform conversion -// Default = CP_ACP (Get local code page). -// -// Purpose: Gets a Unicode string from a MultiByte string. Calculates the buffer for you and -// allocates it with "new". -// Notes: It's better to ask this function to allocate the buffer for you, because it will -// calculate the correct size. If we just take the number of bytes from the multibyte -// string as the size, we won't be in danger of allocating too little memory, but we -// may well allocate too much. -// -// The use of a smart ptr array combines this flexibility with efficiency. A default buffer can be passed in -// and used wherever is it sufficient to contain the output string. This avoids lots of unnecessary "new"s and -// "delete"s when reading or writing large files. -// Exceptions: None. -// -/*static*/ int CStdioFileEx::GetNewUnicodeStringFromMultiByteString(IN LPCSTR szMultiByteString, IN OUT CTemplateSmartPtrArray& spUnicodeString, IN const int nDefaultBufferSize/*=0*/, IN UINT nCodePage /*=CP_ACP OPTIONAL*/) -{ - int nActualBufferSize = nDefaultBufferSize; - - // Calculate the required buffer size and allocate - int nUnicodeBufferSizeChars = GetRequiredUnicodeLengthFromMultiByteString(szMultiByteString, nCodePage); - - // If we have enough in the default buffer, don't bother to allocate - if (nUnicodeBufferSizeChars > nDefaultBufferSize) - { - //pszUnicodeString = new wchar_t[nUnicodeBufferSizeChars]; - - // The new buffer will be marked as "owned" by the smart ptr by default, and therefore automatically deleted by the smart ptr - spUnicodeString.Assign(new wchar_t[nUnicodeBufferSizeChars]); - - nActualBufferSize = nUnicodeBufferSizeChars; - } - - // Call standard - return GetUnicodeStringFromMultiByteString(szMultiByteString, spUnicodeString.GetBuffer(), nActualBufferSize, nCodePage); -} - -// -------------------------------------------------------------------------------------------- -// -// CStdioFileEx::GetMultiByteStringFromUnicodeString() -// -// -------------------------------------------------------------------------------------------- -// Returns: int - number of chars written. 0 if error. -// Parameters: wchar_t * szUnicodeString (IN) Unicode input string -// char* szMultiByteString (OUT) Multibyte output string -// int nMultiByteBufferSize (IN) Multibyte buffer size -// UINT nCodePage (IN) Code page used to perform conversion -// Default = CP_ACP (Get local code page). -// char cFillerChar (IN) Unicode-to-multibyte filler char -// Default = # -// -// Purpose: Gets a MultiByte string from a Unicode string. -// Notes: It's better to ask this function to allocate the buffer for you, because it will -// calculate the correct size. Multibyte code pages will require larger buffers than -// the normal Western code pages, so we can't just say new char[numchars]! -// Exceptions: None. -// -int CStdioFileEx::GetMultiByteStringFromUnicodeString(IN const wchar_t * szUnicodeString, OUT char* szMultiByteString, - IN const int nMultiByteBufferSize, IN UINT nCodePage/*=CP_ACP OPTIONAL*/, - IN char cFillerChar/*=sDEFAULT_UNICODE_FILLER_CHAR OPTIONAL*/) -{ - BOOL bUsedDefChar = FALSE; - int nBytesWritten = 0; - - // Fix by Andy Goodwin: don't do anything if buffer is 0 - if (nMultiByteBufferSize > 0) - { - if (szUnicodeString && szMultiByteString) - { - // Zero out buffer first - memset((void*)szMultiByteString, '\0', sizeof(char) * nMultiByteBufferSize); - - // If no code page specified, take default for system - if (nCodePage == (UINT)-1) - { - nCodePage = (UINT)GetACP(); - } - - try - { - // If writing to UTF8, flags, default char and boolean flag must be NULL - nBytesWritten = WideCharToMultiByte((UINT)nCodePage, - (nCodePage == CP_UTF8 ? 0 : WC_COMPOSITECHECK | WC_SEPCHARS), // Flags - szUnicodeString, -1, - szMultiByteString, - nMultiByteBufferSize, - (nCodePage == CP_UTF8 ? NULL : &cFillerChar), // Filler char - (nCodePage == CP_UTF8 ? NULL : &bUsedDefChar)); // Did we use filler char? - - // If no chars were written and the buffer is not 0, error! - if (nBytesWritten == 0 && nMultiByteBufferSize > 0) - { - TRACE1("Error in WideCharToMultiByte: %d\n", ::GetLastError()); - } - } - catch (...) - { - TRACE0("Controlled exception in WideCharToMultiByte!\n"); - } - } - } - - // Now fix nCharsWritten to exclude \0 terminator - if (nBytesWritten > 0) - { - nBytesWritten = nBytesWritten - sizeof('\0'); - } - - return nBytesWritten; -} - - - -//--------------------------------------------------------------------------------------------------- -// -// CStdioFileEx::GetRequiredMultiByteLengthForUnicodeString() -// -//--------------------------------------------------------------------------------------------------- -// Returns: int - no of bytes required -// Parameters: wchar_t * szUnicodeString (IN) String to convert -// UINT nCodePage=CP_ACP (IN) Code page to which to convert -// -// Purpose: Obtains the multi-byte buffer size (in bytes) needed to accommodate a converted Unicode string. -// Notes: We can't assume that the buffer length is simply equal to the number of characters -// because that wouldn't accommodate multibyte characters! -// -/*static*/ int CStdioFileEx::GetRequiredMultiByteLengthForUnicodeString(IN const wchar_t * szUnicodeString, IN UINT nCodePage /*=CP_ACP OPTIONAL*/) -{ - int nBytesNeeded = 0; - - try - { - // If no code page specified, take default for system - if (nCodePage == -1) - { - nCodePage = GetACP(); - } - - // If writing to UTF8, flags, default char and boolean flag must be NULL - nBytesNeeded = WideCharToMultiByte((UINT)nCodePage, - (nCodePage == CP_UTF8 ? 0 : WC_COMPOSITECHECK | WC_SEPCHARS), // Flags - szUnicodeString, -1, - NULL, - 0, // Calculate required buffer, please! (Includes space for terminator) - NULL, // Filler char doesn't matter here - NULL); - } - catch (...) - { - // TRACE(_T("Controlled exception in WideCharToMultiByte!\n")); - // Gives us "unreachable code" error compiling on level 4 - } - - return nBytesNeeded; -} - - -// -------------------------------------------------------------------------------------------- -// -// CStdioFileEx::GetNewMultiByteStringFromUnicodeString() -// -// -------------------------------------------------------------------------------------------- -// Returns: int - number of chars written. 0 if error. -// Parameters: wchar_t * szUnicodeString (IN) Unicode input string -// CTemplateSmartPtrArray& -// spMultiByteString (IN/OUT) Smart pointer containing default buffer (or NULL) -// on input, and pointing to buffer used for conversion -// on output. A newly allocated buffer will be automatically -// deleted when the smart ptr object is destroyed. -// This allows a default buffer to be declared and used for -// most strings. Dynamic allocation is only performed when -// the default buffer would not be large enough. -// int nDefaultBufferSize (IN) Size of default buffer in smart ptr (may be 0). -// UINT nCodePage (IN) Code page used to perform conversion -// Default = CP_ACP (Get local code page). -// char cFillerChar (IN) Unicode-to-multibyte filler char -// Default = # -// -// Purpose: Gets a MultiByte string from a Unicode string. Calculates the buffer for you and -// allocates it with new. -// Notes: It's better to ask this function to allocate the buffer for you, because it will -// calculate the correct size. Multibyte code pages will require larger buffers than -// the normal Western code pages, so we can't just say new char[numchars]! -// -// The use of a smart ptr array combines this flexibility with efficiency. A default buffer can be passed in -// and used wherever is it sufficient to contain the output string. This avoids lots of unnecessary "new"s and -// "delete"s when reading or writing large files. -// Exceptions: None. -// -/*static*/ int CStdioFileEx::GetNewMultiByteStringFromUnicodeString(IN const wchar_t * szUnicodeString, IN OUT CTemplateSmartPtrArray& spMultiByteString, IN const int nDefaultBufferSize/*=0*/, - IN UINT nCodePage /*=CP_ACP OPTIONAL*/, IN char cFillerChar/*=sDEFAULT_UNICODE_FILLER_CHAR OPTIONAL*/) -{ - int nActualBufferSize = nDefaultBufferSize; - - // Calculate the required buffer size and allocate - int nMultibyteBufferSizeBytes = GetRequiredMultiByteLengthForUnicodeString(szUnicodeString, nCodePage); - - // If we have enough in the default buffer, don't bother to allocate - if (nMultibyteBufferSizeBytes > nDefaultBufferSize) - { - // The new buffer will be marked as "owned" by the smart ptr by default, and therefore automatically deleted by the smart ptr - spMultiByteString.Assign(new char[nMultibyteBufferSizeBytes]); - - nActualBufferSize = nMultibyteBufferSizeBytes; - } - - // Call standard - return GetMultiByteStringFromUnicodeString(szUnicodeString, spMultiByteString.GetBuffer(), nActualBufferSize, nCodePage, cFillerChar); -} - -//--------------------------------------------------------------------------------------------------- -// -// CStdioFileEx::GetNewUTF8StringFromUnicodeString() -// -//--------------------------------------------------------------------------------------------------- -// Returns: bool - true if successful, false if it fails. -// Parameters: const wchar_t* szUnicodeString (IN) Input Unicode string -// unsigned char*& pszUTF8String (OUT) Receives a ptr. If the function returns -// successfully. -// the ptr points to the output string -// -// Purpose: Does conversion from Unicode to UTF8. Allocates memory for the output string -// Notes: Culled from http://www.bytemycode.com/snippets/snippet/438/ -// Contributed by Dean -// -/*static*/ /*bool CStdioFileEx::GetNewUTF8StringFromUnicodeString( IN const wchar_t* szUnicodeString, OUT unsigned char*& pszUTF8String ) -{ - bool bConvertedOK = false; - const wchar_t* w; - - // Calculate length needed for output string, taking account - // of the variable number of bytes needed to represent each - // Unicode character in UTF8 - int len = 0; - for ( w = szUnicodeString; *w; w++ ) - { - if ( *w < 0Õ°080 ) len++; - - else if ( *w < 0Õ°800 ) len += 2; - - else len += 3; - } - - //unsigned char* szOut = ( unsigned char* )malloc( len+1 ); - pszUTF8String = new char[len+1]; - - if ( pszUTF8String != NULL ) - { - int i = 0; - - for ( w = szUnicodeString; *w; w++ ) - { - // Handle ASCII chars - if ( *w < 0Õ°080 ) - { - pszUTF8String[i++] = ( char ) *w; - } - else if ( *w < 0Õ°800 ) - { - pszUTF8String[i++] = 0xc0 | (( *w ) >> 6 ); - pszUTF8String[i++] = 0Õ¸0 | (( *w ) & 0Õŗf ); - } - else - { - pszUTF8String[i++] = 0xe0 | (( *w ) >> 12 ); - pszUTF8String[i++] = 0Õ¸0 | (( ( *w ) >> 6 ) & 0Õŗf ); - pszUTF8String[i++] = 0Õ¸0 | (( *w ) & 0Õŗf ); - } - } - - pszUTF8String[ i ] = \0; - - bConvertedOK = true; - } - - //return ( char* )szOut; - return bConvertedOK; -}*/ - -/**********************************************************************************/ -/* Reading */ -/**********************************************************************************/ -#ifdef _UNICODE -// Read Unicode in Unicode compilation -BOOL CStdioFileEx::ReadUnicodeLine(OUT CString& sOutputLine) -{ - BOOL bReadData = FALSE; - wchar_t* pszUnicodeString = (wchar_t*)&m_arrUnicodeDefaultBuffer; - bool bNeedToDelete = false; - - try - { - bReadData = (FGGETS_OK == fggets(&pszUnicodeString, m_pStream, bNeedToDelete, nSTDIOFILEEX_DEFAULT_BUFFER_SIZE)); - - if (bReadData) - { - sOutputLine = (CString)pszUnicodeString; - } - else - { - sOutputLine.Empty(); - } - } - // Ensure we always clean up, no matter what - FINALLY(if (bNeedToDelete) DELETE_SAFE_ARRAY(pszUnicodeString); ) - - return bReadData; -} - -// Read Multibyte in Unicode compilation -BOOL CStdioFileEx::ReadMultiByteLine(OUT CString& sOutputLine) -{ - BOOL bReadData = FALSE; - char * pszMultiByteString = (char*)&m_arrMultibyteDefaultBuffer;; - int nChars = 0; - bool bNeedToDelete = false; - - try - { - // Read the string -- the function dynamically allocates the necessary memory according - // to the line length - bReadData = (FGGETS_OK == fggets(&pszMultiByteString, m_pStream, bNeedToDelete, nSTDIOFILEEX_DEFAULT_BUFFER_SIZE)); - - if (bReadData) - { - // Assign default buffer to take care of 99% of cases. Not owned by smart ptr array, so won't be deleted - CTemplateSmartPtrArray spUnicodeString((wchar_t*)&m_arrUnicodeDefaultBuffer, bTEMPLATESMARTPTR_NOTOWNED); - - // Use all-in-one allocation and conversion function. Avoid _mbslen and such like since they're unreliable - // with UTF8 - nChars = GetNewUnicodeStringFromMultiByteString(pszMultiByteString, spUnicodeString, nSTDIOFILEEX_DEFAULT_BUFFER_SIZE, m_nFileCodePage); - - if (nChars > 0) - { - sOutputLine = (CString)spUnicodeString.GetBuffer(); - } - } - - // Empty the string if we failed to read anything - if (nChars == 0) - { - sOutputLine.Empty(); - } - } - // Ensure we always clean up, no matter what - FINALLY(if (bNeedToDelete) DELETE_SAFE_ARRAY(pszMultiByteString); ) - - return bReadData; -} - -#else - -// Read Unicode in Multibyte compilation -BOOL CStdioFileEx::ReadUnicodeLine(OUT CString& sOutputLine) -{ - BOOL bReadData = FALSE; - wchar_t* pszUnicodeString = (wchar_t*)&m_arrUnicodeDefaultBuffer; - bool bNeedToDelete = false; - int nChars = 0; - - try - { - bReadData = (FGGETS_OK == fggets(&pszUnicodeString, m_pStream, bNeedToDelete, nSTDIOFILEEX_DEFAULT_BUFFER_SIZE)); - - if (bReadData) - { - // Assign default buffer to take care of 99% of cases. Not owned by smart ptr array, so won't be deleted - CTemplateSmartPtrArray spMultiByteString((char*)&m_arrMultibyteDefaultBuffer, bTEMPLATESMARTPTR_NOTOWNED); - - // Call all-in-one function to calculate required buffer size and allocate - nChars = GetNewMultiByteStringFromUnicodeString(pszUnicodeString, spMultiByteString, nSTDIOFILEEX_DEFAULT_BUFFER_SIZE, m_nFileCodePage, m_cUnicodeFillerChar); - - if (nChars > 0) - { - sOutputLine = (CString)spMultiByteString.GetBuffer(); - } - } - - // Empty the string if we failed to read anything - if (nChars == 0) - { - sOutputLine.Empty(); - } - } - // Ensure we always clean up, no matter what - FINALLY(if (bNeedToDelete) DELETE_SAFE_ARRAY(pszUnicodeString); ) - - return bReadData; -} - -// Read Multibyte in Multibyte compilation -BOOL CStdioFileEx::ReadMultiByteLine(OUT CString& sOutputLine) -{ - BOOL bReadData = FALSE; - char * pszMultiByteString = (char*)&m_arrMultibyteDefaultBuffer;; - int nChars = 0; - UINT nLocaleCodePage = 0; - bool bNeedToDelete = false; - - try - { - // Read multibyte from file - bReadData = (FGGETS_OK == fggets(&pszMultiByteString, m_pStream, bNeedToDelete, nSTDIOFILEEX_DEFAULT_BUFFER_SIZE)); - - if (bReadData) - { - // Convert to CString - sOutputLine = (CString)pszMultiByteString; - - // Now see if we've got to convert to another code page. Get the current code page - nLocaleCodePage = GetCurrentLocaleCodePage(); - - // If we got it OK... - if (nLocaleCodePage > 0) - { - // If file code page does not match the system code page (and we have a code page!), - // we need to do a double conversion! - // Konrad Windszus 29/3/2006: Do nothing if we haven't set a code page - if (m_nFileCodePage > 0 && nLocaleCodePage != (UINT)m_nFileCodePage) - { - // Assign default buffer to take care of 99% of cases. Not owned by smart ptr array, so won't be deleted - CTemplateSmartPtrArray spUnicodeString((wchar_t*)&m_arrUnicodeDefaultBuffer, bTEMPLATESMARTPTR_NOTOWNED); - - // Use all-in-one allocation and conversion function. Avoid _mbslen and such like since they're unreliable - // with UTF8 - nChars = GetNewUnicodeStringFromMultiByteString(sOutputLine, spUnicodeString, nSTDIOFILEEX_DEFAULT_BUFFER_SIZE, m_nFileCodePage); - - // Convert back to multibyte using the system code page - // (This doesn't really confer huge advantages except to avoid "mangling" of non-convertible special - // characters. So, if a file in the E.European code page is displayed on a system using the - // western European code page, special accented characters which the system cannot display will be - // replaced by the default character (a hash or something), rather than being incorrectly mapped to - // other, western European accented characters). - if (nChars > 0) - { - // Assign default buffer to take care of 99% of cases. Not owned by smart ptr array, so won't be deleted - CTemplateSmartPtrArray spMultiByteString((char*)&m_arrMultibyteDefaultBuffer, bTEMPLATESMARTPTR_NOTOWNED); - - // Call all-in-one function to calculate required buffer size and allocate - nChars = GetNewMultiByteStringFromUnicodeString(spUnicodeString.GetBuffer(), spMultiByteString, nSTDIOFILEEX_DEFAULT_BUFFER_SIZE, nLocaleCodePage, m_cUnicodeFillerChar); - - sOutputLine = (CString)spMultiByteString.GetBuffer(); - } - } - } - } - - // Empty the string if we failed to read anything - if (!bReadData) - { - sOutputLine.Empty(); - } - - } - // Ensure we always clean up, no matter what - FINALLY(if (bNeedToDelete) DELETE_SAFE_ARRAY(pszMultiByteString); ) - - return bReadData; -} -#endif - -/**********************************************************************************/ -/* Writing */ -/**********************************************************************************/ -#ifdef _UNICODE - -// Unicode in Unicode -- no conversion needed -void CStdioFileEx::WriteUnicodeLine(IN LPCTSTR sInputLine) -{ - // Write in byte mode - CFile::Write(sInputLine, (UINT)(wcslen(sInputLine) * sizeof(wchar_t))); -} - -// Multibyte/ANSI in Unicode -- have to convert to Multibyte, taking into account the desired code page -void CStdioFileEx::WriteMultiByteLine(IN LPCTSTR sInputLine) -{ - int nCharsWritten = 0; - - // Assign default buffer to take care of 99% of cases. Not owned by smart ptr array, so won't be deleted - CTemplateSmartPtrArray spMultiByteString((char*)&m_arrMultibyteDefaultBuffer, bTEMPLATESMARTPTR_NOTOWNED); - - // Call all-in-one function to calculate required buffer size and allocate - nCharsWritten = GetNewMultiByteStringFromUnicodeString(sInputLine, spMultiByteString, nSTDIOFILEEX_DEFAULT_BUFFER_SIZE, m_nFileCodePage, m_cUnicodeFillerChar); - - if (nCharsWritten > 0) - { - // Do byte-mode write using actual chars written (fix by Howard J Oh) - CFile::Write((const void*)spMultiByteString.GetBuffer(), - nCharsWritten * sizeof(char)); - } -} - -#else -// Writing Unicode in Multibyte, need to convert to Unicode -void CStdioFileEx::WriteUnicodeLine(IN LPCTSTR sInputLine) -{ - int nCharsWritten = 0; - - // Assign default buffer to take care of 99% of cases. Not owned by smart ptr array, so won't be deleted - CTemplateSmartPtrArray spUnicodeString((wchar_t*)&m_arrUnicodeDefaultBuffer, bTEMPLATESMARTPTR_NOTOWNED); - - // Use all-in-one allocation and conversion function. Avoid _mbslen and such like since they're unreliable - // with UTF8 - nCharsWritten = GetNewUnicodeStringFromMultiByteString(sInputLine, spUnicodeString, nSTDIOFILEEX_DEFAULT_BUFFER_SIZE, m_nFileCodePage); - - if (nCharsWritten > 0) - { - // Do byte-mode write using actual chars written (fix by Howard J Oh) - CFile::Write((const void*)spUnicodeString.GetBuffer(), nCharsWritten * sizeof(wchar_t)); - } - else - { - ASSERT(false); - } - - // If a buffer was dynamically allocated, it gets deleted by the smart ptr, even on an exception -} - -// Writing Multibyte in Multibyte, no conversion needed, unless the code page differs -void CStdioFileEx::WriteMultiByteLine(IN LPCTSTR sInputLine) -{ - UINT nLocaleCodePage = 0; - int nUnicodeCharsWritten = 0; - int nMultiByteCharsWritten = 0; - - // Get the current code page - nLocaleCodePage = GetCurrentLocaleCodePage(); - - // if file code page does not match the system code page (and we have a code page!), - // we need to do a double conversion! - // Konrad Windszus 29/3/2006: Do nothing if we haven't set a code page - if (nLocaleCodePage > 0 && m_nFileCodePage > 0 && nLocaleCodePage != (UINT)m_nFileCodePage) - { - // Assign default buffer to take care of 99% of cases. Not owned by smart ptr array, so won't be deleted - CTemplateSmartPtrArray spUnicodeString((wchar_t*)&m_arrUnicodeDefaultBuffer, bTEMPLATESMARTPTR_NOTOWNED); - - // Use all-in-one allocation and conversion function. Avoid _mbslen and such like since they're unreliable - // with UTF8 - nUnicodeCharsWritten = GetNewUnicodeStringFromMultiByteString(sInputLine, spUnicodeString, nSTDIOFILEEX_DEFAULT_BUFFER_SIZE, nLocaleCodePage); - - // Convert back to multibyte using the file code page - // (Note that you can't reliably read a non-Unicode file written in code page A on a system using a code page B, - // modify the file and write it back using code page A, unless you disable all this double-conversion code. - // In effect, you have to choose between a mangled character display and mangled file writing). - if (nUnicodeCharsWritten > 0) - { - // Assign default buffer to take care of 99% of cases. Not owned by smart ptr array, so won't be deleted - CTemplateSmartPtrArray spMultiByteString((char*)&m_arrMultibyteDefaultBuffer, bTEMPLATESMARTPTR_NOTOWNED); - - // Call all-in-one function to calculate required buffer size and allocate - nMultiByteCharsWritten = GetNewMultiByteStringFromUnicodeString( - spUnicodeString.GetBuffer(), spMultiByteString, nSTDIOFILEEX_DEFAULT_BUFFER_SIZE, m_nFileCodePage, m_cUnicodeFillerChar); - - // Do byte-mode write. This avoids annoying "interpretation" of \n's as \r\n - CFile::Write((const void*)spMultiByteString.GetBuffer(), nMultiByteCharsWritten * sizeof(char)); - - // If a Unicode buffer was dynamically allocated, it now gets deleted by the smart ptr, even on an exception - } - - // If a multibyte buffer was dynamically allocated, it now gets deleted by the smart ptr, even on an exception - } - else - { - // Do byte-mode write. This avoids annoying "interpretation" of \n's as \r\n - // Use strlen because we want a straightforward byte-for-byte copy. Characters are irrelevant. - // strlen always counts bytes. - CFile::Write((const void*)sInputLine, strlen((const char*)sInputLine) * sizeof(char)); - } -} - -#endif diff --git a/microsip/StdioFileEx.h b/microsip/StdioFileEx.h deleted file mode 100644 index c7dc856c..00000000 --- a/microsip/StdioFileEx.h +++ /dev/null @@ -1,353 +0,0 @@ -// StdioFileEx.h: interface for the CStdioFileEx class. -// -// Version 1.1 23 August 2003. Incorporated fixes from Dennis Jeryd. -// Version 1.3 19 February 2005. Incorporated fixes from Howard J Oh and some of my own. -// Version 1.4 26 February 2005. Fixed stupid screw-up in code from 1.3. -// Version 1.5 18 November 2005. - Incorporated fixes from Andy Goodwin. -// - Allows code page to be specified for reading/writing -// - Properly calculates multibyte buffer size instead of -// assuming lstrlen(s). -// - Should handle UTF8 properly. -// Version 1.6 ??? 2006. - ReadString incorrectly removed \r or \n characters -// immediately preceding line breaks -// Fixed tab problem in these comments! (Perry) -// Made GetMultiByteStringFromUnicodeString input string const -// (Perry) -// Avoided double conversion if code page not set. -// (Konrad Windszus) -// Fixed ASSERT in GetUnicodeStringFromMultiByteString -// (Konrad Windszus) -// Maximum line length restriction removed. Lines of any length -// can now be read thanks to C.B. Falconer's fggets (fgoodgets), -// ably assisted by Ana Sayfa and Dave Kondrad. -// Substantial code reorganisation and tidying. -// _mbstrlen now used everywhere instead of strlen/lstrlen -// to get correct multibyte string length. -// Serious, systematic tests are now included with the code. -// BOM is only stripped off if actually there. -// UTF-8 BOM is now read and written. UTF-8 conversion works. -// -// Copyright David Pritchard 2003-2007. davidpritchard@ctv.es -// -// You can use this class freely, but please keep my ego happy -// by leaving this comment in place. -// -////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_STDIOFILEEX_H__41AFE3CA_25E0_482F_8B00_C40775BCDB81__INCLUDED_) -#define AFX_STDIOFILEEX_H__41AFE3CA_25E0_482F_8B00_C40775BCDB81__INCLUDED_ - -#include "TemplateSmartPtr.h" - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#define MS_COMPILER_VS2005 1400 // v8.0 - -// Make length type ULONGLONG for VS 2005 -#if _MSC_VER < MS_COMPILER_VS2005 // If prior to VS 2005 - typedef unsigned long STDIOEXLONG; -#else - typedef ULONGLONG STDIOEXLONG; -#endif - -#define nUNICODE_BOM 0xFEFF // Unicode "byte order mark" which goes at start of file -#define sNEWLINE _T("\r\n") // New line characters -#define sDEFAULT_UNICODE_FILLER_CHAR '#' // Filler char used when no conversion from Unicode to local code page is possible -#define nSTDIOFILEEX_DEFAULT_BUFFER_SIZE 4096 // Size of default buffer for strings - -// Macro to do post-exception cleanup. Rethrows exception afterwards -#define FINALLY(x) catch(...)\ - {\ - ASSERT(false);\ - x;\ - throw;\ - }\ - x; - -// An adaptation of the supremely handy DELETE_SAFE macro by mandhjo -// (http://www.experts-exchange.com/Programming/Programming_Languages/MFC/Q_10292771.html) -#define DELETE_SAFE_ARRAY(parr) if (parr)\ - {\ - delete [] parr;\ - parr = NULL;\ - } - -class CStdioFileEx: public CStdioFile -{ -public: - CStdioFileEx(); - - virtual BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL ); - virtual BOOL ReadString(CString& rString); - virtual LPTSTR ReadString(LPTSTR lpsz, UINT nMax); - virtual void WriteString( LPCTSTR lpsz ); - STDIOEXLONG GetCharCount(); - virtual STDIOEXLONG Seek(LONGLONG lOff, UINT nFrom); - - bool IsFileUnicodeText() { return m_bIsUnicodeText; } - - // Additional flag to allow Unicode text writing - static const UINT modeWriteUnicode; - - void SetCodePage(IN const UINT nCodePage); - void SetFillerChar(IN const char cFiller); - void SetWriteBOM(IN const bool bWrite); - //void SetUnicode(IN const bool bIsUnicode); - - // static utility functions - - // -------------------------------------------------------------------------------------------- - // - // CStdioFileEx::GetUnicodeStringFromMultiByteString() - // - // -------------------------------------------------------------------------------------------- - // Returns: int - number of chars written (0 means error) - // Parameters: LPCSTR szMultiByteString (IN) Multi-byte input string - // wchar_t* szUnicodeString (OUT) Unicode output string - // size_t nUnicodeBufferSize (IN) Size of Unicode output buffer - // UINT nCodePage (IN) Code page used to perform conversion - // Default = CP_ACP (Get local code page). - // - // Purpose: Gets a Unicode string from a MultiByte string. - // Notes: None. - // Exceptions: None. - // - static int GetUnicodeStringFromMultiByteString(IN LPCSTR szMultiByteString, OUT wchar_t* szUnicodeString, - IN const size_t nUnicodeBufferSize, IN UINT nCodePage=CP_ACP); - - // -------------------------------------------------------------------------------------------- - // - // CStdioFileEx::GetRequiredUnicodeLengthFromMultiByteString() - // - // -------------------------------------------------------------------------------------------- - // Returns: int - number of chars needed - // Parameters: LPCSTR szMultiByteString (IN) Multi-byte input string - // UINT nCodePage (IN) Code page of input string - // Default = CP_ACP (local code page). - // - // Purpose: Gets the length required, in wchar_t values (chars) to convert a MultiByte string to a Unicode string. - // Notes: None. - // Exceptions: None. - // - static int GetRequiredUnicodeLengthFromMultiByteString(IN LPCSTR szMultiByteString, IN UINT nCodePage=CP_ACP OPTIONAL); - - // -------------------------------------------------------------------------------------------- - // - // CStdioFileEx::GetNewUnicodeStringFromMultiByteString() - // - // -------------------------------------------------------------------------------------------- - // Returns: int - number of chars written (0 means error) - // Parameters: LPCSTR szMultiByteString (IN) Multi-byte input string - // CTemplateSmartPtrArray& - // spUnicodeString (IN/OUT) Smart pointer containing default buffer (or NULL) - // on input, and pointing to buffer used for conversion - // on output. A newly allocated buffer will be automatically - // deleted when the smart ptr object is destroyed. - // This allows a default buffer to be declared and used for - // most strings. Dynamic allocation is only performed when - // the default buffer would not be large enough. - // int nDefaultBufferSize (IN) Size of default buffer in smart ptr (may be 0). - // UINT nCodePage (IN) Code page used to perform conversion - // Default = CP_ACP (Get local code page). - // - // Purpose: Gets a Unicode string from a MultiByte string. Calculates the buffer for you and - // allocates it with "new". - // Notes: It's better to ask this function to allocate the buffer for you, because it will - // calculate the correct size. If we just take the number of bytes from the multibyte - // string as the size, we won't be in danger of allocating too little memory, but we - // may well allocate too much. - // - // The use of a smart ptr array combines this flexibility with efficiency. A default buffer can be passed in - // and used wherever is it sufficient to contain the output string. This avoids lots of unnecessary "new"s and - // "delete"s when reading or writing large files. - // Exceptions: None. - // -// static int GetNewUnicodeStringFromMultiByteString(IN LPCSTR szMultiByteString, OUT wchar_t*& pszUnicodeString, -// IN UINT nCodePage=CP_ACP OPTIONAL); - static int GetNewUnicodeStringFromMultiByteString(IN LPCSTR szMultiByteString, IN OUT CTemplateSmartPtrArray& spUnicodeString, IN const int nDefaultBufferSize=0, - IN UINT nCodePage=CP_ACP OPTIONAL); - - // -------------------------------------------------------------------------------------------- - // - // CStdioFileEx::GetMultiByteStringFromUnicodeString() - // - // -------------------------------------------------------------------------------------------- - // Returns: int - number of chars written. 0 if error. - // Parameters: wchar_t * szUnicodeString (IN) Unicode input string - // char* szMultiByteString (OUT) Multibyte output string - // int nMultiByteBufferSize (IN) Multibyte buffer size - // UINT nCodePage (IN) Code page used to perform conversion - // Default = CP_ACP (Get local code page). - // char cFillerChar (IN) Unicode-to-multibyte filler char - // Default = # - // - // Purpose: Gets a MultiByte string from a Unicode string. - // Notes: . - // Exceptions: None. - // - static int GetMultiByteStringFromUnicodeString(IN const wchar_t * szUnicodeString, OUT char* szMultiByteString, - IN const int nMultiByteBufferSize,IN UINT nCodePage=CP_ACP OPTIONAL, - IN char cFillerChar=sDEFAULT_UNICODE_FILLER_CHAR OPTIONAL); - - - //--------------------------------------------------------------------------------------------------- - // - // CStdioFileEx::GetRequiredMultiByteLengthForUnicodeString() - // - //--------------------------------------------------------------------------------------------------- - // Returns: int - no of bytes required - // Parameters: IN const wchar_t * szUnicodeString,int nCodePage=-1, char cFillerChar='#' - // - // Purpose: Obtains the multi-byte buffer size needed to accommodate a converted Unicode string. - // Notes: We can't assume that the buffer length is simply equal to the number of characters - // because that wouldn't accommodate multibyte characters! - // - static int GetRequiredMultiByteLengthForUnicodeString(IN const wchar_t * szUnicodeString,IN UINT nCodePage=CP_ACP OPTIONAL); - - // -------------------------------------------------------------------------------------------- - // - // CStdioFileEx::GetNewMultiByteStringFromUnicodeString() - // - // -------------------------------------------------------------------------------------------- - // Returns: int - number of chars written. 0 if error. - // Parameters: wchar_t * szUnicodeString (IN) Unicode input string - // CTemplateSmartPtrArray& - // spMultiByteString (IN/OUT) Smart pointer containing default buffer (or NULL) - // on input, and pointing to buffer used for conversion - // on output. A newly allocated buffer will be automatically - // deleted when the smart ptr object is destroyed. - // This allows a default buffer to be declared and used for - // most strings. Dynamic allocation is only performed when - // the default buffer would not be large enough. - // int nDefaultBufferSize (IN) Size of default buffer in smart ptr (may be 0). - // UINT nCodePage (IN) Code page used to perform conversion - // Default = CP_ACP (Get local code page). - // char cFillerChar (IN) Unicode-to-multibyte filler char - // Default = # - // - // Purpose: Gets a MultiByte string from a Unicode string. Calculates the buffer for you and - // allocates it with new. - // Notes: It's better to ask this function to allocate the buffer for you, because it will - // calculate the correct size. Multibyte code pages will require larger buffers than - // the normal Western code pages, so we can't just say new char[numchars]! - // - // The use of a smart ptr array combines this flexibility with efficiency. A default buffer can be passed in - // and used wherever is it sufficient to contain the output string. This avoids lots of unnecessary "new"s and - // "delete"s when reading or writing large files. - // Exceptions: None. - // - static int GetNewMultiByteStringFromUnicodeString(IN const wchar_t * szUnicodeString,IN OUT CTemplateSmartPtrArray& spMultiByteString, IN const int nDefaultBufferSize=0,IN UINT nCodePage=CP_ACP OPTIONAL, - IN char cFillerChar=sDEFAULT_UNICODE_FILLER_CHAR OPTIONAL); - - - //--------------------------------------------------------------------------------------------------- - // - // CStdioFileEx::GetNewUTF8StringFromUnicodeString() - // - //--------------------------------------------------------------------------------------------------- - // Returns: bool - true if successful, false if it fails. - // Parameters: const wchar_t* szUnicodeString (IN) Input Unicode string - // unsigned char*& pszUTF8String (OUT) Receives a ptr. If the function returns - // successfully. - // the ptr points to the output string - // - // Purpose: Does conversion from Unicode to UTF8. Allocates memory for the output string - // Notes: Culled from http://www.bytemycode.com/snippets/snippet/438/ - // Contributed by Dean - // Reformatted, commented and adapted by David Pritchard - // - //static bool GetNewUTF8StringFromUnicodeString(IN const wchar_t* szUnicodeString,OUT unsigned char*& pszUTF8String); - - // -------------------------------------------------------------------------------------------- - // - // CStdioFileEx::IsFileUnicode() - // - // -------------------------------------------------------------------------------------------- - // Returns: bool - // Parameters: const CString& sFilePath - // - // Purpose: Determines whether a file is Unicode by reading the first character and detecting - // whether it's the Unicode byte marker. - // Notes: None. - // Exceptions: None. - // - static bool IsFileUnicode(const CString& sFilePath); - - static UINT GetCurrentLocaleCodePage(); - -protected: - UINT ProcessFlags(UINT& nOpenFlags);//, bool& bCheckForUnicodeOnOpen); -#ifdef _UNICODE - BOOL ReadUnicodeLine(OUT CString& sOutputLine); - BOOL ReadMultiByteLine(OUT CString& sOutputLine); - void WriteUnicodeLine(IN LPCTSTR sInputLine); - void WriteMultiByteLine(IN LPCTSTR sInputLine); -#else - BOOL ReadUnicodeLine(OUT CString& sOutputLine); - BOOL ReadMultiByteLine(OUT CString& sOutputLine); - void WriteUnicodeLine(IN LPCTSTR sInputLine); - void WriteMultiByteLine(IN LPCTSTR sInputLine); -#endif - - bool m_bIsUnicodeText; - UINT m_nFlags; - int m_nFileCodePage; - char m_cUnicodeFillerChar; - bool m_bWriteBOM; - bool m_bReadBOM; - wchar_t m_arrUnicodeDefaultBuffer[nSTDIOFILEEX_DEFAULT_BUFFER_SIZE]; // default buffer for strings; used to avoid dynamic allocation where possible - char m_arrMultibyteDefaultBuffer[nSTDIOFILEEX_DEFAULT_BUFFER_SIZE]; // default buffer for strings; used to avoid dynamic allocation where possible - bool m_bCheckFilePos; -}; - -// Helper class to switch code pages (for multibyte functions) and then guarantee -// the restoration of the original page even in the event of exceptions. -// Note that we are switching the MULTIBYTE code page here, as opposed to the -// LOCALE code page -- yes, there is a difference, but only insofar as the switch -// affects OS functions. The code pages are really the same code pages, so we can -// mix and match, but if we switch the LOCALE cp certain functions will be affected, -// and if we switch the MB cp, other functions will be affected. So it's important to -// decide which functions we're using. I'm using _mbslen (affected by the MB code page), -// as opposed to _mbstrlen (affected by the locale page). ggets also makes used of -// _mbschr, also affected by the multibyte page. Be careful with these obscure -// shenanigans if you decide to use other multibyte functions in your code. -/*class CMBCodePageSwitcher -{ -public: - // Constructor - CMBCodePageSwitcher(IN const int nTargetCodePage) - { - m_nOriginalCodePage = -1; - - // If we don't have a specific target code page, do nothing - if (nTargetCodePage != -1) - { - // Get current locale page and store (always? even if 0?) - m_nOriginalCodePage = _getmbcp(); - - // Code page can't be UTF8 or UTF7! - ASSERT(nTargetCodePage != CP_UTF7 && nTargetCodePage != CP_UTF8); - - // Switch code page for multibyte functions - VERIFY (_setmbcp(nTargetCodePage) == 0); - } - } - - ~CMBCodePageSwitcher() - { - // Put things back the way they were if they were changed - if (m_nOriginalCodePage > -1) - { - // Try to restore MB code page, but don't check for success - // because 0 may fail (?) - VERIFY( _setmbcp(m_nOriginalCodePage) == 0 ); - } - } - -private: - int m_nOriginalCodePage; -};*/ - -#endif // !defined(AFX_STDIOFILEEX_H__41AFE3CA_25E0_482F_8B00_C40775BCDB81__INCLUDED_) diff --git a/microsip/TemplateSmartPtr.h b/microsip/TemplateSmartPtr.h deleted file mode 100644 index fcf553de..00000000 --- a/microsip/TemplateSmartPtr.h +++ /dev/null @@ -1,135 +0,0 @@ -/*************************************************************************** - TemplateSmartPtr.h: header file - - Header of smart ptr template class - -****************************************************************************/ - -#ifndef TEMPLATESMARTPTR_H -#define TEMPLATESMARTPTR_H - -#define bTEMPLATESMARTPTR_NOTOWNED false - -template class CTemplateSmartPtrArray -{ -public: - CTemplateSmartPtrArray() - { - m_pBuffer = NULL;/* For later construction*/; - m_bOwnObject = true; - } - CTemplateSmartPtrArray(IN const int nArrayLength) - { - m_bOwnObject = true; - InitBuffer(nArrayLength); - } - CTemplateSmartPtrArray(TYPE* pBuffer, IN const bool bOwned=true) - { - m_pBuffer = NULL; - Assign(pBuffer, bOwned); - } - virtual ~CTemplateSmartPtrArray() - { - // Auto-delete, but only if we own it! - if (m_pBuffer && m_bOwnObject) - { - delete [] m_pBuffer; - } - } - void InitBuffer(IN const int nArrayLength) - { - m_pBuffer = new TYPE[nArrayLength]; - } - void Assign(TYPE* pBuffer, IN const bool bOwned=true) - { - if (m_pBuffer && m_bOwnObject) - { - delete []m_pBuffer; - } - m_pBuffer = pBuffer; - m_bOwnObject = bOwned; - } - TYPE* GetBuffer() - { - ASSERT(m_pBuffer); - return m_pBuffer; - } - bool IsNull() - { - return (m_pBuffer == NULL); - } - // Determine who gets to delete the buffer - void SetBufferOwnership(IN const bool bOwnObject) - { - m_bOwnObject = bOwnObject; - } - - TYPE* m_pBuffer; - bool m_bOwnObject; -}; - -template class CTemplateSmartPtr -{ -public: - CTemplateSmartPtr() - { - m_bOwnObject = true; - Init(); - } - CTemplateSmartPtr(TYPE* pThing) // also permits NULL initialisation for later assigment - { - m_bOwnObject = true; - m_pThing = NULL; - Assign(pThing); - } - virtual ~CTemplateSmartPtr() - { - // Auto-delete, but only if we own it! - if (m_pThing && m_bOwnObject) - { - delete m_pThing; - } - } - - void Init() - { - m_pThing = new TYPE; - } - void Assign(TYPE* pThing) - { - if (m_pThing) - { - delete m_pThing; - } - m_pThing = pThing; - } - void Detach() - { - // Stop the smart pointer managing the object - m_pThing = NULL; - } - bool IsNull() - { - return (m_pThing == NULL); - } - TYPE* GetPtr() - { - ASSERT(m_pThing); - return GetPtrSafe(); - } - TYPE* GetPtrSafe() - { - // Don't assert. That's the only "safe" thing about it - return m_pThing; - } - void SetOwnObject(IN const bool bOwnObject) - { - m_bOwnObject = bOwnObject; - } - - TYPE* m_pThing; - bool m_bOwnObject; -}; - - -#endif \ No newline at end of file diff --git a/microsip/Transfer.cpp b/microsip/Transfer.cpp deleted file mode 100644 index 9259cecd..00000000 --- a/microsip/Transfer.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "Transfer.h" -#include "mainDlg.h" -#include "langpack.h" - -Transfer::Transfer(CWnd* pParent /*=NULL*/) -: CDialog(Transfer::IDD, pParent) -{ - Create (IDD, pParent); -} - -Transfer::~Transfer(void) -{ -} - -int Transfer::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (langPack.rtl) { - ModifyStyleEx(0,WS_EX_LAYOUTRTL); - } - return 0; -} - -BOOL Transfer::OnInitDialog() -{ - CDialog::OnInitDialog(); - TranslateDialog(this->m_hWnd); - CComboBox *combobox = (CComboBox*)GetDlgItem(IDC_NUMBER); - CListCtrl *list= (CListCtrl*)mainDlg->pageContacts->GetDlgItem(IDC_CONTACTS); - if (mainDlg->pageContacts->isFiltered()) { - mainDlg->pageContacts->filterReset(); - } - int count = list->GetItemCount(); - for (int i=0;iGetItemData(i); - int n = combobox->AddString(pContact->name); - CString *number = new CString(pContact->number); - combobox->SetItemData(n, (DWORD_PTR)number); - } - combobox->SetWindowText(lastTransferNumber); - return TRUE; -} - -void Transfer::OnDestroy() -{ - mainDlg->transferDlg = NULL; - CComboBox *combobox = (CComboBox*)GetDlgItem(IDC_NUMBER); - int n = combobox->GetCount(); - for (int i=0;iGetItemData(i); - delete number; - } - CDialog::OnDestroy(); -} - -void Transfer::PostNcDestroy() -{ - CDialog::PostNcDestroy(); - delete this; -} - -BEGIN_MESSAGE_MAP(Transfer, CDialog) - ON_WM_CREATE() - ON_WM_CLOSE() - ON_WM_DESTROY() - ON_BN_CLICKED(IDCANCEL, &Transfer::OnBnClickedCancel) - ON_BN_CLICKED(IDOK, &Transfer::OnBnClickedOk) -END_MESSAGE_MAP() - - -void Transfer::OnClose() -{ - if (mainDlg->transferDlg) { - DestroyWindow(); - } -} - -void Transfer::OnBnClickedCancel() -{ - OnClose(); -} - -void Transfer::SetAction(msip_action action) -{ - this->action = action; - if (action == MSIP_ACTION_TRANSFER) { - SetWindowText(Translate(_T("Call Transfer"))); - } - if (action == MSIP_ACTION_INVITE) { - SetWindowText(Translate(_T("Invite to Conference"))); - } -} - -void Transfer::OnBnClickedOk() -{ - CString number; - CComboBox *combobox = (CComboBox*)GetDlgItem(IDC_NUMBER); - int i = combobox->GetCurSel(); - if (i == -1) { - combobox->GetWindowText(number); - number.Trim(); - } else { - number = * (CString *)combobox->GetItemData(i); - } - if (!number.IsEmpty()) { - lastTransferNumber = number; - mainDlg->messagesDlg->CallAction(action, number); - OnClose(); - } -} diff --git a/microsip/Transfer.h b/microsip/Transfer.h deleted file mode 100644 index 978f5452..00000000 --- a/microsip/Transfer.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#pragma once - -#include "resource.h" -#include "const.h" - -enum msip_action { - MSIP_ACTION_TRANSFER, - MSIP_ACTION_INVITE, -}; - -class Transfer : - public CDialog -{ -public: - Transfer(CWnd* pParent = NULL); // standard constructor - ~Transfer(); - enum { IDD = IDD_TRANSFER }; - msip_action action; - void SetAction(msip_action action); -protected: - afx_msg void OnDestroy(); - virtual BOOL OnInitDialog(); - virtual void PostNcDestroy(); - DECLARE_MESSAGE_MAP() -public: - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnClose(); - afx_msg void OnBnClickedCancel(); - afx_msg void OnBnClickedOk(); -}; diff --git a/microsip/VisualStylesXP.cpp b/microsip/VisualStylesXP.cpp deleted file mode 100644 index 9f2cc5eb..00000000 --- a/microsip/VisualStylesXP.cpp +++ /dev/null @@ -1,458 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2001-2002 by David Yuheng Zhao -// -// Distribute and change freely, except: don't remove my name from the source -// -// No warrantee of any kind, express or implied, is included with this -// software; use at your own risk, responsibility for damages (if any) to -// anyone resulting from the use of this software rests entirely with the -// user. -// -// Partly based on the _ThemeHelper struct in MFC7.0 source code (winctrl3.cpp), -// and the difference is that this implementation wraps the full set of -// visual style APIs from the platform SDK August 2001 -// -// If you have any questions, I can be reached as follows: -// yuheng_zhao@yahoo.com -// -// -// How to use: -// Instead of calling the API directly, -// OpenThemeData(...); -// use the global variable -// g_xpStyle.OpenThemeData(...); -// -///////////////////////////////////////////////////////////////////////////// -#include "stdafx.h" -#include "VisualStylesXP.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - - -CVisualStylesXP g_xpStyle; - -HMODULE CVisualStylesXP::m_hThemeDll = NULL; - -CVisualStylesXP::CVisualStylesXP(void) -{ - m_hThemeDll = LoadLibrary(_T("UxTheme.dll")); -} - -CVisualStylesXP::~CVisualStylesXP(void) -{ - if (m_hThemeDll != NULL) - VERIFY( FreeLibrary(m_hThemeDll) ); - m_hThemeDll = NULL; -} - -void* CVisualStylesXP::GetProc(LPCSTR szProc, void* pfnFail) -{ - void* pRes = pfnFail; - if (m_hThemeDll != NULL){ - void* pRet = GetProcAddress(m_hThemeDll, szProc); - if (pRet != NULL) - pRes = pRet; - } - return pRes; -} - -HTHEME CVisualStylesXP::OpenThemeData(HWND hwnd, LPCWSTR pszClassList) -{ - static PFNOPENTHEMEDATA pfn = NULL; - if (pfn == NULL) - pfn = (PFNOPENTHEMEDATA)GetProc("OpenThemeData", (void*)OpenThemeDataFail); - return (*pfn)(hwnd, pszClassList); -} - -HRESULT CVisualStylesXP::CloseThemeData(HTHEME hTheme) -{ - static PFNCLOSETHEMEDATA pfn = NULL; - if (pfn == NULL) - pfn = (PFNCLOSETHEMEDATA)GetProc("CloseThemeData", (void*)CloseThemeDataFail); - return (*pfn)(hTheme); -} - -HRESULT CVisualStylesXP::DrawThemeBackground(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect) -{ - static PFNDRAWTHEMEBACKGROUND pfn = NULL; - if (pfn == NULL) - pfn = (PFNDRAWTHEMEBACKGROUND)GetProc("DrawThemeBackground", (void*)DrawThemeBackgroundFail); - return (*pfn)(hTheme, hdc, iPartId, iStateId, pRect, pClipRect); -} - -HRESULT CVisualStylesXP::DrawThemeText(HTHEME hTheme, HDC hdc, int iPartId, - int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags, - DWORD dwTextFlags2, const RECT *pRect) -{ - static PFNDRAWTHEMETEXT pfn = NULL; - if (pfn == NULL) - pfn = (PFNDRAWTHEMETEXT)GetProc("DrawThemeText", (void*)DrawThemeTextFail); - return (*pfn)(hTheme, hdc, iPartId, iStateId, pszText, iCharCount, dwTextFlags, dwTextFlags2, pRect); -} -HRESULT CVisualStylesXP::GetThemeBackgroundContentRect(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, const RECT *pBoundingRect, - RECT *pContentRect) -{ - static PFNGETTHEMEBACKGROUNDCONTENTRECT pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEBACKGROUNDCONTENTRECT)GetProc("GetThemeBackgroundContentRect", (void*)GetThemeBackgroundContentRectFail); - return (*pfn)(hTheme, hdc, iPartId, iStateId, pBoundingRect, pContentRect); -} - -HRESULT CVisualStylesXP::GetThemeBackgroundExtent(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, const RECT *pContentRect, - RECT *pExtentRect) -{ - static PFNGETTHEMEBACKGROUNDEXTENT pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEBACKGROUNDEXTENT)GetProc("GetThemeBackgroundExtent", (void*)GetThemeBackgroundExtentFail); - return (*pfn)(hTheme, hdc, iPartId, iStateId, pContentRect, pExtentRect); -} - -HRESULT CVisualStylesXP::GetThemePartSize(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, RECT * pRect, enum THEMESIZE eSize, SIZE *psz) -{ - static PFNGETTHEMEPARTSIZE pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEPARTSIZE)GetProc("GetThemePartSize", (void*)GetThemePartSizeFail); - return (*pfn)(hTheme, hdc, iPartId, iStateId, pRect, eSize, psz); -} - -HRESULT CVisualStylesXP::GetThemeTextExtent(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, - DWORD dwTextFlags, const RECT *pBoundingRect, RECT *pExtentRect) -{ - static PFNGETTHEMETEXTEXTENT pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMETEXTEXTENT)GetProc("GetThemeTextExtent", (void*)GetThemeTextExtentFail); - return (*pfn)(hTheme, hdc, iPartId, iStateId, pszText, iCharCount, dwTextFlags, pBoundingRect, pExtentRect); -} - -HRESULT CVisualStylesXP::GetThemeTextMetrics(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, TEXTMETRIC* ptm) -{ - static PFNGETTHEMETEXTMETRICS pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMETEXTMETRICS)GetProc("GetThemeTextMetrics", (void*)GetThemeTextMetricsFail); - return (*pfn)(hTheme, hdc, iPartId, iStateId, ptm); -} - -HRESULT CVisualStylesXP::GetThemeBackgroundRegion(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, const RECT *pRect, HRGN *pRegion) -{ - static PFNGETTHEMEBACKGROUNDREGION pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEBACKGROUNDREGION)GetProc("GetThemeBackgroundRegion", (void*)GetThemeBackgroundRegionFail); - return (*pfn)(hTheme, hdc, iPartId, iStateId, pRect, pRegion); -} - -HRESULT CVisualStylesXP::HitTestThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, - int iStateId, DWORD dwOptions, const RECT *pRect, HRGN hrgn, - POINT ptTest, WORD *pwHitTestCode) -{ - static PFNHITTESTTHEMEBACKGROUND pfn = NULL; - if (pfn == NULL) - pfn = (PFNHITTESTTHEMEBACKGROUND)GetProc("HitTestThemeBackground", (void*)HitTestThemeBackgroundFail); - return (*pfn)(hTheme, hdc, iPartId, iStateId, dwOptions, pRect, hrgn, ptTest, pwHitTestCode); -} - -HRESULT CVisualStylesXP::DrawThemeEdge(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, - const RECT *pDestRect, UINT uEdge, UINT uFlags, RECT *pContentRect) -{ - static PFNDRAWTHEMEEDGE pfn = NULL; - if (pfn == NULL) - pfn = (PFNDRAWTHEMEEDGE)GetProc("DrawThemeEdge", (void*)DrawThemeEdgeFail); - return (*pfn)(hTheme, hdc, iPartId, iStateId, pDestRect, uEdge, uFlags, pContentRect); -} - -HRESULT CVisualStylesXP::DrawThemeIcon(HTHEME hTheme, HDC hdc, int iPartId, - int iStateId, const RECT *pRect, HIMAGELIST himl, int iImageIndex) -{ - static PFNDRAWTHEMEICON pfn = NULL; - if (pfn == NULL) - pfn = (PFNDRAWTHEMEICON)GetProc("DrawThemeIcon", (void*)DrawThemeIconFail); - return (*pfn)(hTheme, hdc, iPartId, iStateId, pRect, himl, iImageIndex); -} - -BOOL CVisualStylesXP::IsThemePartDefined(HTHEME hTheme, int iPartId, int iStateId) -{ - static PFNISTHEMEPARTDEFINED pfn = NULL; - if (pfn == NULL) - pfn = (PFNISTHEMEPARTDEFINED)GetProc("IsThemePartDefined", (void*)IsThemePartDefinedFail); - return (*pfn)(hTheme, iPartId, iStateId); -} - -BOOL CVisualStylesXP::IsThemeBackgroundPartiallyTransparent(HTHEME hTheme, int iPartId, int iStateId) -{ - static PFNISTHEMEBACKGROUNDPARTIALLYTRANSPARENT pfn = NULL; - if (pfn == NULL) - pfn = (PFNISTHEMEBACKGROUNDPARTIALLYTRANSPARENT)GetProc("IsThemeBackgroundPartiallyTransparent", (void*)IsThemeBackgroundPartiallyTransparentFail); - return (*pfn)(hTheme, iPartId, iStateId); -} - -HRESULT CVisualStylesXP::GetThemeColor(HTHEME hTheme, int iPartId, int iStateId, int iPropId, COLORREF *pColor) -{ - static PFNGETTHEMECOLOR pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMECOLOR)GetProc("GetThemeColor", (void*)GetThemeColorFail); - return (*pfn)(hTheme, iPartId, iStateId, iPropId, pColor); -} - -HRESULT CVisualStylesXP::GetThemeMetric(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, int *piVal) -{ - static PFNGETTHEMEMETRIC pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEMETRIC)GetProc("GetThemeMetric", (void*)GetThemeMetricFail); - return (*pfn)(hTheme, hdc, iPartId, iStateId, iPropId, piVal); -} - -HRESULT CVisualStylesXP::GetThemeString(HTHEME hTheme, int iPartId, int iStateId, int iPropId, - LPWSTR pszBuff, int cchMaxBuffChars) -{ - static PFNGETTHEMESTRING pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMESTRING)GetProc("GetThemeString", (void*)GetThemeStringFail); - return (*pfn)(hTheme, iPartId, iStateId, iPropId, pszBuff, cchMaxBuffChars); -} - -HRESULT CVisualStylesXP::GetThemeBool(HTHEME hTheme, int iPartId, int iStateId, int iPropId, BOOL *pfVal) -{ - static PFNGETTHEMEBOOL pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEBOOL)GetProc("GetThemeBool", (void*)GetThemeBoolFail); - return (*pfn)(hTheme, iPartId, iStateId, iPropId, pfVal); -} - -HRESULT CVisualStylesXP::GetThemeInt(HTHEME hTheme, int iPartId, int iStateId, int iPropId, int *piVal) -{ - static PFNGETTHEMEINT pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEINT)GetProc("GetThemeInt", (void*)GetThemeIntFail); - return (*pfn)(hTheme, iPartId, iStateId, iPropId, piVal); -} - -HRESULT CVisualStylesXP::GetThemeEnumValue(HTHEME hTheme, int iPartId, int iStateId, int iPropId, int *piVal) -{ - static PFNGETTHEMEENUMVALUE pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEENUMVALUE)GetProc("GetThemeEnumValue", (void*)GetThemeEnumValueFail); - return (*pfn)(hTheme, iPartId, iStateId, iPropId, piVal); -} - -HRESULT CVisualStylesXP::GetThemePosition(HTHEME hTheme, int iPartId, int iStateId, int iPropId, POINT *pPoint) -{ - static PFNGETTHEMEPOSITION pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEPOSITION)GetProc("GetThemePosition", (void*)GetThemePositionFail); - return (*pfn)(hTheme, iPartId, iStateId, iPropId, pPoint); -} - -HRESULT CVisualStylesXP::GetThemeFont(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, LOGFONT *pFont) -{ - static PFNGETTHEMEFONT pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEFONT)GetProc("GetThemeFont", (void*)GetThemeFontFail); - return (*pfn)(hTheme, hdc, iPartId, iStateId, iPropId, pFont); -} - -HRESULT CVisualStylesXP::GetThemeRect(HTHEME hTheme, int iPartId, int iStateId, int iPropId, RECT *pRect) -{ - static PFNGETTHEMERECT pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMERECT)GetProc("GetThemeRect", (void*)GetThemeRectFail); - return (*pfn)(hTheme, iPartId, iStateId, iPropId, pRect); -} - -HRESULT CVisualStylesXP::GetThemeMargins(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, RECT *prc, - MARGINS *pMargins) -{ - static PFNGETTHEMEMARGINS pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEMARGINS)GetProc("GetThemeMargins", (void*)GetThemeMarginsFail); - return (*pfn)(hTheme, hdc, iPartId, iStateId, iPropId, prc, pMargins); -} - -HRESULT CVisualStylesXP::GetThemeIntList(HTHEME hTheme, int iPartId, int iStateId, int iPropId, INTLIST *pIntList) -{ - static PFNGETTHEMEINTLIST pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEINTLIST)GetProc("GetThemeIntList", (void*)GetThemeIntListFail); - return (*pfn)(hTheme, iPartId, iStateId, iPropId, pIntList); -} - -HRESULT CVisualStylesXP::GetThemePropertyOrigin(HTHEME hTheme, int iPartId, int iStateId, int iPropId, - enum PROPERTYORIGIN *pOrigin) -{ - static PFNGETTHEMEPROPERTYORIGIN pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEPROPERTYORIGIN)GetProc("GetThemePropertyOrigin", (void*)GetThemePropertyOriginFail); - return (*pfn)(hTheme, iPartId, iStateId, iPropId, pOrigin); -} - -HRESULT CVisualStylesXP::SetWindowTheme(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList) -{ - static PFNSETWINDOWTHEME pfn = NULL; - if (pfn == NULL) - pfn = (PFNSETWINDOWTHEME)GetProc("SetWindowTheme", (void*)SetWindowThemeFail); - return (*pfn)(hwnd, pszSubAppName, pszSubIdList); -} - -HRESULT CVisualStylesXP::GetThemeFilename(HTHEME hTheme, int iPartId, int iStateId, int iPropId, - LPWSTR pszThemeFileName, int cchMaxBuffChars) -{ - static PFNGETTHEMEFILENAME pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEFILENAME)GetProc("GetThemeFilename", (void*)GetThemeFilenameFail); - return (*pfn)(hTheme, iPartId, iStateId, iPropId, pszThemeFileName, cchMaxBuffChars); -} - -COLORREF CVisualStylesXP::GetThemeSysColor(HTHEME hTheme, int iColorId) -{ - static PFNGETTHEMESYSCOLOR pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMESYSCOLOR)GetProc("GetThemeSysColor", (void*)GetThemeSysColorFail); - return (*pfn)(hTheme, iColorId); -} - -HBRUSH CVisualStylesXP::GetThemeSysColorBrush(HTHEME hTheme, int iColorId) -{ - static PFNGETTHEMESYSCOLORBRUSH pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMESYSCOLORBRUSH)GetProc("GetThemeSysColorBrush", (void*)GetThemeSysColorBrushFail); - return (*pfn)(hTheme, iColorId); -} - -BOOL CVisualStylesXP::GetThemeSysBool(HTHEME hTheme, int iBoolId) -{ - static PFNGETTHEMESYSBOOL pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMESYSBOOL)GetProc("GetThemeSysBool", (void*)GetThemeSysBoolFail); - return (*pfn)(hTheme, iBoolId); -} - -int CVisualStylesXP::GetThemeSysSize(HTHEME hTheme, int iSizeId) -{ - static PFNGETTHEMESYSSIZE pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMESYSSIZE)GetProc("GetThemeSysSize", (void*)GetThemeSysSizeFail); - return (*pfn)(hTheme, iSizeId); -} - -HRESULT CVisualStylesXP::GetThemeSysFont(HTHEME hTheme, int iFontId, LOGFONT *plf) -{ - static PFNGETTHEMESYSFONT pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMESYSFONT)GetProc("GetThemeSysFont", (void*)GetThemeSysFontFail); - return (*pfn)(hTheme, iFontId, plf); -} - -HRESULT CVisualStylesXP::GetThemeSysString(HTHEME hTheme, int iStringId, LPWSTR pszStringBuff, int cchMaxStringChars) -{ - static PFNGETTHEMESYSSTRING pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMESYSSTRING)GetProc("GetThemeSysString", (void*)GetThemeSysStringFail); - return (*pfn)(hTheme, iStringId, pszStringBuff, cchMaxStringChars); -} - -HRESULT CVisualStylesXP::GetThemeSysInt(HTHEME hTheme, int iIntId, int *piValue) -{ - static PFNGETTHEMESYSINT pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMESYSINT)GetProc("GetThemeSysInt", (void*)GetThemeSysIntFail); - return (*pfn)(hTheme, iIntId, piValue); -} - -BOOL CVisualStylesXP::IsThemeActive() -{ - static PFNISTHEMEACTIVE pfn = NULL; - if (pfn == NULL) - pfn = (PFNISTHEMEACTIVE)GetProc("IsThemeActive", (void*)IsThemeActiveFail); - return (*pfn)(); -} - -BOOL CVisualStylesXP::IsAppThemed() -{ - static PFNISAPPTHEMED pfn = NULL; - if (pfn == NULL) - pfn = (PFNISAPPTHEMED)GetProc("IsAppThemed", (void*)IsAppThemedFail); - return (*pfn)(); -} - -HTHEME CVisualStylesXP::GetWindowTheme(HWND hwnd) -{ - static PFNGETWINDOWTHEME pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETWINDOWTHEME)GetProc("GetWindowTheme", (void*)GetWindowThemeFail); - return (*pfn)(hwnd); -} - -HRESULT CVisualStylesXP::EnableThemeDialogTexture(HWND hwnd, DWORD dwFlags) -{ - static PFNENABLETHEMEDIALOGTEXTURE pfn = NULL; - if (pfn == NULL) - pfn = (PFNENABLETHEMEDIALOGTEXTURE)GetProc("EnableThemeDialogTexture", (void*)EnableThemeDialogTextureFail); - return (*pfn)(hwnd, dwFlags); -} - -BOOL CVisualStylesXP::IsThemeDialogTextureEnabled(HWND hwnd) -{ - static PFNISTHEMEDIALOGTEXTUREENABLED pfn = NULL; - if (pfn == NULL) - pfn = (PFNISTHEMEDIALOGTEXTUREENABLED)GetProc("IsThemeDialogTextureEnabled", (void*)IsThemeDialogTextureEnabledFail); - return (*pfn)(hwnd); -} - -DWORD CVisualStylesXP::GetThemeAppProperties() -{ - static PFNGETTHEMEAPPPROPERTIES pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEAPPPROPERTIES)GetProc("GetThemeAppProperties", (void*)GetThemeAppPropertiesFail); - return (*pfn)(); -} - -void CVisualStylesXP::SetThemeAppProperties(DWORD dwFlags) -{ - static PFNSETTHEMEAPPPROPERTIES pfn = NULL; - if (pfn == NULL) - pfn = (PFNSETTHEMEAPPPROPERTIES)GetProc("SetThemeAppProperties", (void*)SetThemeAppPropertiesFail); - (*pfn)(dwFlags); -} - -HRESULT CVisualStylesXP::GetCurrentThemeName(LPWSTR pszThemeFileName, int cchMaxNameChars, - LPWSTR pszColorBuff, int cchMaxColorChars, - LPWSTR pszSizeBuff, int cchMaxSizeChars) -{ - static PFNGETCURRENTTHEMENAME pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETCURRENTTHEMENAME)GetProc("GetCurrentThemeName", (void*)GetCurrentThemeNameFail); - return (*pfn)(pszThemeFileName, cchMaxNameChars, pszColorBuff, cchMaxColorChars, pszSizeBuff, cchMaxSizeChars); -} - -HRESULT CVisualStylesXP::GetThemeDocumentationProperty(LPCWSTR pszThemeName, LPCWSTR pszPropertyName, - LPWSTR pszValueBuff, int cchMaxValChars) -{ - static PFNGETTHEMEDOCUMENTATIONPROPERTY pfn = NULL; - if (pfn == NULL) - pfn = (PFNGETTHEMEDOCUMENTATIONPROPERTY)GetProc("GetThemeDocumentationProperty", (void*)GetThemeDocumentationPropertyFail); - return (*pfn)(pszThemeName, pszPropertyName, pszValueBuff, cchMaxValChars); -} - -HRESULT CVisualStylesXP::DrawThemeParentBackground(HWND hwnd, HDC hdc, RECT* prc) -{ - static PFNDRAWTHEMEPARENTBACKGROUND pfn = NULL; - if (pfn == NULL) - pfn = (PFNDRAWTHEMEPARENTBACKGROUND)GetProc("DrawThemeParentBackground", (void*)DrawThemeParentBackgroundFail); - return (*pfn)(hwnd, hdc, prc); -} - -HRESULT CVisualStylesXP::EnableTheming(BOOL fEnable) -{ - static PFNENABLETHEMING pfn = NULL; - if (pfn == NULL) - pfn = (PFNENABLETHEMING)GetProc("EnableTheming", (void*)EnableThemingFail); - return (*pfn)(fEnable); -} diff --git a/microsip/VisualStylesXP.h b/microsip/VisualStylesXP.h deleted file mode 100644 index a4f5d2b1..00000000 --- a/microsip/VisualStylesXP.h +++ /dev/null @@ -1,246 +0,0 @@ -#pragma once - -#include -#include - -#pragma warning(disable:4100) // unreferenced formal parameter -class CVisualStylesXP -{ -public: - CVisualStylesXP(void); - ~CVisualStylesXP(void); - - HTHEME OpenThemeData(HWND hwnd, LPCWSTR pszClassList); - HRESULT CloseThemeData(HTHEME hTheme); - HRESULT DrawThemeBackground(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect); - HRESULT DrawThemeText(HTHEME hTheme, HDC hdc, int iPartId, - int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags, - DWORD dwTextFlags2, const RECT *pRect); - HRESULT GetThemeBackgroundContentRect(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, const RECT *pBoundingRect, - RECT *pContentRect); - HRESULT GetThemeBackgroundExtent(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, const RECT *pContentRect, - RECT *pExtentRect); - HRESULT GetThemePartSize(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, RECT * pRect, enum THEMESIZE eSize, SIZE *psz); - HRESULT GetThemeTextExtent(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, - DWORD dwTextFlags, const RECT *pBoundingRect, - RECT *pExtentRect); - HRESULT GetThemeTextMetrics(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, TEXTMETRIC* ptm); - HRESULT GetThemeBackgroundRegion(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, const RECT *pRect, HRGN *pRegion); - HRESULT HitTestThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, - int iStateId, DWORD dwOptions, const RECT *pRect, HRGN hrgn, - POINT ptTest, WORD *pwHitTestCode); - HRESULT DrawThemeEdge(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, - const RECT *pDestRect, UINT uEdge, UINT uFlags, RECT *pContentRect); - HRESULT DrawThemeIcon(HTHEME hTheme, HDC hdc, int iPartId, - int iStateId, const RECT *pRect, HIMAGELIST himl, int iImageIndex); - BOOL IsThemePartDefined(HTHEME hTheme, int iPartId, - int iStateId); - BOOL IsThemeBackgroundPartiallyTransparent(HTHEME hTheme, - int iPartId, int iStateId); - HRESULT GetThemeColor(HTHEME hTheme, int iPartId, - int iStateId, int iPropId, COLORREF *pColor); - HRESULT GetThemeMetric(HTHEME hTheme, HDC hdc, int iPartId, - int iStateId, int iPropId, int *piVal); - HRESULT GetThemeString(HTHEME hTheme, int iPartId, - int iStateId, int iPropId, LPWSTR pszBuff, int cchMaxBuffChars); - HRESULT GetThemeBool(HTHEME hTheme, int iPartId, - int iStateId, int iPropId, BOOL *pfVal); - HRESULT GetThemeInt(HTHEME hTheme, int iPartId, - int iStateId, int iPropId, int *piVal); - HRESULT GetThemeEnumValue(HTHEME hTheme, int iPartId, - int iStateId, int iPropId, int *piVal); - HRESULT GetThemePosition(HTHEME hTheme, int iPartId, - int iStateId, int iPropId, POINT *pPoint); - HRESULT GetThemeFont(HTHEME hTheme, HDC hdc, int iPartId, - int iStateId, int iPropId, LOGFONT *pFont); - HRESULT GetThemeRect(HTHEME hTheme, int iPartId, - int iStateId, int iPropId, RECT *pRect); - HRESULT GetThemeMargins(HTHEME hTheme, HDC hdc, int iPartId, - int iStateId, int iPropId, RECT *prc, MARGINS *pMargins); - HRESULT GetThemeIntList(HTHEME hTheme, int iPartId, - int iStateId, int iPropId, INTLIST *pIntList); - HRESULT GetThemePropertyOrigin(HTHEME hTheme, int iPartId, - int iStateId, int iPropId, enum PROPERTYORIGIN *pOrigin); - HRESULT SetWindowTheme(HWND hwnd, LPCWSTR pszSubAppName, - LPCWSTR pszSubIdList); - HRESULT GetThemeFilename(HTHEME hTheme, int iPartId, - int iStateId, int iPropId, LPWSTR pszThemeFileName, int cchMaxBuffChars); - COLORREF GetThemeSysColor(HTHEME hTheme, int iColorId); - HBRUSH GetThemeSysColorBrush(HTHEME hTheme, int iColorId); - BOOL GetThemeSysBool(HTHEME hTheme, int iBoolId); - int GetThemeSysSize(HTHEME hTheme, int iSizeId); - HRESULT GetThemeSysFont(HTHEME hTheme, int iFontId, LOGFONT *plf); - HRESULT GetThemeSysString(HTHEME hTheme, int iStringId, - LPWSTR pszStringBuff, int cchMaxStringChars); - HRESULT GetThemeSysInt(HTHEME hTheme, int iIntId, int *piValue); - BOOL IsThemeActive(); - BOOL IsAppThemed(); - HTHEME GetWindowTheme(HWND hwnd); - HRESULT EnableThemeDialogTexture(HWND hwnd, DWORD dwFlags); - BOOL IsThemeDialogTextureEnabled(HWND hwnd); - DWORD GetThemeAppProperties(); - void SetThemeAppProperties(DWORD dwFlags); - HRESULT GetCurrentThemeName( - LPWSTR pszThemeFileName, int cchMaxNameChars, - LPWSTR pszColorBuff, int cchMaxColorChars, - LPWSTR pszSizeBuff, int cchMaxSizeChars); - HRESULT GetThemeDocumentationProperty(LPCWSTR pszThemeName, - LPCWSTR pszPropertyName, LPWSTR pszValueBuff, int cchMaxValChars); - HRESULT DrawThemeParentBackground(HWND hwnd, HDC hdc, RECT* prc); - HRESULT EnableTheming(BOOL fEnable); - -private: - static HMODULE m_hThemeDll; - static void* GetProc(LPCSTR szProc, void* pfnFail); - - typedef HTHEME (__stdcall *PFNOPENTHEMEDATA)(HWND hwnd, LPCWSTR pszClassList); - static HTHEME OpenThemeDataFail(HWND, LPCWSTR) {return NULL;} - - typedef HRESULT(__stdcall *PFNCLOSETHEMEDATA)(HTHEME hTheme); - static HRESULT CloseThemeDataFail(HTHEME) {return E_FAIL;} - - typedef HRESULT(__stdcall *PFNDRAWTHEMEBACKGROUND)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect); - static HRESULT DrawThemeBackgroundFail(HTHEME, HDC, int, int, const RECT *, const RECT *) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNDRAWTHEMETEXT)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags, DWORD dwTextFlags2, const RECT *pRect); - static HRESULT DrawThemeTextFail(HTHEME, HDC, int, int, LPCWSTR, int, DWORD, DWORD, const RECT*) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMEBACKGROUNDCONTENTRECT)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pBoundingRect, RECT *pContentRect); - static HRESULT GetThemeBackgroundContentRectFail(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pBoundingRect, RECT *pContentRect) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMEBACKGROUNDEXTENT)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pContentRect, RECT *pExtentRect); - static HRESULT GetThemeBackgroundExtentFail(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pContentRect, RECT *pExtentRect) {return E_FAIL;} - - typedef HRESULT(__stdcall *PFNGETTHEMEPARTSIZE)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, RECT * pRect, enum THEMESIZE eSize, SIZE *psz); - static HRESULT GetThemePartSizeFail(HTHEME, HDC, int, int, RECT *, enum THEMESIZE, SIZE *) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMETEXTEXTENT)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags, const RECT *pBoundingRect, RECT *pExtentRect); - static HRESULT GetThemeTextExtentFail(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags, const RECT *pBoundingRect, RECT *pExtentRect) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMETEXTMETRICS)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, TEXTMETRIC* ptm); - static HRESULT GetThemeTextMetricsFail(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, TEXTMETRIC* ptm) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMEBACKGROUNDREGION)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, HRGN *pRegion); - static HRESULT GetThemeBackgroundRegionFail(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, HRGN *pRegion) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNHITTESTTHEMEBACKGROUND)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, DWORD dwOptions, const RECT *pRect, HRGN hrgn, POINT ptTest, WORD *pwHitTestCode); - static HRESULT HitTestThemeBackgroundFail(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, DWORD dwOptions, const RECT *pRect, HRGN hrgn, POINT ptTest, WORD *pwHitTestCode) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNDRAWTHEMEEDGE)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pDestRect, UINT uEdge, UINT uFlags, RECT *pContentRect); - static HRESULT DrawThemeEdgeFail(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pDestRect, UINT uEdge, UINT uFlags, RECT *pContentRect) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNDRAWTHEMEICON)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, HIMAGELIST himl, int iImageIndex); - static HRESULT DrawThemeIconFail(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, HIMAGELIST himl, int iImageIndex) {return E_FAIL;} - - typedef BOOL (__stdcall *PFNISTHEMEPARTDEFINED)(HTHEME hTheme, int iPartId, int iStateId); - static BOOL IsThemePartDefinedFail(HTHEME hTheme, int iPartId, int iStateId) {return FALSE;} - - typedef BOOL (__stdcall *PFNISTHEMEBACKGROUNDPARTIALLYTRANSPARENT)(HTHEME hTheme, int iPartId, int iStateId); - static BOOL IsThemeBackgroundPartiallyTransparentFail(HTHEME hTheme, int iPartId, int iStateId) {return FALSE;} - - typedef HRESULT (__stdcall *PFNGETTHEMECOLOR)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, COLORREF *pColor); - static HRESULT GetThemeColorFail(HTHEME hTheme, int iPartId, int iStateId, int iPropId, COLORREF *pColor) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMEMETRIC)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, int *piVal); - static HRESULT GetThemeMetricFail(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, int *piVal) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMESTRING)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, LPWSTR pszBuff, int cchMaxBuffChars); - static HRESULT GetThemeStringFail(HTHEME hTheme, int iPartId, int iStateId, int iPropId, LPWSTR pszBuff, int cchMaxBuffChars) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMEBOOL)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, BOOL *pfVal); - static HRESULT GetThemeBoolFail(HTHEME hTheme, int iPartId, int iStateId, int iPropId, BOOL *pfVal) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMEINT)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, int *piVal); - static HRESULT GetThemeIntFail(HTHEME hTheme, int iPartId, int iStateId, int iPropId, int *piVal) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMEENUMVALUE)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, int *piVal); - static HRESULT GetThemeEnumValueFail(HTHEME hTheme, int iPartId, int iStateId, int iPropId, int *piVal) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMEPOSITION)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, POINT *pPoint); - static HRESULT GetThemePositionFail(HTHEME hTheme, int iPartId, int iStateId, int iPropId, POINT *pPoint) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMEFONT)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, LOGFONT *pFont); - static HRESULT GetThemeFontFail(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, LOGFONT *pFont) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMERECT)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, RECT *pRect); - static HRESULT GetThemeRectFail(HTHEME hTheme, int iPartId, int iStateId, int iPropId, RECT *pRect) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMEMARGINS)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, RECT *prc, MARGINS *pMargins); - static HRESULT GetThemeMarginsFail(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, RECT *prc, MARGINS *pMargins) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMEINTLIST)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, INTLIST *pIntList); - static HRESULT GetThemeIntListFail(HTHEME hTheme, int iPartId, int iStateId, int iPropId, INTLIST *pIntList) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMEPROPERTYORIGIN)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, enum PROPERTYORIGIN *pOrigin); - static HRESULT GetThemePropertyOriginFail(HTHEME hTheme, int iPartId, int iStateId, int iPropId, enum PROPERTYORIGIN *pOrigin) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNSETWINDOWTHEME)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList); - static HRESULT SetWindowThemeFail(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMEFILENAME)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, LPWSTR pszThemeFileName, int cchMaxBuffChars); - static HRESULT GetThemeFilenameFail(HTHEME hTheme, int iPartId, int iStateId, int iPropId, LPWSTR pszThemeFileName, int cchMaxBuffChars) {return E_FAIL;} - - typedef COLORREF (__stdcall *PFNGETTHEMESYSCOLOR)(HTHEME hTheme, int iColorId); - static COLORREF GetThemeSysColorFail(HTHEME hTheme, int iColorId) {return RGB(255,255,255);} - - typedef HBRUSH (__stdcall *PFNGETTHEMESYSCOLORBRUSH)(HTHEME hTheme, int iColorId); - static HBRUSH GetThemeSysColorBrushFail(HTHEME hTheme, int iColorId) {return NULL;} - - typedef BOOL (__stdcall *PFNGETTHEMESYSBOOL)(HTHEME hTheme, int iBoolId); - static BOOL GetThemeSysBoolFail(HTHEME hTheme, int iBoolId) {return FALSE;} - - typedef int (__stdcall *PFNGETTHEMESYSSIZE)(HTHEME hTheme, int iSizeId); - static int GetThemeSysSizeFail(HTHEME hTheme, int iSizeId) {return 0;} - - typedef HRESULT (__stdcall *PFNGETTHEMESYSFONT)(HTHEME hTheme, int iFontId, LOGFONT *plf); - static HRESULT GetThemeSysFontFail(HTHEME hTheme, int iFontId, LOGFONT *plf) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMESYSSTRING)(HTHEME hTheme, int iStringId, LPWSTR pszStringBuff, int cchMaxStringChars); - static HRESULT GetThemeSysStringFail(HTHEME hTheme, int iStringId, LPWSTR pszStringBuff, int cchMaxStringChars) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMESYSINT)(HTHEME hTheme, int iIntId, int *piValue); - static HRESULT GetThemeSysIntFail(HTHEME hTheme, int iIntId, int *piValue) {return E_FAIL;} - - typedef BOOL (__stdcall *PFNISTHEMEACTIVE)(); - static BOOL IsThemeActiveFail() {return FALSE;} - - typedef BOOL(__stdcall *PFNISAPPTHEMED)(); - static BOOL IsAppThemedFail() {return FALSE;} - - typedef HTHEME (__stdcall *PFNGETWINDOWTHEME)(HWND hwnd); - static HTHEME GetWindowThemeFail(HWND hwnd) {return NULL;} - - typedef HRESULT (__stdcall *PFNENABLETHEMEDIALOGTEXTURE)(HWND hwnd, DWORD dwFlags); - static HRESULT EnableThemeDialogTextureFail(HWND hwnd, DWORD dwFlags) {return E_FAIL;} - - typedef BOOL (__stdcall *PFNISTHEMEDIALOGTEXTUREENABLED)(HWND hwnd); - static BOOL IsThemeDialogTextureEnabledFail(HWND hwnd) {return FALSE;} - - typedef DWORD (__stdcall *PFNGETTHEMEAPPPROPERTIES)(); - static DWORD GetThemeAppPropertiesFail() {return 0;} - - typedef void (__stdcall *PFNSETTHEMEAPPPROPERTIES)(DWORD dwFlags); - static void SetThemeAppPropertiesFail(DWORD dwFlags) {return;} - - typedef HRESULT (__stdcall *PFNGETCURRENTTHEMENAME)(LPWSTR pszThemeFileName, int cchMaxNameChars, LPWSTR pszColorBuff, int cchMaxColorChars, LPWSTR pszSizeBuff, int cchMaxSizeChars); - static HRESULT GetCurrentThemeNameFail(LPWSTR pszThemeFileName, int cchMaxNameChars, LPWSTR pszColorBuff, int cchMaxColorChars, LPWSTR pszSizeBuff, int cchMaxSizeChars) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNGETTHEMEDOCUMENTATIONPROPERTY)(LPCWSTR pszThemeName, LPCWSTR pszPropertyName, LPWSTR pszValueBuff, int cchMaxValChars); - static HRESULT GetThemeDocumentationPropertyFail(LPCWSTR pszThemeName, LPCWSTR pszPropertyName, LPWSTR pszValueBuff, int cchMaxValChars) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNDRAWTHEMEPARENTBACKGROUND)(HWND hwnd, HDC hdc, RECT* prc); - static HRESULT DrawThemeParentBackgroundFail(HWND hwnd, HDC hdc, RECT* prc) {return E_FAIL;} - - typedef HRESULT (__stdcall *PFNENABLETHEMING)(BOOL fEnable); - static HRESULT EnableThemingFail(BOOL fEnable) {return E_FAIL;} -}; -#pragma warning(default:4100) // unreferenced formal parameter - -extern CVisualStylesXP g_xpStyle; diff --git a/microsip/addons.cpp b/microsip/addons.cpp deleted file mode 100644 index d350ac14..00000000 --- a/microsip/addons.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "mainDlg.h" -#include "settings.h" - -#include "addons/CXMLFile/XMLFile.cpp" - diff --git a/microsip/addons.h b/microsip/addons.h deleted file mode 100644 index de42c421..00000000 --- a/microsip/addons.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "const.h" - -#include "addons/CXMLFile/XMLFile.h" - diff --git a/microsip/addons.rc2 b/microsip/addons.rc2 deleted file mode 100644 index e69de29b..00000000 diff --git a/microsip/addons/CXMLFile/XMLFile.cpp b/microsip/addons/CXMLFile/XMLFile.cpp deleted file mode 100644 index be268252..00000000 --- a/microsip/addons/CXMLFile/XMLFile.cpp +++ /dev/null @@ -1,823 +0,0 @@ -#include "StdAfx.h" -#include "XMLFile.h" -#include "io.h" - - -CXMLFile::CXMLFile(void) -{ - // Init members - m_dwDataSize = 0; - m_lpData = NULL; - m_lpXMLElement = NULL; -} - -CXMLFile::~CXMLFile(void) -{ - // Unload previously loaded XML file - Unload(); -} - -void CXMLFile::Unload() -{ - // Destroy XML element collection - if (m_lpXMLElement) - { - delete m_lpXMLElement; - m_lpXMLElement = NULL; - } - - // Free data buffer - if (m_lpData != NULL) - { - free(m_lpData); - m_lpData = NULL; - m_dwDataSize = 0; - } -} - -BOOL CXMLFile::LoadFromFile(LPTSTR lpszXMLFilePath) -{ - BOOL bResult = FALSE; - - // Unload previously loaded XML file - Unload(); - - // Try to open XML file - FILE* xmlFile = _tfopen(lpszXMLFilePath, _T("r")); - if (xmlFile != NULL) - { - // Get file length - m_dwDataSize = _filelength(_fileno(xmlFile)); - - // Read file data - m_lpData = (BYTE*)malloc(m_dwDataSize*sizeof(BYTE)); - DWORD dwActualSize = 0; - if ((dwActualSize=(DWORD)fread(m_lpData, sizeof(BYTE), m_dwDataSize, xmlFile))) - { - // Update actual data size - if (dwActualSize != m_dwDataSize) - { - m_dwDataSize = dwActualSize; - m_lpData = (BYTE*)realloc(m_lpData, m_dwDataSize*sizeof(BYTE)); - } - - // Create "XML:ROOT" element - m_lpXMLElement = new CXMLElement(); - m_lpXMLElement->Create(_T("XML:ROOT"), XET_TAG); - - // Parse XML file - DWORD dwStartOffset = 0; - DWORD dwEndOffset = m_dwDataSize; - if (ParseXMLElement(m_lpXMLElement, dwStartOffset, dwEndOffset)) - { - bResult = TRUE; - } - } - - // Close XML file - fclose(xmlFile); - } - - return bResult; -} - -BOOL CXMLFile::LoadFromStream(LPBYTE lpData, DWORD dwDataSize) -{ - BOOL bResult = FALSE; - - // Unload previously loaded XML file - Unload(); - - // Check for valid XML data - if (lpData != NULL) - { - // Get data size - m_dwDataSize = dwDataSize; - - // Get data - m_lpData = (BYTE*)malloc(m_dwDataSize*sizeof(BYTE)); - memcpy(m_lpData, lpData, m_dwDataSize); - - // Create "XML:ROOT" element - m_lpXMLElement = new CXMLElement(); - m_lpXMLElement->Create(_T("XML:ROOT"), XET_TAG); - - // Parse XML data - DWORD dwStartOffset = 0; - DWORD dwEndOffset = m_dwDataSize; - if (ParseXMLElement(m_lpXMLElement, dwStartOffset, dwEndOffset)) - { - bResult = TRUE; - } - } - - return bResult; -} - -BOOL CXMLFile::SaveToFile(LPTSTR lpszXMLFilePath) -{ - BOOL bResult = FALSE; - - // Check for valid XML element collection - if (m_lpXMLElement != NULL) - { - // Try to open XML file - FILE* xmlFile = _tfopen(lpszXMLFilePath, _T("w")); - if (xmlFile != NULL) - { - // Write XML prolog - BYTE szProlog[] = "\n"; - fwrite(szProlog, sizeof(BYTE), strlen((LPSTR)szProlog), xmlFile); - - // Save XML element collection - CXMLElement* lpXMLElement = m_lpXMLElement->GetFirstChild(); - // Escape attributes - while ((lpXMLElement != NULL) && (lpXMLElement->GetElementType() == XET_ATTRIBUTE)) - { - lpXMLElement = m_lpXMLElement->GetNextChild(); - } - while(lpXMLElement != NULL) - { - // Save XML element - bResult = SaveXMLElement(xmlFile, lpXMLElement); - lpXMLElement = m_lpXMLElement->GetNextChild(); - } - - // Close XML file - fclose(xmlFile); - } - } - - return bResult; -} - -BOOL CXMLFile::SaveXMLElement(FILE* file, CXMLElement* lpXMLElement) -{ - BOOL bResult = FALSE; - - // Check for valid XML file - if (file != NULL) - { - // Check for valid XML element - if (lpXMLElement != NULL) - { - // Set params - BYTE szSOT = '<'; - BYTE szEOT = '>'; - BYTE szCLT = '/'; - BYTE szESC = ' '; - BYTE szATTR = '='; - BYTE szDQT = '\"'; - BYTE szCRLF = '\n'; - - // Get XML element name - LPTSTR lpszElementName = lpXMLElement->GetElementName(); - int iNameLen = (int)_tcslen(lpszElementName); - LPBYTE lpNameData = (LPBYTE)malloc(iNameLen*sizeof(BYTE)); - for (int i=0; iGetElementType() == XET_TAG) - { - // Save XML element opening tag - fwrite(&szSOT, sizeof(BYTE), 1, file); - fwrite(lpNameData, sizeof(BYTE), iNameLen, file); - - // Save XML element attribute collection - CXMLElement* lpXMLChildElement = lpXMLElement->GetFirstChild(); - while ((lpXMLChildElement != NULL) && (lpXMLChildElement->GetElementType() == XET_ATTRIBUTE)) - { - // Get attribute name - LPTSTR lpszAttributeName = lpXMLChildElement->GetElementName(); - int iNameLen = (int)_tcslen(lpszAttributeName); - LPBYTE lpAttributeName = (LPBYTE)malloc(iNameLen*sizeof(BYTE)); - for (int i=0; iGetValue(); - int iValueLen; - LPBYTE lpAttributeValue; - if (lpszAttributeValue != NULL) - { - iValueLen = (int)_tcslen(lpszAttributeValue); - lpAttributeValue = (LPBYTE)malloc(iValueLen*sizeof(BYTE)); - for (int i=0; iGetNextChild(); - } - fwrite(&szEOT, sizeof(BYTE), 1, file); - fwrite(&szCRLF, sizeof(BYTE), 1, file); - - // Save XML element child collection - while(lpXMLChildElement != NULL) - { - // Save XML element - bResult = SaveXMLElement(file, lpXMLChildElement); - lpXMLChildElement = lpXMLElement->GetNextChild(); - } - - // Save XML element closing tag - fwrite(&szSOT, sizeof(BYTE), 1, file); - fwrite(&szCLT, sizeof(BYTE), 1, file); - fwrite(lpNameData, sizeof(BYTE), iNameLen, file); - fwrite(&szEOT, sizeof(BYTE), 1, file); - fwrite(&szCRLF, sizeof(BYTE), 1, file); - } - else if (lpXMLElement->GetElementType() == XET_TEXT) - { - // Save XML text element - fwrite(lpNameData, sizeof(BYTE), iNameLen, file); - fwrite(&szCRLF, sizeof(BYTE), 1, file); - } - - // Free data bufers - free(lpNameData); - - bResult = TRUE; - } - } - - return bResult; -} - -BOOL CXMLFile::ParseXMLElement(CXMLElement* lpXMLElement, DWORD dwStartOffset, DWORD dwEndOffset) -{ - BOOL bResult = FALSE; - - // Check for valid data - if (m_lpData != NULL) - { - // Parse XML data - BOOL bPlainText = TRUE; - DWORD i = dwStartOffset; - DWORD dwAttributeOffset; - DWORD dwFlags = FLG_DEF; - DWORD dwMode = MOD_DEF; - _TCHAR lpName[255], lpOpenTagName[255], lpCloseTagName[255], lpAttributeName[255], lpAttributeValue[255]; - int iNameLength = 0; - DWORD startOffset, endOffset; - _tcscpy((LPTSTR)lpOpenTagName, _T("")); - _tcscpy((LPTSTR)lpCloseTagName, _T("")); - while ((i <= dwEndOffset) && (i < m_dwDataSize)) - { - // Check for input character - switch (m_lpData[i]) - { - case XML_SOT: - { - // Update flags - dwFlags |= FLG_SOT; - dwFlags |= FLG_OPT; - bPlainText = FALSE; - - // Clear name - _tcscpy((LPTSTR)lpName, _T("")); - iNameLength = 0; - - // Set new mode - dwMode = MOD_DEF; - } - break; - - case XML_EOT: - { - // Update flags - dwFlags |= FLG_EOT; - - // Set new mode - dwMode = MOD_CLS; - - dwStartOffset = i + 1; - } - break; - - case XML_PRT: - { - // Update flags - dwFlags |= FLG_PRT; - - // Set new mode - dwMode = MOD_DEF; - } - break; - - case XML_SPT: - { - // Update flags - dwFlags |= FLG_SPT; - - // Set new mode - dwMode = MOD_DEF; - } - break; - - case XML_ESC: - { - // Update flags - dwFlags |= FLG_ESC; - - // Set new mode - if (dwMode != MOD_DEF) - { - dwMode = MOD_CLS; - } - } - break; - - case XML_CLT: - { - // Update flags - dwFlags |= FLG_CLT; - } - break; - - case XML_ATR: - { - // Update flags - dwFlags |= FLG_ATR; - - // Clear attribute - _tcscpy((LPTSTR)lpAttributeName, _T("")); - _tcscpy((LPTSTR)lpAttributeValue, _T("")); - } - break; - - default: - { - // Default (do nothing) - } - } - - // Check mode - switch (dwMode) - { - case MOD_APN: - { - // Append name - lpName[iNameLength++] = m_lpData[i]; - } - break; - - case MOD_CLS: - { - // Close name - lpName[iNameLength++] = '\0'; - - // Check for opening tag - if (dwFlags & FLG_OPT) - { - // Update flags - dwFlags &= ~FLG_OPT; - - // Check for opened tag - if (_tcscmp(lpOpenTagName, _T("")) == 0) - { - // Update start offset - startOffset = i + 1; - - // Save tag name - _tcsncpy(lpOpenTagName, lpName, iNameLength); - lpCloseTagName[0] = '/'; - _tcsncpy(lpCloseTagName+1, lpOpenTagName, iNameLength); - } - // Compare tag names - else if (_tcsncmp(lpName, lpCloseTagName, iNameLength) == 0) - { - // Update end offset - endOffset = i - iNameLength - 1; - - // Create new XML child element - CXMLElement* pNewXMLElement = new CXMLElement(); - pNewXMLElement->Create(lpOpenTagName, XET_TAG); - lpXMLElement->AppendChild(pNewXMLElement); - - // Parse child XML element - bResult = ParseXMLElement(pNewXMLElement, startOffset, endOffset); - if (!bResult) - { - return FALSE; - } - - // Clear opening and closing tag name - _tcscpy(lpOpenTagName, _T("")); - _tcscpy(lpCloseTagName, _T("")); - } - else - { - bResult = FALSE; - } - } - // Check for closing tag - if (dwFlags & FLG_CLT) - { - // Update flags - dwFlags &= ~FLG_CLT; - } - } - break; - - case MOD_DEF: - { - // Default (do nothing) - } - break; - } - - // Check flags - if (dwFlags & FLG_SOT) - { - // Set new mode - dwMode = MOD_APN; - - // Update flags - dwFlags &= ~FLG_SOT; - } - else if (dwFlags & FLG_EOT) - { - // Set new mode - dwMode = MOD_DEF; - - // Update flags - dwFlags &= ~FLG_EOT; - } - else if (dwFlags & FLG_PRT) - { - // Set new mode - dwMode = MOD_DEF; - - // Update flags - dwFlags &= ~FLG_PRT; - } - else if (dwFlags & FLG_ESC) - { - // Set new mode - dwMode = MOD_DEF; - - // Update flags - dwFlags &= ~FLG_ESC; - } - else if (dwFlags & FLG_ATR) - { - // Extract attribute name and value - dwAttributeOffset = ExtractAttribute(i, lpAttributeName, lpAttributeValue); - - // Update flags - dwFlags &= ~FLG_ATR; - } - - // Check for valid attribute - if (i == dwAttributeOffset) - { - // Check for valid tag - if (_tcscmp(lpOpenTagName, _T("")) == 0) - { - // Create new XML child element - CXMLElement* pNewXMLElement = new CXMLElement(); - pNewXMLElement->Create(lpAttributeName, XET_ATTRIBUTE); - pNewXMLElement->SetValue(lpAttributeValue); - lpXMLElement->AppendChild(pNewXMLElement); - } - } - - // Increment offset - i++; - } - - // Check for XML text element - if (bPlainText) - { - // Extract element name - int iNameLen = dwEndOffset - dwStartOffset + 1; - LPTSTR lpszElementName = (LPTSTR)malloc((iNameLen+1)*sizeof(_TCHAR)); - int k = 0; - for (DWORD j=dwStartOffset; j<=dwEndOffset; j++) - { - lpszElementName[k++] = m_lpData[j]; - } - lpszElementName[k] = '\0'; - - // Create new XML child element - CXMLElement* pNewXMLElement = new CXMLElement(); - pNewXMLElement->Create(lpszElementName, XET_TEXT); - lpXMLElement->AppendChild(pNewXMLElement); - free(lpszElementName); - - bResult = TRUE; - } - } - - return bResult; -} - -DWORD CXMLFile::ExtractAttribute(DWORD offset, LPTSTR lpszAttributeName, LPTSTR lpszAttributeValue) -{ - DWORD dwResult = 0; - - // Extract attribute name - int k = 0; - DWORD dwNameOffset = offset - 1; - while ((dwNameOffset >= 0) && (m_lpData[dwNameOffset] != XML_ESC) && (m_lpData[dwNameOffset] != XML_SOT) && - (m_lpData[dwNameOffset] != XML_EOT) && (m_lpData[dwNameOffset] != XML_PRT) && (m_lpData[dwNameOffset] != XML_SPT)) - { - if ((m_lpData[dwNameOffset] != XML_SQT) && (m_lpData[dwNameOffset] != XML_DQT)) - { - lpszAttributeName[k++] = m_lpData[dwNameOffset]; - } - dwNameOffset--; - } - lpszAttributeName[k] = '\0'; - // Reverse attribute name - _TCHAR tchTmp; - for (int i=0; ipNext; - delete pPrev->pCurrent; - delete pPrev; - } - - // Destroy XML element - m_Type = XET_INVALID; - if (m_lpszName != NULL) - { - free(m_lpszName); - m_lpszName = NULL; - } - - // Destroy value - if (m_lpszValue != NULL) - { - free(m_lpszValue); - m_lpszValue = NULL; - } -} - -void CXMLElement::Create(LPTSTR lpszElementName, XML_ELEMENT_TYPE type) -{ - // Check for valid XML element name - if (lpszElementName != NULL) - { - // Create new XML element - m_Type = type; - int iNameLen = (int)_tcslen(lpszElementName); - m_lpszName = (LPTSTR)malloc((iNameLen+1)*sizeof(_TCHAR)); - _tcsncpy(m_lpszName, lpszElementName, iNameLen); - m_lpszName[iNameLen] = '\0'; - } -} - -void CXMLElement::AppendChild(CXMLElement* lpXMLChild) -{ - // Check for valid XML child element - if (lpXMLChild != NULL) - { - // Create new XMLElementArray element - XMLElementArray* pNewXMLChild = new XMLElementArray; - pNewXMLChild->pCurrent = lpXMLChild; - pNewXMLChild->pNext = NULL; - - // Add new XML child element - m_iChildNumber++; - if (m_lpXMLChildArray == NULL) - { - // Add root element - m_lpXMLChildArray = pNewXMLChild; - m_lpXMLChildPointer = m_lpXMLChildArray; - m_lpXMLLastChild = m_lpXMLChildArray; - } - else - { - // Append to last element - m_lpXMLLastChild->pNext = pNewXMLChild; - m_lpXMLLastChild = pNewXMLChild; - } - } -} - -LPTSTR CXMLElement::GetElementName() -{ - // Return XML element name - return m_lpszName; -} - -XML_ELEMENT_TYPE CXMLElement::GetElementType() -{ - // Return XML element type - return m_Type; -} - -int CXMLElement::GetChildNumber() -{ - // Return XML element child number - return m_iChildNumber; -} - -CXMLElement* CXMLElement::GetFirstChild() -{ - CXMLElement* pResult = NULL; - - // Check for valid child collection pointer - m_lpXMLChildPointer = m_lpXMLChildArray; - if (m_lpXMLChildPointer != NULL) - { - // Return first XML element child collection element - pResult = m_lpXMLChildPointer->pCurrent; - } - - return pResult; -} - -CXMLElement* CXMLElement::GetCurrentChild() -{ - CXMLElement* pResult = NULL; - - // Check for valid child collection pointer - if (m_lpXMLChildPointer != NULL) - { - // Return current XML element child collection element - pResult = m_lpXMLChildPointer->pCurrent; - } - - return pResult; -} - -CXMLElement* CXMLElement::GetNextChild() -{ - CXMLElement* pResult = NULL; - - // Check for valid child collection pointer - if (m_lpXMLChildPointer != NULL) - { - // Get next XML element child collection element - m_lpXMLChildPointer = m_lpXMLChildPointer->pNext; - - // Return XML element child collection next element - if (m_lpXMLChildPointer != NULL) - { - pResult = m_lpXMLChildPointer->pCurrent; - } - } - - return pResult; -} - -CXMLElement* CXMLElement::GetLastChild() -{ - CXMLElement* pResult = NULL; - - // Check for valid child collection pointer - if (m_lpXMLLastChild != NULL) - { - // Get last XML element child collection element - pResult = m_lpXMLLastChild->pCurrent; - } - - return pResult; -} - -void CXMLElement::SetValue(LPTSTR lpszValue) -{ - // Check for valie value - if (lpszValue != NULL) - { - // Delete previous value - if (m_lpszValue != NULL) - { - free(m_lpszValue); - m_lpszValue = NULL; - } - - // Set element value - int iValueLen = (int)_tcslen(lpszValue); - m_lpszValue = (LPTSTR)malloc((iValueLen+1)*sizeof(_TCHAR)); - _tcsncpy(m_lpszValue, lpszValue, iValueLen); - m_lpszValue[iValueLen] = '\0'; - } -} - -LPTSTR CXMLElement::GetValue() -{ - // Return element value - return m_lpszValue; -} diff --git a/microsip/addons/CXMLFile/XMLFile.h b/microsip/addons/CXMLFile/XMLFile.h deleted file mode 100644 index 7e279707..00000000 --- a/microsip/addons/CXMLFile/XMLFile.h +++ /dev/null @@ -1,103 +0,0 @@ -#pragma once - - -#define FLG_DEF 0x0000 // Default flag -#define XML_SOT '<' // Start of tag symbol -#define FLG_SOT 0x0001 // Start of tag flag -#define XML_EOT '>' // End of tag symbol -#define FLG_EOT 0x0002 // End of tag flag -#define XML_PRT '?' // Prolog tag symbol -#define FLG_PRT 0x0004 // Prolog tag flag -#define XML_SPT '!' // Special tag symbol -#define FLG_SPT 0x0008 // Special tag flag -#define XML_ESC ' ' // Escape symbol -#define FLG_ESC 0x0010 // Escape flag -#define XML_CLT '/' // Closing tag symbol -#define FLG_CLT 0x0020 // Closing tag flag -#define FLG_OPT 0x0040 // Opening tag flag -#define XML_ATR '=' // Attribute symbol -#define FLG_ATR 0x0080 // Attribute flag -#define XML_SQT '\'' // Single quote symbol -#define XML_DQT '\"' // Double quote symbol -#define MOD_DEF 0x0000 // Mode "Default" -#define MOD_APN 0x0001 // Mode "Append" -#define MOD_CLS 0x0002 // Mode "Close" - - -typedef enum _XML_ELEMENT_TYPE -{ - XET_INVALID = 0, - XET_TAG, - XET_ATTRIBUTE, - XET_TEXT - -} XML_ELEMENT_TYPE; - - -class CXMLElement -{ - typedef struct _XMLElementArray - { - CXMLElement* pCurrent; - _XMLElementArray* pNext; - - } XMLElementArray; - -public: - // Public methods - CXMLElement(void); - virtual ~CXMLElement(void); - void Create(LPTSTR lpszElementName, XML_ELEMENT_TYPE type); - void AppendChild(CXMLElement* lpXMLChild); - LPTSTR GetElementName(); - XML_ELEMENT_TYPE GetElementType(); - int GetChildNumber(); - CXMLElement* GetFirstChild(); - CXMLElement* GetCurrentChild(); - CXMLElement* GetNextChild(); - CXMLElement* GetLastChild(); - void SetValue(LPTSTR lpszValue); - LPTSTR GetValue(); - -private: - // Private methods - void Destroy(); - -private: - // Private members - XML_ELEMENT_TYPE m_Type; - LPTSTR m_lpszName; - int m_iChildNumber; - XMLElementArray* m_lpXMLChildArray; - XMLElementArray* m_lpXMLChildPointer; - XMLElementArray* m_lpXMLLastChild; - LPTSTR m_lpszValue; -}; - - -class CXMLFile -{ -public: - // Public methods - CXMLFile(void); - virtual ~CXMLFile(void); - BOOL LoadFromFile(LPTSTR lpszXMLFilePath); - BOOL LoadFromStream(LPBYTE lpData, DWORD dwDataSize); - BOOL SaveToFile(LPTSTR lpszXMLFilePath); - CXMLElement* GetRoot(); - void SetRoot(CXMLElement* xmlElement); - -private: - // Private methods - void Unload(); - BOOL Parse(); - DWORD ExtractAttribute(DWORD offset, LPTSTR lpszAttributeName, LPTSTR lpszAttributeValue); - BOOL ParseXMLElement(CXMLElement* lpXMLElement, DWORD dwStartOffset, DWORD dwEndOffset); - BOOL SaveXMLElement(FILE* file, CXMLElement* lpXMLElement); - -private: - // Private members - DWORD m_dwDataSize; - BYTE* m_lpData; - CXMLElement* m_lpXMLElement; -}; diff --git a/microsip/atlrx.h b/microsip/atlrx.h deleted file mode 100644 index ce55ea74..00000000 --- a/microsip/atlrx.h +++ /dev/null @@ -1,2013 +0,0 @@ -// This is a part of the Active Template Library. -// Copyright (C) Microsoft Corporation -// All rights reserved. -// -// This source code is only intended as a supplement to the -// Active Template Library Reference and related -// electronic documentation provided with the library. -// See these sources for detailed information regarding the -// Active Template Library product. - -#ifndef __ATLRX_H__ -#define __ATLRX_H__ - -#pragma once - -#include -#include -#include - -#ifndef ATL_REGEXP_MIN_STACK -#define ATL_REGEXP_MIN_STACK 256 -#endif - -/* - Regular Expression Grammar - - R - top level grammar rule - RE - regular expression - AltE - Alternative expression - E - expression - SE - simple expression - - R -> RE - '^'RE (matches begining of string) - - RE -> AltE RE - AltE - - - AltE -> E - E '|' AltE - E -> SE (RepeatOp '?'?)? - SE -> Arg - Group - CharClass - '\'Abbrev (see below) - '\'EscapedChar (any character including reserved symbols) - '\'Digit+ (Arg back reference) - '!' (not) - '.' (any char) - '$' (end of input) - Symbol (any non-reserved character) - Arg -> '{'RE'}' - Group -> '('RE')' - CharClass -> '[' '^'? CharSet ']' - CharSet -> CharItem+ - CharItem -> Char('-'Char)? - RepeatOp -> '*' - '+' - '?' - Abbrev -> Abbreviation defined in CAtlRECharTraits - Abbrev Expansion Meaning - a ([a-zA-Z0-9]) alpha numeric - b ([ \\t]) white space (blank) - c ([a-zA-Z]) alpha - d ([0-9]) digit - h ([0-9a-fA-F]) hex digit - n (\r|(\r?\n)) newline - q (\"[^\"]*\")|(\'[^\']*\') quoted string - w ([a-zA-Z]+) simple word - z ([0-9]+) integer -*/ - -#pragma pack(push,_ATL_PACKING) -namespace ATL { - -//Convertion utility classes used to convert char* to RECHAR. -//Used by rx debugging printing. -template -class CAToREChar -{ -public: - CAToREChar(const char* psz) throw() - : m_psz(psz) - { - } - operator const RECHARTYPE*() const throw() { return m_psz; } - const char* m_psz; -}; - -template<> -class CAToREChar -{ -public: - CAToREChar(const char* psz) throw() - : m_a2w(psz) - { - } - operator const wchar_t*() const throw() { return (wchar_t*)m_a2w; } - -private: - CA2W m_a2w; -}; - -class CAtlRECharTraitsA -{ -public: - typedef char RECHARTYPE; - - static size_t GetBitFieldForRangeArrayIndex(const RECHARTYPE *sz) throw() - { -#ifndef ATL_NO_CHECK_BIT_FIELD - ATLASSERT(UseBitFieldForRange()); -#endif - return static_cast(static_cast(*sz)); - } - static RECHARTYPE *Next(const RECHARTYPE *sz) throw() - { - return (RECHARTYPE *) (sz+1); - } - - static int Strncmp(const RECHARTYPE *szLeft, const RECHARTYPE *szRight, size_t nCount) throw() - { - return strncmp(szLeft, szRight, nCount); - } - - static int Strnicmp(const RECHARTYPE *szLeft, const RECHARTYPE *szRight, size_t nCount) throw() - { - return _strnicmp(szLeft, szRight, nCount); - } - - _ATL_INSECURE_DEPRECATE("CAtlRECharTraitsA::Strlwr must be passed a buffer size.") - static RECHARTYPE *Strlwr(RECHARTYPE *sz) throw() - { - #pragma warning (push) - #pragma warning(disable : 4996) - return _strlwr(sz); - #pragma warning (pop) - } - - static RECHARTYPE *Strlwr(RECHARTYPE *sz, int nSize) throw() - { - Checked::strlwr_s(sz, nSize); - return sz; - } - - static long Strtol(const RECHARTYPE *sz, RECHARTYPE **szEnd, int nBase) throw() - { - return strtol(sz, szEnd, nBase); - } - - static int Isdigit(RECHARTYPE ch) throw() - { - return isdigit(static_cast(ch)); - } - - static const RECHARTYPE** GetAbbrevs() - { - static const RECHARTYPE *s_szAbbrevs[] = - { - "a([a-zA-Z0-9])", // alpha numeric - "b([ \\t])", // white space (blank) - "c([a-zA-Z])", // alpha - "d([0-9])", // digit - "h([0-9a-fA-F])", // hex digit - "n(\r|(\r?\n))", // newline - "q(\"[^\"]*\")|(\'[^\']*\')", // quoted string - "w([a-zA-Z]+)", // simple word - "z([0-9]+)", // integer - NULL - }; - - return s_szAbbrevs; - } - - static BOOL UseBitFieldForRange() throw() - { - return TRUE; - } - - static int ByteLen(const RECHARTYPE *sz) throw() - { - return int(strlen(sz)); - } -}; - -class CAtlRECharTraitsW -{ -public: - typedef WCHAR RECHARTYPE; - - static size_t GetBitFieldForRangeArrayIndex(const RECHARTYPE *sz) throw() - { -#ifndef ATL_NO_CHECK_BIT_FIELD - ATLASSERT(UseBitFieldForRange()); -#endif - return static_cast(*sz); - } - static RECHARTYPE *Next(const RECHARTYPE *sz) throw() - { - return (RECHARTYPE *) (sz+1); - } - - static int Strncmp(const RECHARTYPE *szLeft, const RECHARTYPE *szRight, size_t nCount) throw() - { - return wcsncmp(szLeft, szRight, nCount); - } - - static int Strnicmp(const RECHARTYPE *szLeft, const RECHARTYPE *szRight, size_t nCount) throw() - { - return _wcsnicmp(szLeft, szRight, nCount); - } - - _ATL_INSECURE_DEPRECATE("CAtlRECharTraitsW::Strlwr must be passed a buffer size.") - static RECHARTYPE *Strlwr(RECHARTYPE *sz) throw() - { - #pragma warning (push) - #pragma warning(disable : 4996) - return _wcslwr(sz); - #pragma warning (pop) - } - - static RECHARTYPE *Strlwr(RECHARTYPE *sz, int nSize) throw() - { - Checked::wcslwr_s(sz, nSize); - return sz; - } - - static long Strtol(const RECHARTYPE *sz, RECHARTYPE **szEnd, int nBase) throw() - { - return wcstol(sz, szEnd, nBase); - } - - static int Isdigit(RECHARTYPE ch) throw() - { - return iswdigit(ch); - } - - static const RECHARTYPE** GetAbbrevs() - { - static const RECHARTYPE *s_szAbbrevs[] = - { - L"a([a-zA-Z0-9])", // alpha numeric - L"b([ \\t])", // white space (blank) - L"c([a-zA-Z])", // alpha - L"d([0-9])", // digit - L"h([0-9a-fA-F])", // hex digit - L"n(\r|(\r?\n))", // newline - L"q(\"[^\"]*\")|(\'[^\']*\')", // quoted string - L"w([a-zA-Z]+)", // simple word - L"z([0-9]+)", // integer - NULL - }; - - return s_szAbbrevs; - } - - static BOOL UseBitFieldForRange() throw() - { - return FALSE; - } - - static int ByteLen(const RECHARTYPE *sz) throw() - { - return int(wcslen(sz)*sizeof(WCHAR)); - } -}; - -class CAtlRECharTraitsMB -{ -public: - typedef unsigned char RECHARTYPE; - - static size_t GetBitFieldForRangeArrayIndex(const RECHARTYPE *sz) throw() - { -#ifndef ATL_NO_CHECK_BIT_FIELD - ATLASSERT(UseBitFieldForRange()); -#endif - - return static_cast(*sz); - } - - static RECHARTYPE *Next(const RECHARTYPE *sz) throw() - { - return _mbsinc(sz); - } - - static int Strncmp(const RECHARTYPE *szLeft, const RECHARTYPE *szRight, size_t nCount) throw() - { - return _mbsncmp(szLeft, szRight, nCount); - } - - static int Strnicmp(const RECHARTYPE *szLeft, const RECHARTYPE *szRight, size_t nCount) throw() - { - return _mbsnicmp(szLeft, szRight, nCount); - } - - _ATL_INSECURE_DEPRECATE("CAtlRECharTraitsMB::Strlwr must be passed a buffer size.") - static RECHARTYPE *Strlwr(RECHARTYPE *sz) throw() - { - #pragma warning (push) - #pragma warning(disable : 4996) - return _mbslwr(sz); - #pragma warning (pop) - } - - static RECHARTYPE *Strlwr(RECHARTYPE *sz, int nSize) throw() - { - Checked::mbslwr_s(sz, nSize); - return sz; - } - - static long Strtol(const RECHARTYPE *sz, RECHARTYPE **szEnd, int nBase) throw() - { - return strtol((const char *) sz, (char **) szEnd, nBase); - } - - static int Isdigit(RECHARTYPE ch) throw() - { - return _ismbcdigit((unsigned int) ch); - } - - static const RECHARTYPE** GetAbbrevs() - { - return reinterpret_cast(CAtlRECharTraitsA::GetAbbrevs()); - } - - static BOOL UseBitFieldForRange() throw() - { - return FALSE; - } - - static int ByteLen(const RECHARTYPE *sz) throw() - { - return (int)strlen((const char *) sz); - } -}; - -#ifndef _UNICODE -typedef CAtlRECharTraitsA CAtlRECharTraits; -#else // _UNICODE -typedef CAtlRECharTraitsW CAtlRECharTraits; -#endif // !_UNICODE -// Note: If you want to use CAtlRECharTraitsMB you must pass it in -// as a template argument - -template -class CAtlRegExp; // forward declaration - -template -class CAtlREMatchContext -{ -public: - friend CAtlRegExp; - typedef typename CharTraits::RECHARTYPE RECHAR; - - struct MatchGroup - { - const RECHAR *szStart; - const RECHAR *szEnd; - }; - - UINT m_uNumGroups; - - MatchGroup m_Match; - - void GetMatch(UINT nIndex, const RECHAR **szStart, const RECHAR **szEnd) - { - ATLENSURE(szStart != NULL); - ATLENSURE(szEnd != NULL); - ATLENSURE(nIndex >=0 && nIndex < m_uNumGroups); - *szStart = m_Matches[nIndex].szStart; - *szEnd = m_Matches[nIndex].szEnd; - } - - void GetMatch(UINT nIndex, MatchGroup *pGroup) - { - - ATLENSURE(pGroup != NULL); - ATLENSURE(nIndex >=0&&(static_cast(nIndex))< m_uNumGroups); - pGroup->szStart = m_Matches[nIndex].szStart; - pGroup->szEnd = m_Matches[nIndex].szEnd; - } - -protected: - CAutoVectorPtr m_Mem; - CAutoVectorPtr m_Matches; - CAtlArray m_stack; - size_t m_nTos; - -public: - CAtlREMatchContext(size_t nInitStackSize=ATL_REGEXP_MIN_STACK) - { - m_uNumGroups = 0; - m_nTos = 0; - m_stack.SetCount(nInitStackSize); - m_Match.szStart = NULL; - m_Match.szEnd = NULL; - } - -protected: - BOOL Initialize(UINT uRequiredMem, UINT uNumGroups) throw() - { - m_nTos = 0; - - m_uNumGroups = 0; - m_Matches.Free(); - - if (!m_Matches.Allocate(uNumGroups)) - return FALSE; - - m_uNumGroups = uNumGroups; - - m_Mem.Free(); - - if (!m_Mem.Allocate(uRequiredMem)) - return FALSE; - - memset(m_Mem.m_p, 0x00, uRequiredMem*sizeof(void *)); - - memset(m_Matches, 0x00, m_uNumGroups * sizeof(MatchGroup)); - return TRUE; - } - - BOOL Push(void *p) - { - m_nTos++; - if (m_stack.GetCount() <= (UINT) m_nTos) - { - if (!m_stack.SetCount((m_nTos+1)*2)) - { - m_nTos--; - return FALSE; - } - } - m_stack[m_nTos] = p; - return TRUE; - } - - BOOL Push(size_t n) - { - return Push((void *) n); - } - - void *Pop() throw() - { - if (m_nTos==0) - { - // stack underflow - // this should never happen at match time. - // (the parsing succeeded when it shouldn't have) - ATLASSERT(FALSE); - return NULL; - } - void *p = m_stack[m_nTos]; - m_nTos--; - return p; - } -}; - -enum REParseError { - REPARSE_ERROR_OK = 0, // No error occurred - REPARSE_ERROR_OUTOFMEMORY, // Out of memory - REPARSE_ERROR_BRACE_EXPECTED, // A closing brace was expected - REPARSE_ERROR_PAREN_EXPECTED, // A closing parenthesis was expected - REPARSE_ERROR_BRACKET_EXPECTED, // A closing bracket was expected - REPARSE_ERROR_UNEXPECTED, // An unspecified fatal error occurred - REPARSE_ERROR_EMPTY_RANGE, // A range expression was empty - REPARSE_ERROR_INVALID_GROUP, // A backreference was made to a group - // that did not exist - REPARSE_ERROR_INVALID_RANGE, // An invalid range was specified - REPARSE_ERROR_EMPTY_REPEATOP, // A possibly empty * or + was detected - REPARSE_ERROR_INVALID_INPUT, // The input string was invalid -}; - -template -class CAtlRegExp -{ -public: - CAtlRegExp() throw() - { - m_uNumGroups = 0; - m_uRequiredMem = 0; - m_bCaseSensitive = TRUE; - m_LastError = REPARSE_ERROR_OK; - } - - typedef typename CharTraits::RECHARTYPE RECHAR; - - // CAtlRegExp::Parse - // Parses the regular expression - // returns REPARSE_ERROR_OK if successful, an REParseError otherwise - REParseError Parse(const RECHAR *szRE, BOOL bCaseSensitive=TRUE) - { - ATLASSERT(szRE); - if (!szRE) - return REPARSE_ERROR_INVALID_INPUT; - - Reset(); - - m_bCaseSensitive = bCaseSensitive; - - const RECHAR *szInput = szRE; - - if (!bCaseSensitive) - { - // copy the string - int nSize = CharTraits::ByteLen(szRE)+sizeof(RECHAR); - szInput = (const RECHAR *) malloc(nSize); - if (!szInput) - return REPARSE_ERROR_OUTOFMEMORY; - - Checked::memcpy_s((char *) szInput, nSize, szRE, nSize); - - CharTraits::Strlwr(const_cast(szInput), nSize/sizeof(RECHAR)); - } - const RECHAR *sz = szInput; - - int nCall = AddInstruction(RE_CALL); - if (nCall < 0) - return REPARSE_ERROR_OUTOFMEMORY; - - if (*sz == '^') - { - if (AddInstruction(RE_FAIL) < 0) - return REPARSE_ERROR_OUTOFMEMORY; - sz++; - } - else - { - if (AddInstruction(RE_ADVANCE) < 0) - return REPARSE_ERROR_OUTOFMEMORY; - } - - bool bEmpty = true; - ParseRE(&sz, bEmpty); - if (!GetLastParseError()) - { - GetInstruction(nCall).call.nTarget = 2; - - if (AddInstruction(RE_MATCH) < 0) - return REPARSE_ERROR_OUTOFMEMORY; - } - - if (szInput != szRE) - free((void *) szInput); - - return GetLastParseError(); - } - - BOOL Match(const RECHAR *szIn, CAtlREMatchContext *pContext, const RECHAR **ppszEnd=NULL) - { - ATLASSERT(szIn); - ATLASSERT(pContext); - - if (!szIn || !pContext) - return FALSE; - - if (ppszEnd) - *ppszEnd = NULL; - - const RECHAR *szInput = szIn; - - if (!m_bCaseSensitive) - { - int nSize = CharTraits::ByteLen(szIn)+sizeof(RECHAR); - szInput = (const RECHAR *) malloc(nSize); - if (!szInput) - return FALSE; - - Checked::memcpy_s((char *) szInput, nSize, szIn, nSize); - CharTraits::Strlwr(const_cast(szInput), nSize/sizeof(RECHAR)); - } - - if (!pContext->Initialize(m_uRequiredMem, m_uNumGroups)) - { - if (szInput != szIn) - free((void *) szInput); - return FALSE; - } - - size_t ip = 0; - - const RECHAR *sz = szInput; - const RECHAR *szCurrInput = szInput; - -#pragma warning(push) -#pragma warning(disable:4127) // conditional expression is constant - - while (1) - { -#ifdef ATLRX_DEBUG - OnDebugEvent(ip, szInput, sz, pContext); -#endif - if (ip == 0) - pContext->m_Match.szStart = sz; - - switch (GetInstruction(ip).type) - { - case RE_NOP: - ip++; - break; - - case RE_SYMBOL: - if (GetInstruction(ip).symbol.nSymbol == static_cast(static_cast<_TUCHAR>(*sz))) - { - sz = CharTraits::Next(sz); - ip++; - } - else - { - ip = (size_t) pContext->Pop(); - } - break; - - case RE_ANY: - if (*sz) - { - sz = CharTraits::Next(sz); - ip++; - } - else - { - ip = (size_t) pContext->Pop(); - } - break; - - case RE_GROUP_START: - pContext->m_Matches[GetInstruction(ip).group.nGroup].szStart = sz; - ip++; - break; - - case RE_GROUP_END: - pContext->m_Matches[GetInstruction(ip).group.nGroup].szEnd = sz; - ip++; - break; - - case RE_PUSH_CHARPOS: - pContext->Push((void *) sz); - ip++; - break; - - case RE_POP_CHARPOS: - sz = (RECHAR *) pContext->Pop(); - ip++; - break; - - case RE_CALL: - pContext->Push(ip+1); - ip = GetInstruction(ip).call.nTarget; - break; - - case RE_JMP: - ip = GetInstruction(ip).jmp.nTarget; - break; - - case RE_RETURN: - ip = (size_t) pContext->Pop(); - break; - - case RE_PUSH_MEMORY: - pContext->Push((void *) (pContext->m_Mem[GetInstruction(ip).memory.nIndex])); - ip++; - break; - - case RE_POP_MEMORY: - pContext->m_Mem[GetInstruction(ip).memory.nIndex] = pContext->Pop(); - ip++; - break; - - case RE_STORE_CHARPOS: - pContext->m_Mem[GetInstruction(ip).memory.nIndex] = (void *) sz; - ip++; - break; - - case RE_GET_CHARPOS: - sz = (RECHAR *) pContext->m_Mem[GetInstruction(ip).memory.nIndex]; - ip++; - break; - - case RE_STORE_STACKPOS: - pContext->m_Mem[GetInstruction(ip).memory.nIndex] = (void *) pContext->m_nTos; - ip++; - break; - - case RE_GET_STACKPOS: - pContext->m_nTos = (size_t) pContext->m_Mem[GetInstruction(ip).memory.nIndex]; - ip++; - break; - - case RE_RET_NOMATCH: - if (sz == (RECHAR *) pContext->m_Mem[GetInstruction(ip).memory.nIndex]) - { - // do a return - ip = (size_t) pContext->Pop(); - } - else - ip++; - break; - - case RE_ADVANCE: - sz = CharTraits::Next(szCurrInput); - szCurrInput = sz; - if (*sz == '\0') - goto Error; - ip = 0; - pContext->m_nTos = 0; - break; - - case RE_FAIL: - goto Error; - - case RE_RANGE: - { - if (*sz == '\0') - { - ip = (size_t) pContext->Pop(); - break; - } - - RECHAR *pBits = reinterpret_cast((&m_Instructions[ip]+1)); - size_t u = CharTraits::GetBitFieldForRangeArrayIndex(sz); - if (pBits[u >> 3] & 1 << (u & 0x7)) - { - ip += InstructionsPerRangeBitField(); - ip++; - sz = CharTraits::Next(sz); - } - else - { - ip = (size_t) pContext->Pop(); - } - } - break; - - case RE_NOTRANGE: - { - if (*sz == '\0') - { - ip = (size_t) pContext->Pop(); - break; - } - - RECHAR *pBits = reinterpret_cast((&m_Instructions[ip]+1)); - size_t u = static_cast(static_cast<_TUCHAR>(* ((RECHAR *) sz))); - if (pBits[u >> 3] & 1 << (u & 0x7)) - { - ip = (size_t) pContext->Pop(); - } - else - { - ip += InstructionsPerRangeBitField(); - ip++; - sz = CharTraits::Next(sz); - } - } - break; - - case RE_RANGE_EX: - { - if (*sz == '\0') - { - ip = (size_t) pContext->Pop(); - break; - } - - BOOL bMatch = FALSE; - size_t inEnd = GetInstruction(ip).range.nTarget; - ip++; - - while (ip < inEnd) - { - if (static_cast(static_cast<_TUCHAR>(*sz)) >= GetInstruction(ip).memory.nIndex && - static_cast(static_cast<_TUCHAR>(*sz)) <= GetInstruction(ip+1).memory.nIndex) - { - // if we match, we jump to the end - sz = CharTraits::Next(sz); - ip = inEnd; - bMatch = TRUE; - } - else - { - ip += 2; - } - } - if (!bMatch) - { - ip = (size_t) pContext->Pop(); - } - } - break; - - case RE_NOTRANGE_EX: - { - if (*sz == '\0') - { - ip = (size_t) pContext->Pop(); - break; - } - - BOOL bMatch = TRUE; - size_t inEnd = GetInstruction(ip).range.nTarget; - ip++; - - while (ip < inEnd) - { - if (static_cast(static_cast<_TUCHAR>(*sz)) >= GetInstruction(ip).memory.nIndex && - static_cast(static_cast<_TUCHAR>(*sz)) <= GetInstruction(ip+1).memory.nIndex) - { - ip = (size_t) pContext->Pop(); - bMatch = FALSE; - break; - } - else - { - // if we match, we jump to the end - ip += 2; - } - } - if (bMatch) - sz = CharTraits::Next(sz); - } - break; - - case RE_PREVIOUS: - { - BOOL bMatch = FALSE; - if (m_bCaseSensitive) - { - bMatch = !CharTraits::Strncmp(sz, pContext->m_Matches[GetInstruction(ip).prev.nGroup].szStart, - pContext->m_Matches[GetInstruction(ip).prev.nGroup].szEnd-pContext->m_Matches[GetInstruction(ip).prev.nGroup].szStart); - } - else - { - bMatch = !CharTraits::Strnicmp(sz, pContext->m_Matches[GetInstruction(ip).prev.nGroup].szStart, - pContext->m_Matches[GetInstruction(ip).prev.nGroup].szEnd-pContext->m_Matches[GetInstruction(ip).prev.nGroup].szStart); - } - if (bMatch) - { - sz += pContext->m_Matches[GetInstruction(ip).prev.nGroup].szEnd-pContext->m_Matches[GetInstruction(ip).prev.nGroup].szStart; - ip++; - break; - } - ip = (size_t) pContext->Pop(); - } - break; - - case RE_MATCH: - pContext->m_Match.szEnd = sz; - if (!m_bCaseSensitive) - FixupMatchContext(pContext, szIn, szInput); - if (ppszEnd) - *ppszEnd = szIn + (sz - szInput); - if (szInput != szIn) - free((void *) szInput); - return TRUE; - break; - - case RE_PUSH_GROUP: - pContext->Push((void *) pContext->m_Matches[GetInstruction(ip).group.nGroup].szStart); - pContext->Push((void *) pContext->m_Matches[GetInstruction(ip).group.nGroup].szEnd); - ip++; - break; - - case RE_POP_GROUP: - pContext->m_Matches[GetInstruction(ip).group.nGroup].szEnd = (const RECHAR *) pContext->Pop(); - pContext->m_Matches[GetInstruction(ip).group.nGroup].szStart = (const RECHAR *) pContext->Pop(); - ip++; - break; - - default: - ATLASSERT(FALSE); - break; - } - } - -#pragma warning(pop) // 4127 - - ATLASSERT(FALSE); -Error: - pContext->m_Match.szEnd = sz; - if (!m_bCaseSensitive) - FixupMatchContext(pContext, szIn, szInput); - if (ppszEnd) - *ppszEnd = szIn + (sz - szInput); - if (szInput != szIn) - free((void *) szInput); - return FALSE; - } - -protected: - REParseError m_LastError; - - REParseError GetLastParseError() throw() - { - return m_LastError; - } - - void SetLastParseError(REParseError Error) throw() - { - m_LastError = Error; - } - // CAtlRegExp::Reset - // Removes all instructions to allow reparsing into the same instance - void Reset() throw() - { - m_Instructions.RemoveAll(); - m_uRequiredMem = 0; - m_bCaseSensitive = TRUE; - m_uNumGroups = 0; - SetLastParseError(REPARSE_ERROR_OK); - } - - - enum REInstructionType { - RE_NOP, - RE_GROUP_START, - RE_GROUP_END, - RE_SYMBOL, - RE_ANY, - RE_RANGE, - RE_NOTRANGE, - RE_RANGE_EX, - RE_NOTRANGE_EX, - RE_PLUS, - RE_NG_PLUS, - RE_QUESTION, - RE_NG_QUESTION, - RE_JMP, - RE_PUSH_CHARPOS, - RE_POP_CHARPOS, - RE_CALL, - RE_RETURN, - RE_STAR_BEGIN, - RE_NG_STAR_BEGIN, - RE_PUSH_MEMORY, - RE_POP_MEMORY, - RE_STORE_CHARPOS, - RE_STORE_STACKPOS, - RE_GET_CHARPOS, - RE_GET_STACKPOS, - RE_RET_NOMATCH, - RE_PREVIOUS, - RE_FAIL, - RE_ADVANCE, - RE_MATCH, - RE_PUSH_GROUP, - RE_POP_GROUP, - }; - - struct INSTRUCTION_SYMBOL - { - size_t nSymbol; - }; - - struct INSTRUCTION_JMP - { - size_t nTarget; - }; - - struct INSTRUCTION_GROUP - { - size_t nGroup; - }; - - struct INSTRUCTION_CALL - { - size_t nTarget; - }; - - struct INSTRUCTION_MEMORY - { - size_t nIndex; - }; - - struct INSTRUCTION_PREVIOUS - { - size_t nGroup; - }; - - struct INSTRUCTION_RANGE_EX - { - size_t nTarget; - }; - - struct INSTRUCTION - { - REInstructionType type; - union - { - INSTRUCTION_SYMBOL symbol; - INSTRUCTION_JMP jmp; - INSTRUCTION_GROUP group; - INSTRUCTION_CALL call; - INSTRUCTION_MEMORY memory; - INSTRUCTION_PREVIOUS prev; - INSTRUCTION_RANGE_EX range; - }; - }; - - inline int InstructionsPerRangeBitField() throw() - { - return (256/8) / sizeof(INSTRUCTION) + (((256/8) % sizeof(INSTRUCTION)) ? 1 : 0); - } - - CAtlArray m_Instructions; - - UINT m_uNumGroups; - UINT m_uRequiredMem; - BOOL m_bCaseSensitive; - - - // class used internally to restore - // parsing state when unwinding - class CParseState - { - public: - int m_nNumInstructions; - UINT m_uNumGroups; - UINT m_uRequiredMem; - - CParseState(CAtlRegExp *pRegExp) throw() - { - m_nNumInstructions = (int) pRegExp->m_Instructions.GetCount(); - m_uNumGroups = pRegExp->m_uNumGroups; - m_uRequiredMem = pRegExp->m_uRequiredMem; - } - - void Restore(CAtlRegExp *pRegExp) - { - pRegExp->m_Instructions.SetCount(m_nNumInstructions); - pRegExp->m_uNumGroups = m_uNumGroups; - pRegExp->m_uRequiredMem = m_uRequiredMem; - } - }; - - int AddInstruction(REInstructionType type) - { - if (!m_Instructions.SetCount(m_Instructions.GetCount()+1)) - { - SetLastParseError(REPARSE_ERROR_OUTOFMEMORY); - return -1; - } - - m_Instructions[m_Instructions.GetCount()-1].type = type; - return (int) m_Instructions.GetCount()-1; - } - - BOOL PeekToken(const RECHAR **ppszRE, int ch) throw() - { - if (**ppszRE != ch) - return FALSE; - return TRUE; - } - - BOOL MatchToken(const RECHAR **ppszRE, int ch) throw() - { - if (!PeekToken(ppszRE, ch)) - return FALSE; - *ppszRE = CharTraits::Next(*ppszRE); - return TRUE; - } - - INSTRUCTION &GetInstruction(size_t nIndex) throw() - { - return m_Instructions[nIndex]; - } - - // ParseArg: parse grammar rule Arg - int ParseArg(const RECHAR **ppszRE, bool &bEmpty) - { - int nPushGroup = AddInstruction(RE_PUSH_GROUP); - if (nPushGroup < 0) - return -1; - - GetInstruction(nPushGroup).group.nGroup = m_uNumGroups; - - int p = AddInstruction(RE_GROUP_START); - if (p < 0) - return -1; - GetInstruction(p).group.nGroup = m_uNumGroups++; - - int nCall = AddInstruction(RE_CALL); - if (nCall < 0) - return -1; - - int nPopGroup = AddInstruction(RE_POP_GROUP); - if (nPopGroup < 0) - return -1; - GetInstruction(nPopGroup).group.nGroup = GetInstruction(nPushGroup).group.nGroup; - - if (AddInstruction(RE_RETURN) < 0) - return -1; - - int nAlt = ParseRE(ppszRE, bEmpty); - if (nAlt < 0) - { - if (GetLastParseError()) - return -1; - - if (!PeekToken(ppszRE, '}')) - { - SetLastParseError(REPARSE_ERROR_BRACE_EXPECTED); - return -1; - } - - // in the case of an empty group, we add a nop - nAlt = AddInstruction(RE_NOP); - if (nAlt < 0) - return -1; - } - - GetInstruction(nCall).call.nTarget = nAlt; - - if (!MatchToken(ppszRE, '}')) - { - SetLastParseError(REPARSE_ERROR_BRACE_EXPECTED); - return -1; - } - - int nEnd = AddInstruction(RE_GROUP_END); - if (nEnd < 0) - return -1; - GetInstruction(nEnd).group.nGroup = GetInstruction(p).group.nGroup; - return nPushGroup; - } - - // ParseGroup: parse grammar rule Group - int ParseGroup(const RECHAR **ppszRE, bool &bEmpty) - { - int nCall = AddInstruction(RE_CALL); - if (nCall < 0) - return -1; - - if (AddInstruction(RE_RETURN) < 0) - return -1; - - int nAlt = ParseRE(ppszRE, bEmpty); - if (nAlt < 0) - { - if (GetLastParseError()) - return -1; - - if (!PeekToken(ppszRE, ')')) - { - SetLastParseError(REPARSE_ERROR_PAREN_EXPECTED); - return -1; - } - - // in the case of an empty group, we add a nop - nAlt = AddInstruction(RE_NOP); - if (nAlt < 0) - return -1; - } - - GetInstruction(nCall).call.nTarget = nAlt; - - if (!MatchToken(ppszRE, ')')) - { - SetLastParseError(REPARSE_ERROR_PAREN_EXPECTED); - return -1; - } - - return nCall; - } - - RECHAR GetEscapedChar(RECHAR ch) throw() - { - if (ch == 't') - return '\t'; - return ch; - } - - // ParseCharItem: parse grammar rule CharItem - int ParseCharItem(const RECHAR **ppszRE, RECHAR *pchStartChar, RECHAR *pchEndChar) throw() - { - if (**ppszRE == '\\') - { - *ppszRE = CharTraits::Next(*ppszRE); - *pchStartChar = GetEscapedChar(**ppszRE); - } - else - *pchStartChar = **ppszRE; - *ppszRE = CharTraits::Next(*ppszRE); - - if (!MatchToken(ppszRE, '-')) - { - *pchEndChar = *pchStartChar; - return 0; - } - - // check for unterminated range - if (!**ppszRE || PeekToken(ppszRE, ']')) - { - SetLastParseError(REPARSE_ERROR_BRACKET_EXPECTED); - return -1; - } - - *pchEndChar = **ppszRE; - *ppszRE = CharTraits::Next(*ppszRE); - - if (*pchEndChar < *pchStartChar) - { - SetLastParseError(REPARSE_ERROR_INVALID_RANGE); - return -1; - } - return 0; - } - - int AddInstructions(int nNumInstructions) - { - size_t nCurr = m_Instructions.GetCount(); - if (!m_Instructions.SetCount(nCurr+nNumInstructions)) - { - SetLastParseError(REPARSE_ERROR_OUTOFMEMORY); - return -1; - } - return (int) nCurr; - } - - // ParseCharSet: parse grammar rule CharSet - int ParseCharSet(const RECHAR **ppszRE, BOOL bNot) - { - int p = -1; - - unsigned char *pBits = NULL; - - if (CharTraits::UseBitFieldForRange()) - { - // we use a bit field to represent the characters - // a 1 bit means match against the character - // the last 5 bits are used as an index into - // the byte array, and the first 3 bits - // are used to index into the selected byte - - p = AddInstruction(bNot ? RE_NOTRANGE : RE_RANGE); - if (p < 0) - return -1; - - // add the required space to hold the character - // set. We use one bit per character for ansi - if (AddInstructions(InstructionsPerRangeBitField()) < 0) - return -1; - - pBits = (unsigned char *) (&m_Instructions[p+1]); - memset(pBits, 0x00, 256/8); - } - else - { - p = AddInstruction(bNot ? RE_NOTRANGE_EX : RE_RANGE_EX); - if (p < 0) - return -1; - } - - RECHAR chStart; - RECHAR chEnd; - - while (**ppszRE && **ppszRE != ']') - { - if (ParseCharItem(ppszRE, &chStart, &chEnd)) - return -1; - - if (CharTraits::UseBitFieldForRange()) - { - for (int i=chStart; i<=chEnd; i++) - pBits[i >> 3] |= 1 << (i & 0x7); - } - else - { - int nStart = AddInstruction(RE_NOP); - if (nStart < 0) - return -1; - - int nEnd = AddInstruction(RE_NOP); - if (nEnd < 0) - return -1; - - GetInstruction(nStart).memory.nIndex = (int) chStart; - GetInstruction(nEnd).memory.nIndex = (int) chEnd; - } - } - - if (!CharTraits::UseBitFieldForRange()) - GetInstruction(p).range.nTarget = m_Instructions.GetCount(); - - return p; - } - - // ParseCharClass: parse grammar rule CharClass - int ParseCharClass(const RECHAR **ppszRE, bool &bEmpty) - { - bEmpty = false; - if (MatchToken(ppszRE, ']')) - { - SetLastParseError(REPARSE_ERROR_EMPTY_RANGE); - return -1; - } - - BOOL bNot = FALSE; - if (MatchToken(ppszRE, '^')) - bNot = TRUE; - - if (MatchToken(ppszRE, ']')) - { - SetLastParseError(REPARSE_ERROR_EMPTY_RANGE); - return -1; - } - - int p = ParseCharSet(ppszRE, bNot); - if (p < 0) - return p; - if (!MatchToken(ppszRE, ']')) - { - SetLastParseError(REPARSE_ERROR_BRACKET_EXPECTED); - return -1; - } - - return p; - } - - int AddMemInstruction(REInstructionType type) - { - int p = AddInstruction(type); - if (p < 0) - return p; - GetInstruction(p).memory.nIndex = m_uRequiredMem++; - return p; - } - - // helper for parsing !SE - int ParseNot(const RECHAR **ppszRE, bool &bEmpty) - { - int nStoreCP = AddMemInstruction(RE_STORE_CHARPOS); - int nStoreSP = AddMemInstruction(RE_STORE_STACKPOS); - - int nCall = AddInstruction(RE_CALL); - if (nCall < 0) - return -1; - - int nGetCP = AddInstruction(RE_GET_CHARPOS); - if (nGetCP < 0) - return -1; - GetInstruction(nGetCP).memory.nIndex = GetInstruction(nStoreCP).memory.nIndex; - - int nGetSP = AddInstruction(RE_GET_STACKPOS); - if (nGetSP < 0) - return -1; - GetInstruction(nGetSP).memory.nIndex = GetInstruction(nStoreSP).memory.nIndex; - - int nJmp = AddInstruction(RE_JMP); - if (nJmp < 0) - return -1; - - int nSE = ParseSE(ppszRE, bEmpty); - if (nSE < 0) - return nSE; - - // patch the call - GetInstruction(nCall).call.nTarget = nSE; - - int nGetCP1 = AddInstruction(RE_GET_CHARPOS); - if (nGetCP1 < 0) - return -1; - GetInstruction(nGetCP1).memory.nIndex = GetInstruction(nStoreCP).memory.nIndex; - - int nGetSP1 = AddInstruction(RE_GET_STACKPOS); - if (nGetSP1 < 0) - return -1; - GetInstruction(nGetSP1).memory.nIndex = GetInstruction(nStoreSP).memory.nIndex; - - int nRet = AddInstruction(RE_RETURN); - if (nRet < 0) - return -1; - - GetInstruction(nJmp).jmp.nTarget = nRet+1; - - return nStoreCP; - } - - // ParseAbbrev: parse grammar rule Abbrev - int ParseAbbrev(const RECHAR **ppszRE, bool &bEmpty) - { - const RECHAR **szAbbrevs = CharTraits::GetAbbrevs(); - - while (*szAbbrevs) - { - if (**ppszRE == **szAbbrevs) - { - const RECHAR *szAbbrev = (*szAbbrevs)+1; - int p = ParseE(&szAbbrev, bEmpty); - if (p < 0) - { - SetLastParseError(REPARSE_ERROR_UNEXPECTED); - return p; - } - *ppszRE = CharTraits::Next(*ppszRE); - return p; - } - szAbbrevs++; - } - return -1; - } - - // ParseSE: parse grammar rule SE (simple expression) - int ParseSE(const RECHAR **ppszRE, bool &bEmpty) - { - - if (MatchToken(ppszRE, '{')) - return ParseArg(ppszRE, bEmpty); - if (MatchToken(ppszRE, '(')) - return ParseGroup(ppszRE, bEmpty); - if (MatchToken(ppszRE, '[')) - return ParseCharClass(ppszRE, bEmpty); - - if (MatchToken(ppszRE, '\\')) - { - if (!CharTraits::Isdigit(**ppszRE)) - { - // check for abbreviations - int p; - p = ParseAbbrev(ppszRE, bEmpty); - if (p >= 0) - return p; - - if (GetLastParseError()) - return -1; - - // escaped char - p = AddInstruction(RE_SYMBOL); - if (p < 0) - return -1; - GetInstruction(p).symbol.nSymbol = (int) **ppszRE; - *ppszRE = CharTraits::Next(*ppszRE); - return p; - } - // previous match - bEmpty = false; - int nPrev = AddInstruction(RE_PREVIOUS); - if (nPrev < 0) - return -1; - - UINT uValue = (UINT) CharTraits::Strtol(*ppszRE, (RECHAR **) ppszRE, 10); - if (uValue >= m_uNumGroups) - { - SetLastParseError(REPARSE_ERROR_INVALID_GROUP); - return -1; - } - GetInstruction(nPrev).prev.nGroup = (size_t) uValue; - return nPrev; - } - - if (MatchToken(ppszRE, '!')) - return ParseNot(ppszRE, bEmpty); - - if (**ppszRE == '}' || **ppszRE == ']' || **ppszRE == ')') - { - return -1; - } - - if (**ppszRE == '\0') - { - return -1; - } - - int p; - if (**ppszRE == '.') - { - p = AddInstruction(RE_ANY); - if (p < 0) - return -1; - bEmpty = false; - } - else if (**ppszRE == '$' && (*ppszRE)[1] == '\0') - { - p = AddInstruction(RE_SYMBOL); - if (p < 0) - return -1; - GetInstruction(p).symbol.nSymbol = 0; - bEmpty = false; - } - else - { - p = AddInstruction(RE_SYMBOL); - if (p < 0) - return -1; - GetInstruction(p).symbol.nSymbol = (int) **ppszRE; - bEmpty = false; - } - *ppszRE = CharTraits::Next(*ppszRE); - return p; - } - - // ParseE: parse grammar rule E (expression) - int ParseE(const RECHAR **ppszRE, bool &bEmpty) - { - CParseState ParseState(this); - const RECHAR *sz = *ppszRE; - - int nSE; - - int nFirst = ParseSE(ppszRE, bEmpty); - if (nFirst < 0) - return nFirst; - - REInstructionType type = RE_MATCH; - - if (MatchToken(ppszRE, '*')) - if(MatchToken(ppszRE, '?')) - type = RE_NG_STAR_BEGIN; - else - type = RE_STAR_BEGIN; - - - else if (MatchToken(ppszRE, '+')) - if(MatchToken(ppszRE, '?')) - type = RE_NG_PLUS; - else - type = RE_PLUS; - - else if (MatchToken(ppszRE, '?')) - if(MatchToken(ppszRE, '?')) - type = RE_NG_QUESTION; - else - type = RE_QUESTION; - - - if (type == RE_MATCH) - return nFirst; - - if (type == RE_STAR_BEGIN || type == RE_QUESTION|| type == RE_NG_STAR_BEGIN || type == RE_NG_QUESTION) - { - ParseState.Restore(this); - } - else - { - m_uNumGroups = ParseState.m_uNumGroups; - } - *ppszRE = sz; - - int nE; - - if (type == RE_NG_STAR_BEGIN || type == RE_NG_PLUS || type == RE_NG_QUESTION) // Non-Greedy - { - int nCall = AddInstruction(RE_CALL); - if (nCall < 0) - return -1; - - bEmpty = false; - - nSE = ParseSE(ppszRE, bEmpty); - if (nSE < 0) - return nSE; - - if (bEmpty && (type == RE_NG_STAR_BEGIN || type == RE_NG_PLUS)) - { - SetLastParseError(REPARSE_ERROR_EMPTY_REPEATOP); - return -1; - } - bEmpty = true; - - *ppszRE = CharTraits::Next(*ppszRE); - *ppszRE = CharTraits::Next(*ppszRE); - - if (type == RE_NG_STAR_BEGIN || type == RE_NG_PLUS) - { - int nJmp = AddInstruction(RE_JMP); - if (nJmp < 0) - return -1; - GetInstruction(nCall).call.nTarget = nJmp+1; - GetInstruction(nJmp).jmp.nTarget = nCall; - } - else - GetInstruction(nCall).call.nTarget = nSE+1; - - if (type == RE_NG_PLUS) - nE = nFirst; - else - nE = nCall; - } - else // Greedy - { - - int nPushMem = AddInstruction(RE_PUSH_MEMORY); - if (nPushMem < 0) - return -1; - - int nStore = AddInstruction(RE_STORE_CHARPOS); - if (nStore < 0) - return -1; - - if (AddInstruction(RE_PUSH_CHARPOS) < 0) - return -1; - - int nCall = AddInstruction(RE_CALL); - if (nCall < 0) - return -1; - - if (AddInstruction(RE_POP_CHARPOS) < 0) - return -1; - - int nPopMem = AddInstruction(RE_POP_MEMORY); - if (nPopMem < 0) - return -1; - - int nJmp = AddInstruction(RE_JMP); - if (nJmp < 0) - return -1; - - GetInstruction(nPushMem).memory.nIndex = m_uRequiredMem++; - GetInstruction(nStore).memory.nIndex = GetInstruction(nPushMem).memory.nIndex; - GetInstruction(nCall).call.nTarget = nJmp+1; - GetInstruction(nPopMem).memory.nIndex = GetInstruction(nPushMem).memory.nIndex; - - bEmpty = false; - - nSE = ParseSE(ppszRE, bEmpty); - if (nSE < 0) - return nSE; - - if (bEmpty && (type == RE_STAR_BEGIN || type == RE_PLUS)) - { - SetLastParseError(REPARSE_ERROR_EMPTY_REPEATOP); - return -1; - } - - if (type != RE_PLUS && type != RE_NG_PLUS) - bEmpty = true; - - *ppszRE = CharTraits::Next(*ppszRE); - - - int nRetNoMatch = AddInstruction(RE_RET_NOMATCH); - if (nRetNoMatch < 0) - return -1; - - int nStore1 = AddInstruction(RE_STORE_CHARPOS); - if (nStore1 < 0) - return -1; - - GetInstruction(nRetNoMatch).memory.nIndex = GetInstruction(nPushMem).memory.nIndex; - GetInstruction(nStore1).memory.nIndex = GetInstruction(nPushMem).memory.nIndex; - - if (type != RE_QUESTION) - { - int nJmp1 = AddInstruction(RE_JMP); - if (nJmp1 < 0) - return -1; - GetInstruction(nJmp1).jmp.nTarget = nPushMem; - } - - GetInstruction(nJmp).jmp.nTarget = m_Instructions.GetCount(); - if (type == RE_PLUS) - nE = nFirst; - else - nE = nPushMem; - } - - return nE; - } - - - // ParseAltE: parse grammar rule AltE - int ParseAltE(const RECHAR **ppszRE, bool &bEmpty) - { - const RECHAR *sz = *ppszRE; - CParseState ParseState(this); - - int nPush = AddInstruction(RE_PUSH_CHARPOS); - if (nPush < 0) - return -1; - - int nCall = AddInstruction(RE_CALL); - if (nCall < 0) - return -1; - - GetInstruction(nCall).call.nTarget = nPush+4; - if (AddInstruction(RE_POP_CHARPOS) < 0) - return -1; - - int nJmpNext = AddInstruction(RE_JMP); - if (nJmpNext < 0) - return -1; - - int nE = ParseE(ppszRE, bEmpty); - if (nE < 0) - { - if (GetLastParseError()) - return -1; - ParseState.Restore(this); - return nE; - } - - int nJmpEnd = AddInstruction(RE_JMP); - if (nJmpEnd < 0) - return -1; - - GetInstruction(nJmpNext).jmp.nTarget = nJmpEnd+1; - - if (!MatchToken(ppszRE, '|')) - { - ParseState.Restore(this); - *ppszRE = sz; - - return ParseE(ppszRE, bEmpty); - } - - bool bEmptyAltE; - int nAltE = ParseAltE(ppszRE, bEmptyAltE); - GetInstruction(nJmpEnd).jmp.nTarget = m_Instructions.GetCount(); - GetInstruction(nJmpNext).jmp.nTarget = nAltE; - if (nAltE < 0) - { - if (GetLastParseError()) - return -1; - ParseState.Restore(this); - return nAltE; - } - bEmpty = bEmpty | bEmptyAltE; - return nPush; - } - - // ParseRE: parse grammar rule RE (regular expression) - int ParseRE(const RECHAR **ppszRE, bool &bEmpty) - { - if (**ppszRE == '\0') - return -1; - - int p = ParseAltE(ppszRE, bEmpty); - if (p < 0) - return p; - - bool bEmptyRE = true; - ParseRE(ppszRE, bEmptyRE); - if (GetLastParseError()) - return -1; - bEmpty = bEmpty && bEmptyRE; - return p; - } - - //pointers to the matched string and matched groups, currently point into an internal allocated - //buffer that hold a copy of the input string. - //This function fix these pointers to point into the original, user supplied buffer (first param to Match method). - //Example: If a ptr (szStart) currently point to +3, it is fixed to +3 - void FixupMatchContext(CAtlREMatchContext *pContext, const RECHAR *szOrig, const RECHAR *szNew) - { - ATLENSURE(pContext); - ATLASSERT(szOrig); - ATLASSERT(szNew); - - pContext->m_Match.szStart = szOrig + (pContext->m_Match.szStart - szNew); - pContext->m_Match.szEnd = szOrig + (pContext->m_Match.szEnd - szNew); - for (UINT i=0; im_uNumGroups; i++) - { - if (pContext->m_Matches[i].szStart==NULL || pContext->m_Matches[i].szEnd==NULL) - { - continue; //Do not fix unmatched groups. - } - pContext->m_Matches[i].szStart = szOrig + (pContext->m_Matches[i].szStart - szNew); - pContext->m_Matches[i].szEnd = szOrig + (pContext->m_Matches[i].szEnd - szNew); - } - } - // implementation - // helpers for dumping and debugging the rx engine -public: -#ifdef ATL_REGEXP_DUMP - size_t DumpInstruction(size_t ip) - { - printf("%08x ", ip); - switch (GetInstruction(ip).type) - { - case RE_NOP: - printf("NOP\n"); - ip++; - break; - - case RE_SYMBOL: - AtlprintfT(CAToREChar("Symbol %c\n"),GetInstruction(ip).symbol.nSymbol); - ip++; - break; - - case RE_ANY: - printf("Any\n"); - ip++; - break; - - case RE_RANGE: - printf("Range\n"); - ip++; - ip += InstructionsPerRangeBitField(); - break; - - case RE_NOTRANGE: - printf("NOT Range\n"); - ip++; - ip += InstructionsPerRangeBitField(); - break; - - case RE_RANGE_EX: - printf("RangeEx %08x\n", GetInstruction(ip).range.nTarget); - ip++; - break; - - case RE_NOTRANGE_EX: - printf("NotRangeEx %08x\n", GetInstruction(ip).range.nTarget); - ip++; - break; - - case RE_GROUP_START: - printf("Start group %d\n", GetInstruction(ip).group.nGroup); - ip++; - break; - - case RE_GROUP_END: - printf("Group end %d\n", GetInstruction(ip).group.nGroup); - ip++; - break; - - case RE_PUSH_CHARPOS: - printf("Push char pos\n"); - ip++; - break; - - case RE_POP_CHARPOS: - printf("Pop char pos\n"); - ip++; - break; - - case RE_STORE_CHARPOS: - printf("Store char pos %d\n", GetInstruction(ip).memory.nIndex); - ip++; - break; - - case RE_GET_CHARPOS: - printf("Get char pos %d\n", GetInstruction(ip).memory.nIndex); - ip++; - break; - - case RE_STORE_STACKPOS: - printf("Store stack pos %d\n", GetInstruction(ip).memory.nIndex); - ip++; - break; - - case RE_GET_STACKPOS: - printf("Get stack pos %d\n", GetInstruction(ip).memory.nIndex); - ip++; - break; - - case RE_CALL: - printf("Call %08x\n", GetInstruction(ip).call.nTarget); - ip++; - break; - - case RE_JMP: - printf("Jump %08x\n", GetInstruction(ip).jmp.nTarget); - ip++; - break; - - case RE_RETURN: - printf("return\n"); - ip++; - break; - - case RE_PUSH_MEMORY: - printf("Push memory %08x\n", GetInstruction(ip).memory.nIndex); - ip++; - break; - - case RE_POP_MEMORY: - printf("Pop memory %08x\n", GetInstruction(ip).memory.nIndex); - ip++; - break; - - case RE_RET_NOMATCH: - printf("Return no match %08x\n", GetInstruction(ip).memory.nIndex); - ip++; - break; - - case RE_MATCH: - printf("END\n"); - ip++; - break; - - case RE_ADVANCE: - printf("ADVANCE\n"); - ip++; - break; - - case RE_FAIL: - printf("FAIL\n"); - ip++; - break; - - case RE_PREVIOUS: - printf("Prev %d\n", GetInstruction(ip).prev.nGroup); - ip++; - break; - - case RE_PUSH_GROUP: - printf("Push group %d\n", GetInstruction(ip).group.nGroup); - ip++; - break; - - case RE_POP_GROUP: - printf("Pop group %d\n", GetInstruction(ip).group.nGroup); - ip++; - break; - - - default: - printf("????\n"); - ip++; - break; - } - return ip; - } - - void Dump(size_t ipCurrent = 0) - { - size_t ip = 0; - - while (ip < m_Instructions.GetCount()) - { - if (ip == ipCurrent) - printf("->"); - ip = DumpInstruction(ip); - } - } -#endif - -#ifdef ATLRX_DEBUG - void cls( HANDLE hConsole ) - { - COORD coordScreen = { 0, 0 }; /* here's where we'll home the - cursor */ - BOOL bSuccess; - DWORD cCharsWritten; - CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */ - DWORD dwConSize; /* number of character cells in - the current buffer */ - - /* get the number of character cells in the current buffer */ - - bSuccess = GetConsoleScreenBufferInfo( hConsole, &csbi ); - dwConSize = csbi.dwSize.X * csbi.dwSize.Y; - - /* fill the entire screen with blanks */ - - bSuccess = FillConsoleOutputCharacter( hConsole, (TCHAR) ' ', - dwConSize, coordScreen, &cCharsWritten ); - - /* get the current text attribute */ - - bSuccess = GetConsoleScreenBufferInfo( hConsole, &csbi ); - - /* now set the buffer's attributes accordingly */ - - bSuccess = FillConsoleOutputAttribute( hConsole, csbi.wAttributes, - dwConSize, coordScreen, &cCharsWritten ); - - /* put the cursor at (0, 0) */ - - bSuccess = SetConsoleCursorPosition( hConsole, coordScreen ); - return; - } - - void DumpStack(CAtlREMatchContext *pContext) - { - for (size_t i=pContext->m_nTos; i>0; i--) - { - if (pContext->m_stack[i] < (void *) m_Instructions.GetCount()) - printf("0x%p\n", pContext->m_stack[i]); - else - { - // assume a pointer into the input - AtlprintfT(CAToREChar("%s\n"), pContext->m_stack[i]); - } - } - } - - void DumpMemory(CAtlREMatchContext *pContext) - { - for (UINT i=0; i(CAToREChar("%d: %s\n"), i, pContext->m_Mem.m_p[i]); - } - } - - virtual void OnDebugEvent(size_t ip, const RECHAR *szIn, const RECHAR *sz, CAtlREMatchContext *pContext) - { - cls(GetStdHandle(STD_OUTPUT_HANDLE)); - printf("----------Code---------\n"); - Dump(ip); - printf("----------Input---------\n"); - AtlprintfT(CAToREChar("%s\n"), szIn); - for (int s=0; szIn+s < sz; s++) - { - printf(" "); - } - printf("^\n"); - printf("----------Memory---------\n"); - DumpMemory(pContext); - printf("----------Stack---------\n"); - DumpStack(pContext); - getchar(); - } -#endif - -}; - -} // namespace ATL -#pragma pack(pop) - -#endif // __ATLRX_H__ diff --git a/microsip/const.h b/microsip/const.h deleted file mode 100644 index d1292c778e22108db9dc0b2be7af1d52e530963d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2164 zcmbW2Ur$p(5XI-&#P6_y7cjL5#0dHXDA-tNV~fVbgxvmvo0PWcy+HW#>hH|<_Syzhkd#oAz=x+QW8= zUl;GOwX9}M_tvhQC~s|xcIT~X*K^N|(Zs6knUZ63p1nlTCUa^T(Iy`IlK+GVVP+jL z@6!T4V;hj|j&<4IVY|n6L*KL<;2eHocReJBlk*d$h=AZ4kIxatnR%$GLM(c&RzIqo~MUr zX8}=>|CsENiI=kZF`|D}V6sw$>ZKS#mPm7|HZx|$)4^}NG#=r!p$ z_cvaH0h|r3GRGt4rI=t}(RkZFT7$Z_nIBN$Z*D)Z&os^3SfoP576Mg3d;89__$_dy zsAfW@lr^D_8kW*W_=qj(sbu5SK9J*x{4vjg9fGIsn1mwg_t@uW__k=$K!aVvD&+}h z8;>JSQ1_Xv=UAKgwb)g~FEEOlidahwPt){ZhD~=%Y7Ksia!xA#GjbLgiax+%yv5SL zMnmUF^^ z(#sQHog8bag2(S~ng5}Ctf)0Gbzx8A*S61p8%Cn4#8DI62_Aj-Xu)EEVb^wf&9(0k zG#SWrKFv>EDS_1;f9>_&Z@c#!Rs&jTxkrI+%WJ3Ey1&*5EM0po6j8b3n%>O;`SlV8 zyWmxZ>)sl432d7g=G1AyBaf*3ElqqUag@=wa358tHsqj VQq)WLI -#include /* strchr */ -#include -//#include "ggets.h" - - -// Adapted from code by Ana Sayfa. Thanks also to Dave Kondrad. -template - TTCHAR *ReallocString(TTCHAR *ptr, size_t newsize, size_t oldsize, IN OUT bool& bOwnBuffer) /*size_t unsigned int*/ -{ - // Only reallocate if needed - if (newsize > oldsize) - { - TTCHAR* pTemp = NULL; - - // Declare the new string and zero it out - pTemp = new TTCHAR[newsize] ; - memset(pTemp, '\0', newsize*sizeof(TTCHAR)); - - // Copy the old string if there is one - if (ptr) - { - // Ensure we only copy up to the size of the new buffer - memcpy(pTemp, ptr, min(oldsize*sizeof(TTCHAR), newsize*sizeof(TTCHAR))); - - // Don't delete a default buffer we didn't create - if (bOwnBuffer) - { - if(oldsize > 1) - { - delete [] ptr; - } - else - { - delete ptr; - } - } - } - - // We own it now! - bOwnBuffer = true; - - return pTemp; - } - - return ptr; -} - -// Encapsulate multibyte and Unicode versions of fgets in functions with same -// name. Use this function in our template fggets function and when TTCHAR is -// resolved the correct one will be called -char *GetFileString( char *string, int n, FILE *stream ) -{ - return fgets( string, n, stream ); -} - -wchar_t *GetFileString( wchar_t *string, int n, FILE *stream ) -{ - return fgetws( string, n, stream ); -} - -// Same with strchr -char *FindCharInString( const char *string, int c ) -{ - // This *should* work OK even with UTF-8, since we're only searching for - // '\n' in practice. Careful if you try to use this for anything other - // than ASCII characters. - return (char*)_mbschr( (const unsigned char *)string, c ); -} - -wchar_t *FindCharInString( const wchar_t *string, wint_t c ) -{ - return (wchar_t *)wcschr( string, c ); -} - - -#define INITSIZE 112 /* power of 2 minus 16, helps malloc */ -#define DELTASIZE (INITSIZE + 16) - -// DP 29/03/2006 Modified to "templatise" it so it will work with Unicode and MB -// DP 24/06/2006 Now accepts default buffer to avoid the need for dynamic memory allocation -template - int fggets(TTCHAR* *ln, FILE *f, IN OUT bool& bOwnBuffer, IN const int nDefaultBufferSizeChars) -// int fggets(CTemplateSmartPtrArray& spln, FILE *f, const int nDefaultBufferSizeChars) -{ - int cursize, rdsize, nOldSize; - TTCHAR *buffer, *temp, *rdpoint, *crlocn; - - bOwnBuffer = false; - - ASSERT(*ln != NULL || nDefaultBufferSizeChars==0); - - // DP 24/06/2007: Allow default buffer to be passed in for reading. Avoids need for "new"s/"delete"s in 99% of cases - if (nDefaultBufferSizeChars == 0 || *ln == NULL) - { - // DP 29/3/2006: Changed to use new - buffer = new TTCHAR[INITSIZE]; - if (NULL == buffer) - return FGGETS_NOMEM; - - // DP 24/06/2007: Signal that we own the buffer now - bOwnBuffer = true; - } - else - { - buffer = *ln; - } - - *ln = NULL; /* default */ -// if (NULL == (buffer = (char*)malloc(INITSIZE))) - - // DP 29/3/2006: Added oldsize variable - // Initialise original size to default buffer size or INITSIZE, whichever applies - cursize = rdsize = nOldSize = (nDefaultBufferSizeChars==0 ? INITSIZE:nDefaultBufferSizeChars); - rdpoint = buffer; - *buffer = '\0'; - -// if (NULL == fgets(rdpoint, rdsize, f)) - if (NULL == GetFileString(rdpoint, rdsize, f)) - { -// free(buffer); - // DP 29/3/2006: Changed to use delete - if (bOwnBuffer) - { - delete buffer; - } - return EOF; - } - - /* initial read succeeded, now decide about expansion */ -// while (NULL == (crlocn = strchr(rdpoint, '\n'))) - while (NULL == (crlocn = FindCharInString(rdpoint, '\n'))) - { - /* line is not completed, expand */ - - // DP 29/3/2006: Save current buffer size - nOldSize = cursize; - - /* set up cursize, rdpoint and rdsize, expand buffer */ - rdsize = DELTASIZE + 1; /* allow for a final '\0' */ - cursize += DELTASIZE; -// if (NULL == (temp = (char*)realloc(buffer, (size_t)cursize))) { - - // DP 29/3/2006: Changed to use custom realloc - if (NULL == (temp = ReallocString(buffer, (size_t)cursize, (size_t)nOldSize, bOwnBuffer))) - { - /* ran out of memory */ - *ln = buffer; /* partial line, next call may fail */ - return FGGETS_NOMEM; - } - buffer = temp; - /* Read into the '\0' up */ - rdpoint = buffer + (cursize - DELTASIZE - 1); - - /* get the next piece of this line */ -// if (NULL == fgets(rdpoint, rdsize, f)) { - if (NULL == GetFileString(rdpoint, rdsize, f)) - { - /* early EOF encountered */ -// crlocn = strchr(buffer, '\0'); - crlocn = FindCharInString(buffer, '\0'); - break; - } - } /* while line not complete */ - - *crlocn = '\0'; /* mark line end, strip \n */ - rdsize = (int)(crlocn - buffer); - -// if (NULL == (temp = (char*)realloc(buffer, (size_t)rdsize + 1))) { - - // DP 29/3/2006: Changed to use custom realloc - if (NULL == (temp = ReallocString(buffer, (size_t)rdsize + 1, (size_t)cursize, bOwnBuffer))) - { - *ln = buffer; /* without reducing it */ - return FGGETS_OK; - } - *ln = temp; - return FGGETS_OK; -} /* fggets */ -/* End of ggets.c */ diff --git a/microsip/ggets.h b/microsip/ggets.h deleted file mode 100644 index d2211956..00000000 --- a/microsip/ggets.h +++ /dev/null @@ -1,52 +0,0 @@ -/* File ggets.h - goodgets is a safe alternative to gets */ -/* By C.B. Falconer. Public domain 2002-06-22 */ -/* attribution appreciated. */ - - -/* Revised 2002-06-26 New prototype. - 2002-06-27 Incomplete final lines - */ - -/* fggets and ggets [which is fggets(ln, stdin)] set *ln to - a buffer filled with the next complete line from the text - stream f. The storage has been allocated within fggets, - and is normally reduced to be an exact fit. The trailing - \n has been removed, so the resultant line is ready for - dumping with puts. The buffer will be as large as is - required to hold the complete line. - - Note: this means a final file line without a \n terminator - has an effective \n appended, as EOF occurs within the read. - - If no error occurs fggets returns 0. If an EOF occurs on - the input file, EOF is returned. For memory allocation - errors some positive value is returned. In this case *ln - may point to a partial line. For other errors memory is - freed and *ln is set to NULL. - - Freeing of assigned storage is the callers responsibility - */ - -#ifndef ggets_h_ -# define ggets_h_ - -//# ifdef __cplusplus -// extern "C" { -//# endif - -// DP 26/3/2006 Altered enum and moved to .h file (duh!) -enum {FGGETS_OK = 0, FGGETS_NOMEM}; - -template - int fggets(CTemplateSmartPtrArray& spln, FILE *f, IN OUT bool& bOwnBuffer, IN const int nDefaultBufferSizeChars=0); -// int fggets(TCHAR* *ln, FILE *f, IN const int nDefaultBufferSizeChars=0); - -#include "ggets.cpp" - -//#define ggets(ln) fggets(ln, stdin) - -//# ifdef __cplusplus -// } -//# endif -#endif -/* END ggets.h */ diff --git a/microsip/global.cpp b/microsip/global.cpp deleted file mode 100644 index f60703df..00000000 --- a/microsip/global.cpp +++ /dev/null @@ -1,1314 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "global.h" -#include "settings.h" -#include "utf.h" -#include "langpack.h" -#include - -#ifdef UNICODE -#define CF_TEXT_T CF_UNICODETEXT -#else -#define CF_TEXT_T CF_TEXT -#endif - -struct call_tonegen_data *tone_gen = NULL; -int transport; -pjsua_acc_id account; -pjsua_acc_id account_local; -CString lastTransferNumber; -pjsua_conf_port_id msip_conf_port_id; -pjsua_call_id msip_conf_port_call_id; - -int msip_audio_input; -int msip_audio_output; -int msip_audio_ring; - -CList DTMFTonegens; - - -CString GetErrorMessage(pj_status_t status) -{ - CStringA str; - char *buf = str.GetBuffer(PJ_ERR_MSG_SIZE-1); - pj_strerror(status, buf, PJ_ERR_MSG_SIZE); - str.ReleaseBuffer(); - int i = str.ReverseFind( '(' ); - if (i!=-1) { - str = str.Left(i-1); - } - if (str == "Invalid Request URI" || str == "Invalid URI") { - str = "Invalid number"; - } - return Translate(CString(str).GetBuffer()); -} - -BOOL ShowErrorMessage(pj_status_t status) -{ - if (status!=PJ_SUCCESS) { - AfxMessageBox(GetErrorMessage(status)); - return TRUE; - } else { - return FALSE; - } -} - -CString RemovePort(CString domain) -{ - int pos = domain.Find(_T(":")); - if (pos != -1) { - return domain.Mid(0,pos); - } else { - return domain; - } -} - -BOOL IsIP(CString host) -{ - CStringA hostA(host); - char *pHost = hostA.GetBuffer(); - unsigned long ulAddr = inet_addr(pHost); - if (ulAddr !=INADDR_NONE && ulAddr != INADDR_ANY) { - struct in_addr antelope; - antelope.S_un.S_addr = ulAddr; - if (strcmp(inet_ntoa(antelope),pHost)==0) { - return TRUE; - } - } - return FALSE; -} - -void ParseSIPURI(CString in, SIPURI* out) -{ - // tone_gen.toneslot = -1; - // tone_gen = NULL; - - // "WEwewew rewewe" - // sip:qqweqwe@qwerer.com;rrrr=tttt;qweqwe=rrr?qweqwr=rqwrqwr - if (in.Right(1) == _T(">")) { - in = in.Left(in.GetLength()-1); - } - out->name = _T(""); - out->user = _T(""); - out->domain = _T(""); - out->parameters = _T(""); - - int start = in.Find( _T("sip:") ); - int end; - if (start>0) - { - out->name = in.Left(start); - out->name.Trim(_T(" \" <")); - if (!out->name.CompareNoCase(_T("unknown"))) - { - out->name = _T(""); - } - } - if (start>=0) - { - start+=4; - } else { - start = 0; - } - end = in.Find( _T("@"), start ); - if (end>=0) - { - out->user=in.Mid(start,end-start); - start=end+1; - } - end = in.Find( _T(";"), start ); - if (end>=0) { - out->domain = in.Mid(start,end-start); - start=end; - out->parameters = in.Mid(start); - } else { - end = in.Find( _T("?"), start ); - if (end>=0) { - out->domain = in.Mid(start,end-start); - start=end; - out->parameters = in.Mid(start); - } else { - out->domain = in.Mid(start); - } - } -} - -CString PjToStr(const pj_str_t* str, BOOL utf) -{ - CStringA rab; - rab.Format("%.*s", str->slen, str->ptr); - if (utf) - { -#ifdef _UNICODE - WCHAR* msg; - Utf8DecodeCP(rab.GetBuffer(), CP_ACP, &msg); - return msg; -#else - return Utf8DecodeCP(rab.GetBuffer(), CP_ACP, NULL); -#endif - } else - { - return CString(rab); - } -} - -pj_str_t StrToPjStr(CString str) -{ - return pj_str(StrToPj(str)); -} - -char* StrToPj(CString str) -{ -#ifdef _UNICODE - return Utf8EncodeUcs2(str.GetBuffer()); -#else - return Utf8EncodeCP(str.GetBuffer(), CP_ACP); -#endif -} - -CString Utf8DecodeUni(CStringA str) -{ -#ifdef _UNICODE - LPTSTR msg; - Utf8DecodeCP(str.GetBuffer(), CP_ACP, &msg); - return msg; -#else - return Utf8DecodeCP(str.GetBuffer(), CP_ACP, NULL); -#endif -} - -CStringA UnicodeToAnsi(CString str) -{ - CStringA res; - int nCount = str.GetLength(); - for( int nIdx =0; nIdx < nCount; nIdx++ ) - { - res+=str[nIdx]; - } - return res; -} - -CString AnsiToUnicode(CStringA str) -{ - CString res; - int nCount = str.GetLength(); - for( int nIdx =0; nIdx < nCount; nIdx++ ) - { - res+=str[nIdx]; - } - return res; -} - -CString XMLEntityDecode(CString str) -{ - str.Replace(_T("<"),_T("<")); - str.Replace(_T(">"),_T(">")); - str.Replace(_T("""),_T("\"")); - str.Replace(_T("&"),_T("&")); - return str; -} - -CString XMLEntityEncode(CString str) -{ - str.Replace(_T("&"),_T("&")); - str.Replace(_T("<"),_T("<")); - str.Replace(_T(">"),_T(">")); - str.Replace(_T("\""),_T(""")); - return str; -} - -void OpenURL(CString url) -{ - CString param; - param.Format(_T("url.dll,FileProtocolHandler %s"),url); - ShellExecute(NULL, NULL, _T("rundll32.exe"), param, NULL, SW_SHOWNORMAL); -} - -CString GetDuration(int sec, bool zero) -{ - CString duration; - if (sec || zero) { - int h,m,s; - s = sec; - h = s/3600; - s = s%3600; - m = s/60; - s = s%60; - if (h) { - duration.Format(_T("%d:%02d:%02d"),h,m,s); - } else { - duration.Format(_T("%d:%02d"),m,s); - } - } - return duration; -} - -void AddTransportSuffix(CString &str) -{ - switch (transport) - { - case MSIP_TRANSPORT_TCP: - str.Append(_T(";transport=tcp")); - break; - case MSIP_TRANSPORT_TLS: - str.Append(_T(";transport=tls")); - break; - } -} - -CString GetSIPURI(CString str, bool isSimple, bool isLocal, CString domain) -{ - CString rab = str; - rab.MakeLower(); - int pos = rab.Find(_T("sip:")); - if (pos==-1) - { - str=_T("sip:")+str; - } - if (!isLocal) { - pos = str.Find(_T("@")); - if (accountSettings.accountId && pos == -1) { - str.Append(_T("@") + (!domain.IsEmpty() ? domain : accountSettings.account.domain)); - } - } - if (str.GetAt(str.GetLength()-1)=='>') - { - str = str.Left(str.GetLength()-1); - if (!isSimple) { - if (!isLocal || !accountSettings.accountId) { - AddTransportSuffix(str); - } - } - str += _T(">"); - } else { - if (!isSimple) { - if (!isLocal || !accountSettings.accountId) { - AddTransportSuffix(str); - } - } - str = _T("<") + str + _T(">"); - } - return str; -} - -bool SelectSIPAccount(CString number, pjsua_acc_id &acc_id, pj_str_t &pj_uri) -{ - if (pjsua_var.state!=PJSUA_STATE_RUNNING) { - return false; - } - SIPURI sipuri; - ParseSIPURI(number, &sipuri); - if (pjsua_acc_is_valid(account) && pjsua_acc_is_valid(account_local)) { - acc_id = account; - if (accountSettings.account.domain != sipuri.domain) { - int pos = sipuri.domain.Find(_T(":")); - CString domainWithoutPort = RemovePort(sipuri.domain); - if (domainWithoutPort.CompareNoCase(_T("localhost"))==0 || IsIP(domainWithoutPort)) { - acc_id = account_local; - } - } - } else if (pjsua_acc_is_valid(account)) { - acc_id = account; - } else if (pjsua_acc_is_valid(account_local)) { - acc_id = account_local; - } else { - return false; - } - pj_uri = StrToPjStr ( GetSIPURI(number, acc_id == account_local, acc_id == account_local) ); - return true; -} - -bool IsPSTNNnmber(CString number) -{ - bool isDigits = true; - for (int i = 0; i < number.GetLength(); i++) - { - if ((number[i] > '9' || number[i] < '0') && number[i] != '*' && number[i] != '#' && number[i] != '.' && number[i] != '-' && number[i] != '(' && number[i] != ')' && number[i] != ' ' && number[0] != '+') - { - isDigits = false; - break; - } - } - return isDigits; -} - -CString FormatNumber(CString number, CString *commands) { - int pos = number.Find(','); - if (pos>0 && posleft = GetSystemMetrics (SM_XVIRTUALSCREEN); - rect->top = GetSystemMetrics (SM_YVIRTUALSCREEN); - rect->right = GetSystemMetrics (SM_CXVIRTUALSCREEN) - rect->left; - rect->bottom = GetSystemMetrics (SM_CYVIRTUALSCREEN) - rect->top; -} - -struct call_tonegen_data *call_init_tonegen(pjsua_call_id call_id) -{ - if (pjsua_var.state!=PJSUA_STATE_RUNNING) { - return NULL; - } - pj_status_t status; - pj_pool_t *pool; - struct call_tonegen_data *cd; - pjsua_call_info ci; - - if (call_id !=-1 ) { - pjsua_call_get_info(call_id, &ci); - - if (ci.media_status != PJSUA_CALL_MEDIA_ACTIVE) - return NULL; - } - - pool = pjsua_pool_create("mycall", 512, 512); - cd = PJ_POOL_ZALLOC_T(pool, struct call_tonegen_data); - cd->pool = pool; - - status = pjmedia_tonegen_create(cd->pool, 8000, 1, 64, 16, 0, &cd->tonegen); - if (status != PJ_SUCCESS) { - return NULL; - } - - pjsua_conf_add_port(cd->pool, cd->tonegen, &cd->toneslot); - - if (call_id !=-1 ) { - pjsua_conf_connect(cd->toneslot, ci.conf_slot); - } - if (accountSettings.localDTMF || call_id==-1) { - pjsua_conf_connect(cd->toneslot, 0); - } - - if (call_id !=-1 ) { - call_user_data *user_data = (call_user_data *)pjsua_call_get_user_data(call_id); - if (!user_data) { - user_data = new call_user_data(call_id); - pjsua_call_set_user_data(call_id, user_data); - } - user_data->tonegen_data = cd; - } - return cd; -} - - -static UINT_PTR destroyDTMFPlayerTimer = NULL; -static UINT_PTR tonegenBusyTimer = NULL; - -void destroyDTMFPlayerTimerHandler( - HWND hwnd, - UINT uMsg, - UINT_PTR idEvent, - DWORD dwTime) -{ - if (!tone_gen || pjsua_var.state!=PJSUA_STATE_RUNNING ||!pjmedia_tonegen_is_busy(tone_gen->tonegen)) { - if (destroyDTMFPlayerTimer) { - KillTimer(NULL,destroyDTMFPlayerTimer); - destroyDTMFPlayerTimer = NULL; - } - call_deinit_tonegen(-1); - } -} - -void DTMFQueueTimerHandler( - HWND hwnd, - UINT uMsg, - UINT_PTR idEvent, - DWORD dwTime) -{ - KillTimer(hwnd, idEvent); - pjsua_call_id call_id = (pjsua_call_id) idEvent; - if (pjsua_var.state==PJSUA_STATE_RUNNING && pjsua_call_is_active(call_id)) { - call_user_data *user_data = (call_user_data *) pjsua_call_get_user_data(call_id); - if (user_data && !user_data->commands.IsEmpty()) { - CString dtmf; - int pos = user_data->commands.Find(','); - if (pos!=-1) { - dtmf = user_data->commands.Mid(0,pos); - user_data->commands = user_data->commands.Mid(pos+1); - } else { - dtmf = user_data->commands; - user_data->commands.Empty(); - } - if (!dtmf.IsEmpty()) { - msip_call_dial_dtmf(call_id, dtmf); - } - if (!user_data->commands.IsEmpty()) { - ::SetTimer(hwnd, idEvent, 1000 + 200 * dtmf.GetLength() , (TIMERPROC)DTMFQueueTimerHandler); - } - } - } -} - -void tonegenBusyHandler( - HWND hwnd, - UINT uMsg, - UINT_PTR idEvent, - DWORD dwTime) -{ - POSITION pos = DTMFTonegens.GetHeadPosition(); - while (pos) { - POSITION posKey = pos; - pjmedia_port *port = DTMFTonegens.GetNext(pos); - if (pjsua_var.state!=PJSUA_STATE_RUNNING || pjmedia_tonegen_is_busy(port) == PJ_FALSE) { - DTMFTonegens.RemoveAt(posKey); - } - }; - if (DTMFTonegens.IsEmpty()) { - KillTimer(NULL,tonegenBusyTimer); - tonegenBusyTimer = NULL; - CWnd *hWnd = AfxGetApp()->m_pMainWnd; - if (hWnd) { - hWnd->PostMessage(UM_REFRESH_LEVELS, NULL, NULL); - } - } -} - -void msip_set_sound_device(int outDev, bool forse){ - if (pjsua_var.state!=PJSUA_STATE_RUNNING) { - return; - } - int in,out; - if (forse || pjsua_get_snd_dev(&in,&out)!=PJ_SUCCESS || msip_audio_input!=in || outDev!=out ) { - pjsua_set_snd_dev(msip_audio_input, outDev); - } -} - - -void msip_call_dial_dtmf(pjsua_call_id call_id, CString digits) -{ - if (pjsua_var.state!=PJSUA_STATE_RUNNING) { - return; - } - bool simulate = true; - if (call_id != PJSUA_INVALID_ID) { - pjsua_call_info call_info; - pjsua_call_get_info(call_id, &call_info); - if (call_info.media_status == PJSUA_CALL_MEDIA_ACTIVE) { - pj_str_t pj_digits = StrToPjStr ( digits ); - if (accountSettings.DTMFMethod == 1) { - // in-band - simulate = !call_play_digit(call_id, StrToPj(digits)); - } else if (accountSettings.DTMFMethod == 2) { - // RFC2833 - pjsua_call_dial_dtmf(call_id, &pj_digits); - } else if (accountSettings.DTMFMethod == 3) { - // sip-info - msip_call_send_dtmf_info(call_id, pj_digits); - } else { - // auto - if (pjsua_call_dial_dtmf(call_id, &pj_digits) != PJ_SUCCESS) { - simulate = !call_play_digit(call_id, StrToPj(digits)); - } - } - } - } - if (simulate && accountSettings.localDTMF) { - msip_set_sound_device(msip_audio_output); - call_play_digit(-1, StrToPj(digits)); - } -} - -BOOL call_play_digit(pjsua_call_id call_id, const char *digits, int duration) -{ - if (pjsua_var.state!=PJSUA_STATE_RUNNING) { - return FALSE; - } - pjmedia_tone_digit d[16]; - unsigned i, count = strlen(digits); - struct call_tonegen_data *cd; - call_user_data *user_data = NULL; - if (call_id !=-1 ) { - user_data = (call_user_data *)pjsua_call_get_user_data(call_id); - if (user_data && user_data->tonegen_data) { - cd = user_data->tonegen_data; - } else { - cd = NULL; - } - } else { - cd = tone_gen; - } - if (!cd) - cd = call_init_tonegen(call_id); - if (!cd) - return FALSE; - if (call_id == -1 ) { - tone_gen = cd; - } - - if (count > PJ_ARRAY_SIZE(d)) - count = PJ_ARRAY_SIZE(d); - - pj_bzero(d, sizeof(d)); - for (i=0; itonegen)==NULL) { - DTMFTonegens.AddTail(cd->tonegen); - } - if (tonegenBusyTimer) { - KillTimer(NULL,tonegenBusyTimer); - } - tonegenBusyTimer = SetTimer(NULL, NULL, 800, (TIMERPROC)tonegenBusyHandler); - - } - - pjmedia_tonegen_play_digits(cd->tonegen, count, d, 0); - - if (call_id == -1 ) { - if (destroyDTMFPlayerTimer) { - KillTimer(NULL,destroyDTMFPlayerTimer); - } - destroyDTMFPlayerTimer = SetTimer(NULL, NULL, 5000, (TIMERPROC)destroyDTMFPlayerTimerHandler); - } - return TRUE; -} - -void call_deinit_tonegen(pjsua_call_id call_id) -{ - struct call_tonegen_data *cd; - call_user_data *user_data = NULL; - - if (call_id !=-1 ) { - if (pjsua_var.state==PJSUA_STATE_RUNNING) { - user_data = (call_user_data *)pjsua_call_get_user_data(call_id); - } - if (user_data && user_data->tonegen_data) { - cd = user_data->tonegen_data; - POSITION position = DTMFTonegens.Find(cd->tonegen); - if (position!=NULL) { - DTMFTonegens.RemoveAt(position); - } - - } else { - cd = NULL; - } - } else { - cd = tone_gen; - } - if (!cd) - return; - - if (pjsua_var.state==PJSUA_STATE_RUNNING) { - pjsua_conf_remove_port(cd->toneslot); - pjmedia_port_destroy(cd->tonegen); - pj_pool_release(cd->pool); - } - - if (call_id !=-1 ) { - if (user_data) { - user_data->tonegen_data = NULL; - } - } else { - tone_gen = NULL; - } -} - -unsigned call_get_count_noincoming() -{ - unsigned noincoming_count = 0; - pjsua_call_id call_ids[PJSUA_MAX_CALLS]; - unsigned count = PJSUA_MAX_CALLS; - if (pjsua_var.state==PJSUA_STATE_RUNNING && pjsua_enum_calls ( call_ids, &count)==PJ_SUCCESS) { - for (unsigned i = 0; i < count; ++i) { - pjsua_call_info call_info; - pjsua_call_get_info(call_ids[i], &call_info); - if (call_info.role!=PJSIP_ROLE_UAS || (call_info.state!=PJSIP_INV_STATE_INCOMING && call_info.state!=PJSIP_INV_STATE_EARLY)) { - noincoming_count++; - } - } - } - return noincoming_count; -} - -void call_hangup_all_noincoming(bool onHold) -{ - pjsua_call_id call_ids[PJSUA_MAX_CALLS]; - unsigned count = PJSUA_MAX_CALLS; - if (pjsua_var.state==PJSUA_STATE_RUNNING && pjsua_enum_calls ( call_ids, &count)==PJ_SUCCESS) { - for (unsigned i = 0; i < count; ++i) { - pjsua_call_info call_info; - pjsua_call_get_info(call_ids[i], &call_info); - if (call_info.role!=PJSIP_ROLE_UAS || (call_info.state!=PJSIP_INV_STATE_INCOMING && call_info.state!=PJSIP_INV_STATE_EARLY)) { - if (onHold && call_info.media_status == PJSUA_CALL_MEDIA_LOCAL_HOLD) { - continue; - } - msip_call_hangup_fast(call_ids[i]); - } - } - } -} - -CStringA urlencode(CStringA str) -{ - CStringA escaped; - int max = str.GetLength(); - for(int i=0; i>4; - char dig2 = (dec&0x0F); - if ( 0<= dig1 && dig1<= 9) dig1+=48; //0,48inascii - if (10<= dig1 && dig1<=15) dig1+=97-10; //a,97inascii - if ( 0<= dig2 && dig2<= 9) dig2+=48; - if (10<= dig2 && dig2<=15) dig2+=97-10; - - CStringA r; - r.AppendFormat ("%c", dig1); - r.AppendFormat ("%c", dig2); - return r; -} - -static DWORD WINAPI URLGetAsyncThread( LPVOID lpParam ) -{ - URLGetAsyncData *data = (URLGetAsyncData *)lpParam; - data->body.Empty(); - data->headers.Empty(); - data->statusCode = 0; - if (!data->url.IsEmpty()) { - try { - CInternetSession session; - CHttpConnection* pHttp = NULL; - CHttpFile* pFile = NULL; - DWORD dwServiceType; - CString strServer; - CString strObject; - INTERNET_PORT nPort; - if (AfxParseURL(data->url, dwServiceType, strServer, strObject, nPort)) { - pHttp = session.GetHttpConnection(strServer, (dwServiceType==AFX_INET_SERVICE_HTTPS ? INTERNET_FLAG_SECURE : 0), nPort); - pFile = pHttp->OpenRequest(CHttpConnection::HTTP_VERB_GET,strObject, 0, 1, 0, 0, - INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE | (dwServiceType==AFX_INET_SERVICE_HTTPS ? INTERNET_FLAG_SECURE : 0)); - if (dwServiceType==AFX_INET_SERVICE_HTTPS) { - pFile->SetOption(INTERNET_OPTION_SECURITY_FLAGS, - SECURITY_FLAG_IGNORE_CERT_CN_INVALID | - SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | - SECURITY_FLAG_IGNORE_UNKNOWN_CA | - SECURITY_FLAG_IGNORE_WRONG_USAGE - ); - } - pFile->SetOption(INTERNET_OPTION_CONNECT_TIMEOUT,10000); - if (pFile->SendRequest()) { - pFile->QueryInfoStatusCode(data->statusCode); - CStringA buf; - int i; - UINT len = 0; - do { - LPSTR p = data->body.GetBuffer(len+1024); - i = pFile->Read(p+len,1024); - len+=i; - data->body.ReleaseBuffer(len); - } while (i>0); - //-- - pFile->QueryInfo( - HTTP_QUERY_RAW_HEADERS_CRLF, - data->headers - ); - pFile->Close(); - } - session.Close(); - } else { - data->statusCode = 0; - } - } catch (CInternetException *e) { - data->statusCode = 0; - } - } - if (data->message) { - if (data->hWnd) { - PostMessage(data->hWnd, data->message, (WPARAM)data, 0); - } - } else { - delete data; - } - return 0; -} - -void URLGetAsync(CString url, HWND hWnd, UINT message) -{ - HANDLE hThread; - URLGetAsyncData *data = new URLGetAsyncData(); - data->hWnd = hWnd; - data->message = message; - data->statusCode = 0; - data->url = url; - if (!CreateThread(NULL,0, URLGetAsyncThread, data, 0, NULL)) { - data->url.Empty(); - URLGetAsyncThread(data); - } -} - -URLGetAsyncData URLGetSync(CString url) -{ - URLGetAsyncData data; - data.hWnd = 0; - data.message = 1; - data.url = url; - URLGetAsyncThread(&data); - return data; -} - -CString Bin2String(CByteArray *ca) -{ - CString res; - int k=ca->GetSize(); - for(int i=0;iGetAt(i); - res.AppendFormat(_T("%02x"),ca->GetAt(i)); - } - return res; -} - -void String2Bin(CString str, CByteArray *res) -{ - res->RemoveAll(); - int k=str.GetLength(); - CStringA rab; - for(int i=0;iAdd(bin); - } -} - -void CommandLineToShell(CString cmd, CString &command, CString ¶ms) -{ - cmd.Trim(); - command.Empty(); - params.Empty(); - int nArgs; - LPWSTR *szArglist = CommandLineToArgvW(cmd, &nArgs); - if (NULL == szArglist) { - AfxMessageBox(_T("Wrong command: ") + cmd); - } - else for (int i = 0; i < nArgs; i++) { - if (!i) { - command = szArglist[i]; - } - else { - params.AppendFormat(_T("%s "), szArglist[i]); - } - } - params.TrimRight(); - LocalFree(szArglist); -} - -CString get_account_username() -{ - CString res = accountSettings.account.username; - return res; -} - -CString get_account_password() -{ - CString res = accountSettings.account.password; - return res; -} - -CString get_account_server() -{ - CString res = accountSettings.account.server; - return res; -} - -CString URLMask(CString url, SIPURI* sipuri, pjsua_acc_id acc) -{ - //-- replace server - CString str; - if (pjsua_acc_is_valid(acc) && !get_account_server().IsEmpty()) { - str = get_account_server(); - } else { - str = _T("localhost"); - } - url.Replace(_T("{server}"),str); - //-- - CTime t = CTime::GetCurrentTime(); - time_t time = t.GetTime(); - str.Format(_T("%d"), time); - url.Replace(_T("{time}"), str); - //-- - if (sipuri) { - //-- replace callerid - CString num = !sipuri->name.IsEmpty()?sipuri->name:sipuri->user; - url.Replace(_T("{callerid}"),CString(urlencode(Utf8EncodeUcs2(num)))); - //-- replace - url.Replace(_T("{user}"),CString(urlencode(Utf8EncodeUcs2(sipuri->user)))); - url.Replace(_T("{domain}"),CString(urlencode(Utf8EncodeUcs2(sipuri->domain)))); - url.Replace(_T("{name}"),CString(urlencode(Utf8EncodeUcs2(sipuri->name)))); - //-- - } - return url; -} - -HICON LoadImageIcon(int i) -{ - return (HICON)LoadImage( - AfxGetInstanceHandle(), - MAKEINTRESOURCE(i), - IMAGE_ICON, 0, 0, LR_SHARED); -} - -void msip_call_send_dtmf_info(pjsua_call_id current_call, pj_str_t digits) -{ - if (pjsua_var.state!=PJSUA_STATE_RUNNING) { - return; - } - if (current_call == -1) { - PJ_LOG(3,(THIS_FILE, "No current call")); - } else { - const pj_str_t SIP_INFO = pj_str("INFO"); - int call = current_call; - pj_status_t status; - for (int i=0; istate==PJSIP_INV_STATE_CALLING - || (p_call_info->role==PJSIP_ROLE_UAS && p_call_info->state==PJSIP_INV_STATE_CONNECTING) - ) { - pjsua_call *call = &pjsua_var.calls[call_id]; - pjsip_tx_data *tdata = NULL; - // Generate an INVITE END message - if (pjsip_inv_end_session(call->inv, 487, NULL, &tdata) != PJ_SUCCESS || !tdata) { - pjsip_inv_terminate(call->inv,487,PJ_TRUE); - } else { - // Send that END request - if (pjsip_endpt_send_request(pjsua_get_pjsip_endpt(), tdata, -1, NULL, NULL) != PJ_SUCCESS) { - pjsip_inv_terminate(call->inv,487,PJ_TRUE); - } - } - return; - } - } - pjsua_call_hangup(call_id, 0, NULL, NULL); -} - -void msip_call_end(pjsua_call_id call_id) -{ - if (pjsua_var.state!=PJSUA_STATE_RUNNING) { - return; - } - call_user_data *user_data = (call_user_data *)pjsua_call_get_user_data(call_id); - if (user_data && user_data->inConference) { - pjsua_call_info call_info; - if (pjsua_call_get_info(call_id, &call_info) == PJ_SUCCESS && call_info.state == PJSIP_INV_STATE_CONFIRMED) { - pjsua_call_id call_ids[PJSUA_MAX_CALLS]; - unsigned count = PJSUA_MAX_CALLS; - if (pjsua_enum_calls ( call_ids, &count)==PJ_SUCCESS) { - for (unsigned i = 0; i < count; ++i) { - if (call_id == call_ids[i]) { - continue; - } - call_user_data *curr_user_data = (call_user_data *) pjsua_call_get_user_data(call_ids[i]); - if (curr_user_data && curr_user_data->inConference) { - msip_call_hangup_fast(call_ids[i]); - } - } - } - } - } - msip_call_hangup_fast(call_id); -} - -void msip_conference_join(pjsua_call_info *call_info) -{ - if (pjsua_var.state!=PJSUA_STATE_RUNNING) { - return; - } - call_user_data *user_data = (call_user_data *)pjsua_call_get_user_data(call_info->id); - if (user_data && user_data->inConference) { - pjsua_call_id call_ids[PJSUA_MAX_CALLS]; - unsigned count = PJSUA_MAX_CALLS; - if (pjsua_enum_calls ( call_ids, &count)==PJ_SUCCESS) { - for (unsigned i = 0; i < count; ++i) { - if (call_info->id == call_ids[i]) { - continue; - } - if (!pjsua_call_has_media(call_ids[i])) { - continue; - } - call_user_data *curr_user_data = (call_user_data *) pjsua_call_get_user_data(call_ids[i]); - if (curr_user_data && curr_user_data->inConference) { - if (call_info->conf_slot!=PJSUA_INVALID_ID) { - pjsua_conf_port_id conf_port_id = pjsua_call_get_conf_port(call_ids[i]); - if (conf_port_id!=PJSUA_INVALID_ID) { - pjsua_conf_connect(call_info->conf_slot, conf_port_id); - pjsua_conf_connect(conf_port_id, call_info->conf_slot); - } - } - CWnd *hWnd = AfxGetApp()->m_pMainWnd; - if (hWnd) { - hWnd->PostMessage(UM_TAB_ICON_UPDATE, (WPARAM) call_ids[i], NULL); - } - } - } - } - } -} - -void msip_conference_leave(pjsua_call_info *call_info, bool hold) -{ - if (pjsua_var.state!=PJSUA_STATE_RUNNING) { - return; - } - call_user_data *user_data = (call_user_data *)pjsua_call_get_user_data(call_info->id); - if (user_data && user_data->inConference) { - pjsua_call_id call_ids[PJSUA_MAX_CALLS]; - unsigned count = PJSUA_MAX_CALLS; - if (pjsua_enum_calls ( call_ids, &count)==PJ_SUCCESS) { - int qty = 0; - call_user_data *last_conf_user_data = NULL; - for (unsigned i = 0; i < count; ++i) { - if (call_info->id == call_ids[i]) { - continue; - } - call_user_data *curr_user_data = (call_user_data *) pjsua_call_get_user_data(call_ids[i]); - if (curr_user_data && curr_user_data->inConference) { - last_conf_user_data = curr_user_data; - qty++; - if (call_info->conf_slot!=PJSUA_INVALID_ID) { - pjsua_conf_port_id conf_port_id = pjsua_call_get_conf_port(call_ids[i]); - if (conf_port_id!=PJSUA_INVALID_ID) { - pjsua_conf_disconnect(call_info->conf_slot, conf_port_id); - pjsua_conf_disconnect(conf_port_id, call_info->conf_slot); - } - } - if (!hold) { - CWnd *hWnd = AfxGetApp()->m_pMainWnd; - if (hWnd) { - hWnd->PostMessage(UM_TAB_ICON_UPDATE, (WPARAM) call_ids[i], NULL); - } - } - } - } - if (qty == 1) { - if (!hold) { - last_conf_user_data->inConference = false; - CWnd *hWnd = AfxGetApp()->m_pMainWnd; - if (hWnd) { - hWnd->PostMessage(UM_TAB_ICON_UPDATE, (WPARAM) call_info->id, NULL); - } - } - } - } - if (!hold) { - user_data->inConference = false; - } - } -} - -void msip_call_hold(pjsua_call_info *call_info) -{ - if (pjsua_var.state!=PJSUA_STATE_RUNNING) { - return; - } - call_user_data *user_data = (call_user_data *) pjsua_call_get_user_data(call_info->id); - if (user_data && user_data->inConference) { - pjsua_call_id call_ids[PJSUA_MAX_CALLS]; - unsigned count = PJSUA_MAX_CALLS; - if (pjsua_enum_calls ( call_ids, &count)==PJ_SUCCESS) { - for (unsigned i = 0; i < count; ++i) { - if (call_ids[i] != call_info->id ) { - call_user_data *user_data_curr = (call_user_data *) pjsua_call_get_user_data(call_ids[i]); - if (user_data_curr && user_data_curr->inConference) { - pjsua_call_info call_info_curr; - pjsua_call_get_info(call_ids[i], &call_info_curr); - if (call_info_curr.state == PJSIP_INV_STATE_CONFIRMED) { - if (call_info_curr.media_status != PJSUA_CALL_MEDIA_LOCAL_HOLD && call_info_curr.media_status != PJSUA_CALL_MEDIA_NONE) { - pjsua_call_set_hold(call_info_curr.id, NULL); - } - } - } - } - } - } - } - if (call_info->state == PJSIP_INV_STATE_CONFIRMED) { - if (call_info->media_status != PJSUA_CALL_MEDIA_LOCAL_HOLD && call_info->media_status != PJSUA_CALL_MEDIA_NONE) { - pjsua_call_set_hold(call_info->id, NULL); - } - } -} - -void msip_call_unhold(pjsua_call_info *call_info) -{ - if (pjsua_var.state!=PJSUA_STATE_RUNNING) { - return; - } - call_user_data *user_data = NULL; - if (call_info) { - user_data = (call_user_data *) pjsua_call_get_user_data(call_info->id); - } - bool inConference = user_data && user_data->inConference; - pjsua_call_id call_ids[PJSUA_MAX_CALLS]; - unsigned count = PJSUA_MAX_CALLS; - if (pjsua_enum_calls ( call_ids, &count)==PJ_SUCCESS) { - for (unsigned i = 0; i < count; ++i) { - if (!call_info || call_ids[i] != call_info->id ) { - pjsua_call_info call_info_curr; - pjsua_call_get_info(call_ids[i], &call_info_curr); - if (call_info_curr.state == PJSIP_INV_STATE_CONFIRMED) { - call_user_data *user_data_curr = (call_user_data *) pjsua_call_get_user_data(call_ids[i]); - bool inConferenceCurr = user_data_curr && user_data_curr->inConference; - if (inConference && inConferenceCurr) { - // unhold - if (call_info_curr.media_status == PJSUA_CALL_MEDIA_LOCAL_HOLD || call_info_curr.media_status == PJSUA_CALL_MEDIA_NONE) { - pjsua_call_reinvite(call_ids[i], PJSUA_CALL_UNHOLD, NULL); - } - } else { - // hold - if (call_info_curr.media_status != PJSUA_CALL_MEDIA_LOCAL_HOLD && call_info_curr.media_status != PJSUA_CALL_MEDIA_NONE) { - pjsua_call_set_hold(call_ids[i], NULL); - } - } - } - } - } - } - if (call_info && call_info->state == PJSIP_INV_STATE_CONFIRMED) { - if (call_info->media_status == PJSUA_CALL_MEDIA_LOCAL_HOLD || call_info->media_status == PJSUA_CALL_MEDIA_NONE) { - pjsua_call_reinvite(call_info->id, PJSUA_CALL_UNHOLD, NULL); - } - } -} - -void msip_call_answer(pjsua_call_id call_id) -{ - if (pjsua_var.state!=PJSUA_STATE_RUNNING) { - return; - } - pjsua_call_id call_ids[PJSUA_MAX_CALLS]; - unsigned calls_count = PJSUA_MAX_CALLS; - unsigned calls_count_cmp = 0; - if (pjsua_enum_calls ( call_ids, &calls_count)==PJ_SUCCESS) { - for (unsigned i = 0; i < calls_count; ++i) { - pjsua_call_info call_info; - if (pjsua_call_get_info(call_ids[i], &call_info) == PJ_SUCCESS) { - if (call_info.role==PJSIP_ROLE_UAS && (call_info.state==PJSIP_INV_STATE_INCOMING || call_info.state==PJSIP_INV_STATE_EARLY)) { - CWnd *hWnd = AfxGetApp()->m_pMainWnd; - if (hWnd) { - hWnd->PostMessage(UM_CALL_ANSWER, (WPARAM) call_ids[i], NULL); - } - break; - } - } - } - } -} - -CStringA msip_md5sum(CString *str) -{ - CStringA md5sum; - CStringA utf8 = Utf8EncodeUcs2(str->GetBuffer()); - DWORD cbContent= utf8.GetLength(); - BYTE* pbContent= (BYTE*)utf8.GetBuffer(cbContent); - pj_md5_context ctx; - pj_uint8_t digest[16]; - pj_md5_init(&ctx); - pj_md5_update(&ctx, (pj_uint8_t*)pbContent,cbContent); - pj_md5_final(&ctx, digest); - char *p = md5sum.GetBuffer(32); - for (int i = 0; i<16; ++i) { - pj_val_to_hex_digit(digest[i], p); - p += 2; - } - md5sum.ReleaseBuffer(); - return md5sum; -} - -CString msip_url_mask(CString url) -{ - if (accountSettings.accountId) { - url.Replace(_T("{server}"),get_account_server()); - url.Replace(_T("{username}"),CString(urlencode(Utf8EncodeUcs2(accountSettings.account.username)))); - url.Replace(_T("{password}"),CString(urlencode(Utf8EncodeUcs2(accountSettings.account.password)))); - url.Replace(_T("{md5_password}"),CString(msip_md5sum(&accountSettings.account.password))); - } else { - url.Replace(_T("{server}"),_T("localhost")); - url.Replace(_T("{username}"),_T("")); - url.Replace(_T("{password}"),_T("")); - url.Replace(_T("{md5_password}"),_T("")); - } - return url; -} - -//void msip_audio_output_set_volume(int val, bool mute) -//{ -// if (mute) { -// val = 0; -// } else { -// pj_status_t status = -// pjsua_snd_set_setting( -// PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING, -// &val, PJ_TRUE); -// if (status == PJ_SUCCESS) { -// val = 100; -// } -// } -// pjsua_conf_adjust_tx_level(0, (float)val/100); -//} - -void msip_audio_conf_set_volume(int val, bool mute) -{ - if (pjsua_var.state!=PJSUA_STATE_RUNNING) { - return; - } - if (mute) { - val = 0; - } - pjsua_call_id call_ids[PJSUA_MAX_CALLS]; - unsigned count = PJSUA_MAX_CALLS; - if (pjsua_enum_calls ( call_ids, &count)==PJ_SUCCESS) { - for (unsigned i = 0; i < count; ++i) { - pjsua_conf_port_id conf_port_id = pjsua_call_get_conf_port(call_ids[i]); - if (conf_port_id!=PJSUA_INVALID_ID) { - pjsua_conf_adjust_rx_level(conf_port_id, (float)val/100); - } - } - } -} - -void msip_audio_input_set_volume(int val, bool mute) -{ - if (pjsua_var.state!=PJSUA_STATE_RUNNING) { - return; - } - if (mute) { - val = 0; - } else { - pj_status_t status = -1; - if (!accountSettings.swLevelAdjustment) { - int valHW; - if (accountSettings.micAmplification) { - valHW = val>=50 ? 100 : val*2; - } else { - valHW = val; - } - status = - pjsua_snd_set_setting( - PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING, - &valHW, PJ_TRUE); - } - if (status==PJ_SUCCESS) { - if (accountSettings.micAmplification && val>50) { - val = 100 + pow((float)val-50,1.68f); - } else { - val = 100; - } - } else { - if (accountSettings.micAmplification) { - if (val>50) { - val = 50+pow((float)val-50,1.7f); - } - } - } - } - pjsua_conf_adjust_rx_level(0, (float)val/100); -} diff --git a/microsip/global.h b/microsip/global.h deleted file mode 100644 index 90d098f4..00000000 --- a/microsip/global.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#pragma once - -#include "define.h" -#include "stdafx.h" -#include -#include - -enum EUserWndMessages -{ - UM_FIRST_USER_MSG = (WM_USER + 0x100 + 1), - - UM_UPDATEWINDOWTEXT, - UM_NOTIFYICON, - - UM_UPDATE_SETTINGS, - - UM_CREATE_RINGING, - UM_CALL_ANSWER, - UM_CALL_HANGUP, - UM_TAB_ICON_UPDATE, - UM_ON_ACCOUNT, - UM_ON_REG_STATE2, - UM_ON_CALL_STATE, - UM_ON_CALL_TRANSFER_STATUS, - UM_ON_MWI_INFO, - UM_ON_CALL_MEDIA_STATE, - UM_ON_PAGER, - UM_ON_PAGER_STATUS, - UM_ON_BUDDY_STATE, - UM_ON_PLAYER_PLAY, - UM_ON_PLAYER_STOP, - UM_SET_PANE_TEXT, - UM_REFRESH_LEVELS, - UM_USERS_DIRECTORY, - UM_ON_BALANCE_PLAIN, - UM_ON_BALANCE_OPTIONS, - - IDT_TIMER_IDLE, - IDT_TIMER_TONE, - IDT_TIMER_BALANCE, - IDT_TIMER_INIT_RINGIN, - IDT_TIMER_CALL, - IDT_TIMER_CONTACTS_BLINK, - IDT_TIMER_DIRECTORY, - IDT_TIMER_SAVE, - IDT_TIMER_SWITCH_DEVICES, - IDT_TIMER_HEADSET, - IDT_TIMER_VU_METER, - IDT_TIMER_AUTOANSWER, - - UM_CLOSETAB, - UM_DBLCLICKTAB, - UM_QUERYTAB, - -}; - -enum {MSIP_MESSAGE_TYPE_LOCAL, MSIP_MESSAGE_TYPE_REMOTE, MSIP_MESSAGE_TYPE_SYSTEM}; -enum {MSIP_TRANSPORT_AUTO, MSIP_TRANSPORT_TCP, MSIP_TRANSPORT_TLS}; -enum {MSIP_CALL_OUT, MSIP_CALL_IN, MSIP_CALL_MISS}; -enum { MSIP_SOUND_CUSTOM, MSIP_SOUND_MESSAGE_IN, MSIP_SOUND_MESSAGE_OUT, MSIP_SOUND_HANGUP, MSIP_SOUND_RINGIN, MSIP_SOUND_RINGIN2, MSIP_SOUND_RINGOUT }; -enum msip_srtp_type { MSIP_SRTP_DISABLED, MSIP_SRTP }; -enum msip_shortcut_type { MSIP_SHORTCUT_CALL, MSIP_SHORTCUT_VIDEOCALL, MSIP_SHORTCUT_MESSAGE, MSIP_SHORTCUT_DTMF, MSIP_SHORTCUT_TRANSFER }; - -enum { - MSIP_CONTACT_ICON_UNKNOWN, - MSIP_CONTACT_ICON_OFFLINE, - MSIP_CONTACT_ICON_AWAY, - MSIP_CONTACT_ICON_ONLINE, - MSIP_CONTACT_ICON_ON_THE_PHONE, - MSIP_CONTACT_ICON_BLANK, - MSIP_CONTACT_ICON_BUSY, - MSIP_CONTACT_ICON_DEFAULT -}; - -struct Shortcut { - CString label; - CString number; - msip_shortcut_type type; -}; - -struct SIPURI { - CString name; - CString user; - CString domain; - CString parameters; -}; - -struct Contact { - CString number; - CString name; - BOOL presence; - BOOL directory; - time_t presenceTime; - BOOL ringing; - CString presenceNote; - int image; - BOOL candidate; - Contact():presenceTime(0),ringing(FALSE),image(0),candidate(FALSE){} -}; - -struct MessagesContact { - CString name; - CString number; - CString numberParameters; - CString messages; - CString message; - bool hasNewMessages; - CString lastSystemMessage; - CTime lastSystemMessageTime; - pjsua_call_id callId; - int mediaStatus; - MessagesContact():mediaStatus(PJSUA_CALL_MEDIA_ERROR) - ,hasNewMessages(false) - {} -}; - -struct Call { - int key; - CString id; - CString name; - CString number; - int type; - int time; - int duration; - CString info; -}; - -struct call_tonegen_data -{ - pj_pool_t *pool; - pjmedia_port *tonegen; - pjsua_conf_port_id toneslot; -}; - -struct call_user_data -{ - pjsua_call_id call_id; - call_tonegen_data *tonegen_data; - pj_timer_entry auto_hangup_timer; - msip_srtp_type srtp; - CString userAgent; - CString diversion; - CString commands; - bool inConference; - call_user_data(pjsua_call_id call_id): tonegen_data(NULL) - ,inConference(false) - ,srtp(MSIP_SRTP_DISABLED) - { - this->call_id = call_id; - pj_bzero(&auto_hangup_timer, sizeof(auto_hangup_timer)); - auto_hangup_timer.id = PJSUA_INVALID_ID; - } -}; - -extern struct call_tonegen_data *tone_gen; -extern int transport; -extern pjsua_acc_id account; -extern pjsua_acc_id account_local; -extern CString lastTransferNumber; -extern pjsua_conf_port_id msip_conf_port_id; -extern pjsua_call_id msip_conf_port_call_id; - -extern int msip_audio_input; -extern int msip_audio_output; -extern int msip_audio_ring; - -CString GetErrorMessage(pj_status_t status); -BOOL ShowErrorMessage(pj_status_t status); -BOOL IsIP(CString host); -CString RemovePort(CString domain); -void ParseSIPURI(CString in, SIPURI* out); -CString PjToStr(const pj_str_t* str, BOOL utf = FALSE); -pj_str_t StrToPjStr(CString str); -char* StrToPj(CString str); -CString Utf8DecodeUni(CStringA str); -CStringA UnicodeToAnsi(CString str); -CString AnsiToUnicode(CStringA str); -CString XMLEntityDecode(CString str); -CString XMLEntityEncode(CString str); -void OpenURL(CString url); -CString GetDuration(int sec, bool zero = false); -void AddTransportSuffix(CString &str); -CString GetSIPURI(CString str, bool isSimple = false, bool isLocal = false, CString domain = _T("")); -bool SelectSIPAccount(CString number, pjsua_acc_id &acc_id, pj_str_t &pj_uri); -bool IsPSTNNnmber(CString number); -CString FormatNumber(CString number, CString *commands = NULL); -bool IniSectionExists(CString section, CString iniFile); -CString Bin2String(CByteArray *ca); -void String2Bin(CString str, CByteArray *res); -void CommandLineToShell(CString cmd, CString &command, CString ¶ms); - -namespace MSIP { - void GetScreenRect(CRect *rect); -} - -CString get_account_username(); -CString get_account_password(); -CString get_account_server(); - -struct call_tonegen_data *call_init_tonegen(pjsua_call_id call_id); -BOOL call_play_digit(pjsua_call_id call_id, const char *digits, int duration = 160); -void call_deinit_tonegen(pjsua_call_id call_id); -void destroyDTMFPlayerTimerHandler( - HWND hwnd, - UINT uMsg, - UINT_PTR idEvent, - DWORD dwTime); -void DTMFQueueTimerHandler( - HWND hwnd, - UINT uMsg, - UINT_PTR idEvent, - DWORD dwTime); - -void msip_call_hangup_fast(pjsua_call_id call_id,pjsua_call_info *p_call_info = NULL); - -unsigned call_get_count_noincoming(); -void call_hangup_all_noincoming(bool onHold=false); - -void OpenHelp(CString code); - - -typedef struct { - HWND hWnd; - UINT message; - CString url; - DWORD statusCode; - CString headers; - CStringA body; -} URLGetAsyncData; -void URLGetAsync(CString url, HWND hWnd=0, UINT message=0); -URLGetAsyncData URLGetSync(CString url); - -CStringA urlencode(CStringA str); -CStringA char2hex(char dec); - -CString URLMask(CString url, SIPURI* sipuri, pjsua_acc_id acc); -HICON LoadImageIcon(int i); - -void msip_set_sound_device(int outDev, bool forse = 0); -void msip_call_dial_dtmf(pjsua_call_id call_id, CString digits); -void msip_call_send_dtmf_info(pjsua_call_id current_call, pj_str_t digits); - -void msip_call_end(pjsua_call_id call_id); -void msip_conference_join(pjsua_call_info *call_info); -void msip_conference_leave(pjsua_call_info *call_info, bool hold = false); -void msip_call_hold(pjsua_call_info *call_info); -void msip_call_unhold(pjsua_call_info *call_info = NULL); -void msip_call_answer(pjsua_call_id call_id = PJSUA_INVALID_ID); -void msip_call_process_dtmf_queue(call_user_data *user_data); -CStringA msip_md5sum(CString *str); -CString msip_url_mask(CString url); -void msip_audio_output_set_volume(int val, bool mute = false); -void msip_audio_input_set_volume(int val, bool mute = false); -void msip_audio_conf_set_volume(int val, bool mute); diff --git a/microsip/jumplist.cpp b/microsip/jumplist.cpp deleted file mode 100644 index 1dbb621c..00000000 --- a/microsip/jumplist.cpp +++ /dev/null @@ -1,551 +0,0 @@ -#include "jumplist.h" -#include "langpack.h" -#include "resource.h" -#include "define.h" - -typedef HRESULT (WINAPI *PSetCurrentProcessExplicitAppUserModelID)(_In_ PCWSTR AppID); - -JumpList::JumpList(const std::wstring AppID) : -pcdl(0) -{ - HMODULE hinstDll = LoadLibrary(TEXT("shell32.dll")); - if (hinstDll) { - PSetCurrentProcessExplicitAppUserModelID pSetCurrentProcessExplicitAppUserModelID = - (PSetCurrentProcessExplicitAppUserModelID)GetProcAddress(hinstDll, "SetCurrentProcessExplicitAppUserModelID"); - if (pSetCurrentProcessExplicitAppUserModelID) { - pSetCurrentProcessExplicitAppUserModelID(AppID.c_str()); - HRESULT hr = CoCreateInstance(CLSID_DestinationList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pcdl)); - if (SUCCEEDED(hr)) { - pcdl->SetAppID(AppID.c_str()); - } - } - FreeLibrary(hinstDll); - } -} - -JumpList::~JumpList() -{ - if (pcdl) - { - pcdl->Release(); - } -} - -bool JumpList::DeleteJumpList() -{ - return (pcdl && pcdl->DeleteList(NULL) == S_OK); -} - - -// Creates a CLSID_ShellLink to insert into the Tasks section of the Jump List. This type of Jump -// List item allows the specification of an explicit command line to execute the task. -HRESULT JumpList::_CreateShellLink(PCWSTR pszArguments, PCWSTR pszTitle, IShellLinkW **ppsl, int iconindex) -{ - IShellLinkW *psl; - HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&psl)); - if (SUCCEEDED(hr)) - { - std::wstring fname; - fname.resize(MAX_PATH); - GetModuleFileNameW(0, &fname[0], MAX_PATH); - - fname.resize(wcslen(fname.c_str())); - std::wstring shortfname; - shortfname.resize(MAX_PATH); - GetShortPathNameW(fname.c_str(), &shortfname[0], MAX_PATH); - shortfname.resize(wcslen(shortfname.c_str())); - if (iconindex>=0) { - psl->SetIconLocation(shortfname.c_str(), -iconindex); - } - hr = psl->SetPath(shortfname.c_str()); - if (SUCCEEDED(hr)) - { - hr = psl->SetArguments(pszArguments); - if (SUCCEEDED(hr)) - { - // The title property is required on Jump List items provided as an IShellLink - // instance. This value is used as the display name in the Jump List. - IPropertyStore *pps; - hr = psl->QueryInterface(IID_PPV_ARGS(&pps)); - if (SUCCEEDED(hr)) - { - PROPVARIANT propvar; - hr = InitPropVariantFromString(pszTitle, &propvar); - if (SUCCEEDED(hr)) - { - hr = pps->SetValue(PKEY_Title, propvar); - if (SUCCEEDED(hr)) - { - hr = pps->Commit(); - if (SUCCEEDED(hr)) - { - hr = psl->QueryInterface(IID_PPV_ARGS(ppsl)); - } - } - PropVariantClear(&propvar); - } - pps->Release(); - } - } - } - else - { - hr = HRESULT_FROM_WIN32(GetLastError()); - } - psl->Release(); - } - return hr; -} - -void JumpList::AddTasks() -{ - if (pcdl) - { - UINT cMinSlots; - IObjectArray *poaRemoved; - HRESULT hr = pcdl->BeginList(&cMinSlots, IID_PPV_ARGS(&poaRemoved)); - - if (SUCCEEDED(hr)) - { - - IObjectCollection *poc; - hr = CoCreateInstance(CLSID_EnumerableObjectCollection, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&poc)); - if (SUCCEEDED(hr)) - { - IShellLinkW * psl; -#ifdef _UNICODE - hr = _CreateShellLink(L"/exit",Translate(TEXT("Exit")), &psl, IDI_EXIT); -#else - WCHAR pWideString[50]; - MultiByteToWideChar(CP_ACP,0,Translate(TEXT("Exit")),-1,pWideString,50); - hr = _CreateShellLink(L"/exit", pWideString, &psl, IDI_EXIT); -#endif - if (SUCCEEDED(hr)) - { - hr = poc->AddObject(psl); - psl->Release(); - } - //-- - if (SUCCEEDED(hr)) - { - IObjectArray * poa; - hr = poc->QueryInterface(IID_PPV_ARGS(&poa)); - if (SUCCEEDED(hr)) - { - // Add the tasks to the Jump List. Tasks always appear in the canonical "Tasks" - // category that is displayed at the bottom of the Jump List, after all other - // categories. - hr = pcdl->AddUserTasks(poa); - poa->Release(); - } - } - poc->Release(); - } - hr = pcdl->CommitList(); - poaRemoved->Release(); - } - } -} - -/* -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "jumplist.h" -#include "api.h" - -JumpList::JumpList(const std::wstring AppID) : -m_AppID(AppID), -max_items_jumplist(100) -{ - m_hr = CoCreateInstance(CLSID_DestinationList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pcdl)); - pcdl->SetAppID(m_AppID.c_str()); -} - -JumpList::~JumpList() -{ - pcdl->Release(); -} - -// Creates a CLSID_ShellLink to insert into the Tasks section of the Jump List. This type of Jump -// List item allows the specification of an explicit command line to execute the task. -HRESULT JumpList::_CreateShellLink(PCWSTR pszArguments, PCWSTR pszTitle, IShellLink **ppsl, int iconindex, bool WA) -{ - IShellLink *psl; - HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&psl)); - if (SUCCEEDED(hr)) - { - psl->SetIconLocation(path.c_str(), iconindex); - if (WA) - { - std::wstring fname; - fname.resize(MAX_PATH); - GetModuleFileName(0, &fname[0], MAX_PATH); - fname.resize(wcslen(fname.c_str())); - std::wstring shortfname; - shortfname.resize(MAX_PATH); - GetShortPathName(fname.c_str(), &shortfname[0], MAX_PATH); - shortfname.resize(wcslen(shortfname.c_str())); - hr = psl->SetPath(shortfname.c_str()); - } - else - hr = psl->SetPath(L"rundll32.exe"); - - if (SUCCEEDED(hr)) - { - hr = psl->SetArguments(pszArguments); - if (SUCCEEDED(hr)) - { - // The title property is required on Jump List items provided as an IShellLink - // instance. This value is used as the display name in the Jump List. - IPropertyStore *pps; - hr = psl->QueryInterface(IID_PPV_ARGS(&pps)); - if (SUCCEEDED(hr)) - { - PROPVARIANT propvar; - hr = InitPropVariantFromString(pszTitle, &propvar); - if (SUCCEEDED(hr)) - { - hr = pps->SetValue(PKEY_Title, propvar); - if (SUCCEEDED(hr)) - { - hr = pps->Commit(); - if (SUCCEEDED(hr)) - { - hr = psl->QueryInterface(IID_PPV_ARGS(ppsl)); - } - } - PropVariantClear(&propvar); - } - pps->Release(); - } - } - } - else - { - hr = HRESULT_FROM_WIN32(GetLastError()); - } - psl->Release(); - } - return hr; -} - -bool JumpList::CreateJumpList(std::wstring pluginpath, std::wstring pref, std::wstring fromstart, - std::wstring resume, std::wstring openfile, std::wstring bookmarks, std::wstring pltext, bool recent, - bool frequent, bool tasks, bool addbm, bool playlist, const std::wstring bms) -{ - path = pluginpath; - s1 = pref; - s2 = fromstart; - s3 = resume; - s4 = openfile; - s5 = bookmarks; - s6 = pltext; - - UINT cMinSlots; - IObjectArray *poaRemoved; - HRESULT hr = pcdl->BeginList(&cMinSlots, IID_PPV_ARGS(&poaRemoved)); - - CoCreateInstance(CLSID_EnumerableObjectCollection, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&poc)); - - if (!bms.empty() && addbm && hr == S_OK) - { - std::wstringstream ss(bms); - std::wstring line1, line2; - bool b = false; - while (getline(ss, line1)) - { - if (b) - { - IShellLink * psl; - hr = _CreateShellLink(line2.c_str(), line1.c_str(), &psl, 4, true); - - if (!_IsItemInArray(line2, poaRemoved)) - { - psl->SetDescription(line2.c_str()); - poc->AddObject(psl); - } - psl->Release(); - b = false; - } - else - { - line2.resize(MAX_PATH); - if (GetShortPathName(line1.c_str(), &line2[0], MAX_PATH) == 0) - line2 = line1; - else - line2.resize(wcslen(line2.c_str())); - b = true; - } - } - } - - if (SUCCEEDED(hr)) - { - if (recent) - pcdl->AppendKnownCategory(KDC_RECENT); - - if (frequent) - pcdl->AppendKnownCategory(KDC_FREQUENT); - - if (addbm && !bms.empty()) - _AddCategoryToList(); - - if (playlist) - hr = _AddCategoryToList2(); - - if (tasks) - _AddTasksToList(); - - if (SUCCEEDED(hr)) - { - // Commit the list-building transaction. - hr = pcdl->CommitList(); - } - } - poaRemoved->Release(); - poc->Release(); - - return (hr == S_OK); -} - -bool JumpList::DeleteJumpList() -{ - return (pcdl->DeleteList(NULL) == S_OK); -} - -HRESULT JumpList::_AddTasksToList() -{ - IObjectCollection *poc; - HRESULT hr = CoCreateInstance(CLSID_EnumerableObjectCollection, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&poc)); - if (SUCCEEDED(hr)) - { - std::wstring args; - args = path + L",_pref@0";; - - IShellLink * psl; - hr = _CreateShellLink(args.c_str(), s1.c_str(), &psl, 0, false); - if (SUCCEEDED(hr)) - { - hr = poc->AddObject(psl); - psl->Release(); - } - - args = path + L",_openfile@0"; - - if (SUCCEEDED(hr)) - { - hr = _CreateShellLink(args.c_str(), s4.c_str(), &psl, 1, false); - if (SUCCEEDED(hr)) - { - hr = poc->AddObject(psl); - psl->Release(); - } - } - - args = path + L",_resume@0"; - - if (SUCCEEDED(hr)) - { - hr = _CreateShellLink(args.c_str(), s3.c_str(), &psl, 3, false); - if (SUCCEEDED(hr)) - { - hr = poc->AddObject(psl); - psl->Release(); - } - } - - args = path + L",_fromstart@0"; - - if (SUCCEEDED(hr)) - { - hr = _CreateShellLink(args.c_str(), s2.c_str(), &psl, 2, false); - if (SUCCEEDED(hr)) - { - hr = poc->AddObject(psl); - psl->Release(); - } - } - - if (SUCCEEDED(hr)) - { - IObjectArray * poa; - hr = poc->QueryInterface(IID_PPV_ARGS(&poa)); - if (SUCCEEDED(hr)) - { - // Add the tasks to the Jump List. Tasks always appear in the canonical "Tasks" - // category that is displayed at the bottom of the Jump List, after all other - // categories. - hr = pcdl->AddUserTasks(poa); - poa->Release(); - } - } - poc->Release(); - } - return hr; -} - -// Determines if the provided IShellItem is listed in the array of items that the user has removed -bool JumpList::_IsItemInArray(std::wstring path, IObjectArray *poaRemoved) -{ - bool fRet = false; - UINT cItems; - if (SUCCEEDED(poaRemoved->GetCount(&cItems))) - { - IShellLink *psiCompare; - for (UINT i = 0; !fRet && i < cItems; i++) - { - if (SUCCEEDED(poaRemoved->GetAt(i, IID_PPV_ARGS(&psiCompare)))) - { - std::wstring removedpath; - removedpath.resize(MAX_PATH); - fRet = (psiCompare->GetArguments(&removedpath[0], MAX_PATH)== S_OK); - removedpath.resize(wcslen(removedpath.c_str())); - fRet = !path.compare(removedpath); - - psiCompare->Release(); - } - } - } - return fRet; -} - -// Adds a custom category to the Jump List. Each item that should be in the category is added to -// an ordered collection, and then the category is appended to the Jump List as a whole. -HRESULT JumpList::_AddCategoryToList() -{ - IObjectArray *poa; - HRESULT hr = poc->QueryInterface(IID_PPV_ARGS(&poa)); - if (SUCCEEDED(hr)) - { - // Add the category to the Jump List. If there were more categories, they would appear - // from top to bottom in the order they were appended. - hr = pcdl->AppendCategory(s5.c_str(), poa); - poa->Release(); - } - - return hr; -} - -// Adds a custom category to the Jump List. Each item that should be in the category is added to -// an ordered collection, and then the category is appended to the Jump List as a whole. -HRESULT JumpList::_AddCategoryToList2() -{ - IObjectCollection *poc; - HRESULT hr = CoCreateInstance(CLSID_EnumerableObjectCollection, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&poc)); - - // enumerate through playlists (need to see if can use api_playlists.h via sdk) - if(AGAVE_API_PLAYLISTS && AGAVE_API_PLAYLISTS->GetCount()){ - for(size_t i = 0; i < AGAVE_API_PLAYLISTS->GetCount(); i++){ - size_t numItems; - IShellLink * psl; - std::wstring title; - - std::wstring tmp; - tmp.resize(MAX_PATH); - - title = AGAVE_API_PLAYLISTS->GetName(i); - - AGAVE_API_PLAYLISTS->GetInfo(i, api_playlists_itemCount, &numItems, sizeof(numItems)); - StringCchPrintf((LPWSTR)tmp.c_str(),tmp.size(),L" [%d]",numItems); - title += tmp; - - hr = _CreateShellLink(AGAVE_API_PLAYLISTS->GetFilename(i), title.c_str(), &psl, 5, true); - if (SUCCEEDED(hr)) - { - psl->SetDescription(AGAVE_API_PLAYLISTS->GetFilename(i)); - hr = poc->AddObject(psl); - psl->Release(); - } - } - } - - IObjectArray *poa; - hr = poc->QueryInterface(IID_PPV_ARGS(&poa)); - if (SUCCEEDED(hr)) - { - // Add the category to the Jump List. If there were more categories, they would appear - // from top to bottom in the order they were appended. - hr = pcdl->AppendCategory(s6.c_str(), poa); - poa->Release(); - } - - return S_OK; -} - -bool JumpList::CleanJumpList() -{ - IApplicationDocumentLists *padl; - HRESULT hr = CoCreateInstance(CLSID_ApplicationDocumentLists, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&padl)); - - if (SUCCEEDED(hr)) - { - CleanJL(padl, ADLT_RECENT); - CleanJL(padl, ADLT_FREQUENT); - } - - padl->Release(); - - return true; -} - -bool JumpList::CleanJL(IApplicationDocumentLists *padl, APPDOCLISTTYPE type) -{ - IObjectArray *poa; - padl->SetAppID(m_AppID.c_str()); - HRESULT hr = padl->GetList(type, 0, IID_PPV_ARGS(&poa)); - - if (SUCCEEDED(hr)) - { - UINT *count = new UINT; - hr = poa->GetCount(count); - if (SUCCEEDED(hr) && (*count) > max_items_jumplist) - { - IApplicationDestinations *pad; - HRESULT hr = CoCreateInstance(CLSID_ApplicationDestinations, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pad)); - pad->SetAppID(m_AppID.c_str()); - - if (SUCCEEDED(hr)) - { - for (int i = (*count)-1; i > max_items_jumplist; --i) - { - IShellLink *psi; - hr = poa->GetAt(i, IID_PPV_ARGS(&psi)); - - if (SUCCEEDED(hr)) - { - try - { - pad->RemoveDestination(psi); - } - catch (...) - { - continue; - } - } - } - } - } - } - else - { - wchar_t path[MAX_PATH]; - SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path); - std::wstring filepath(path); - filepath += L"\\Microsoft\\Windows\\Recent\\AutomaticDestinations\\879d567ffa1f5b9f.automaticDestinations-ms"; - if (DeleteFile(filepath.c_str()) == 0) - { - return false; - } - } - - return true; -} -*/ \ No newline at end of file diff --git a/microsip/jumplist.h b/microsip/jumplist.h deleted file mode 100644 index d7324572..00000000 --- a/microsip/jumplist.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef jumplist_h__ -#define jumplist_h__ - -#include -#include -#include -#include - -class JumpList -{ -public: - JumpList(std::wstring AppID); - ~JumpList(); - bool DeleteJumpList(); - void AddTasks(); - -private: - HRESULT _CreateShellLink(PCWSTR pszArguments, PCWSTR pszTitle, IShellLinkW **ppsl, int iconindex = -1); - ICustomDestinationList *pcdl; -}; - -#endif // jumplist_h__ - - -/* -#ifndef jumplist_h__ -#define jumplist_h__ - -#include -#include -#include -#include -#include -#include -#include -#include - -class JumpList -{ -public: - JumpList(std::wstring AppID); - ~JumpList(); - - HRESULT _CreateShellLink(PCWSTR pszArguments, PCWSTR pszTitle, IShellLink **ppsl, int iconindex, bool WA); - bool _IsItemInArray(std::wstring path, IObjectArray *poaRemoved); - HRESULT _AddTasksToList(); - HRESULT _AddCategoryToList(); - HRESULT _AddCategoryToList2(); - bool CreateJumpList(std::wstring pluginpath, std::wstring pref, std::wstring fromstart, - std::wstring resume, std::wstring openfile, std::wstring bookmarks, std::wstring pltext, bool recent, - bool frequent, bool tasks, bool addbm, bool playlist, const std::wstring bms); - bool DeleteJumpList(); - bool CleanJumpList(); - -private: - bool CleanJL(IApplicationDocumentLists *padl, APPDOCLISTTYPE type); - - ICustomDestinationList *pcdl; - IObjectCollection *poc; - HRESULT m_hr; - std::wstring path; - std::wstring m_AppID; - std::wstring s1; - std::wstring s2; - std::wstring s3; - std::wstring s4; - std::wstring s5; - std::wstring s6; - - const int max_items_jumplist; -}; - -#endif // jumplist_h__ -*/ \ No newline at end of file diff --git a/microsip/langpack.cpp b/microsip/langpack.cpp deleted file mode 100644 index 164d9fb6..00000000 --- a/microsip/langpack.cpp +++ /dev/null @@ -1,392 +0,0 @@ -#include "StdAfx.h" -#include "langpack.h" -#include "utf.h" -#include "Strsafe.h" - -LangPackStruct langPack; - -static void TrimString(char *str) -{ - size_t start, len = strlen(str); - while(str[0] && (unsigned char)str[len-1] <= ' ') str[--len] = 0; - for (start = 0; str[start] && (unsigned char)str[start] <= ' '; start++); - memmove(str, str + start, len - start + 1); -} - -static void TrimStringSimple(char *str) -{ - size_t len = strlen(str); - if (str[len-1] == '\n') str[--len] = '\0'; - if (str[len-1] == '\r') str[len-1] = '\0'; -} - -static int IsEmpty(char *str) -{ - int i = 0; - - while (str[i]) - { - if (str[i] != ' ' && str[i] != '\r' && str[i] != '\n') - return 0; - i++; - } - return 1; -} - -void ConvertBackslashes(char *str, UINT fileCp) -{ - char *pstr; - for (pstr = str; *pstr; pstr = CharNextExA(fileCp, pstr, 0)) - { - if( *pstr == '\\' ) - { - switch( pstr[1] ) - { - case 'n': *pstr = '\n'; break; - case 't': *pstr = '\t'; break; - case 'r': *pstr = '\r'; break; - default: *pstr = pstr[1]; break; - } - memmove(pstr+1, pstr+2, strlen(pstr+2) + 1); - } - } -} - -#ifdef _DEBUG -#pragma optimize( "gt", on ) -#endif - -// MurmurHash2 -unsigned int __fastcall hash(const void * key, unsigned int len) -{ - // 'm' and 'r' are mixing constants generated offline. - // They're not really 'magic', they just happen to work well. - const unsigned int m = 0x5bd1e995; - const int r = 24; - - // Initialize the hash to a 'random' value - unsigned int h = len; - - // Mix 4 bytes at a time into the hash - const unsigned char * data = (const unsigned char *)key; - - while(len >= 4) - { - unsigned int k = *(unsigned int *)data; - - k *= m; - k ^= k >> r; - k *= m; - - h *= m; - h ^= k; - - data += 4; - len -= 4; - } - - // Handle the last few bytes of the input array - switch(len) - { - case 3: h ^= data[2] << 16; - case 2: h ^= data[1] << 8; - case 1: h ^= data[0]; - h *= m; - }; - - // Do a few final mixes of the hash to ensure the last few - // bytes are well-incorporated. - h ^= h >> 13; - h *= m; - h ^= h >> 15; - - return h; -} - -unsigned int __fastcall hashstrW(const char * key) -{ - if (key == NULL) return 0; - const unsigned int len = (unsigned int)wcslen((const wchar_t*)key); - char* buf = (char*)alloca(len + 1); - for (unsigned i = 0; i <= len ; ++i) - buf[i] = key[i << 1]; - return hash(buf, len); -} - -__inline unsigned int hashstr(const char * key) -{ - if (key == NULL) return 0; - const unsigned int len = (unsigned int)strlen((const char*)key); - return hash(key, len); -} - -#ifdef _DEBUG -#pragma optimize( "", on ) -#endif - -static int SortLangPackHashesProc(struct LangPackEntry *arg1,struct LangPackEntry *arg2) -{ - if(arg1->englishHashenglishHash) return -1; - if(arg1->englishHash>arg2->englishHash) return 1; - /* both source strings of the same hash (may not be the same string thou) put - the one that was written first to be found first */ - if(arg1->linePoslinePos) return -1; - if(arg1->linePos>arg2->linePos) return 1; - return 0; -} - - -static int SortLangPackHashesProc2(struct LangPackEntry *arg1,struct LangPackEntry *arg2) -{ - if(arg1->englishHashenglishHash) return -1; - if(arg1->englishHash>arg2->englishHash) return 1; - return 0; -} - -static int LoadLangPack(const TCHAR *szLangPack) -{ - FILE *fp; - char line[4096] = ""; - char *pszColon; - char *pszLine; - int entriesAlloced; - int startOfLine=0; - unsigned int linePos=1; - LCID langID; - UINT fileCp = CP_ACP; - - lstrcpy(langPack.filename,szLangPack); - fp = _tfopen(szLangPack,_T("rt")); - if(fp==NULL) return 1; - fgets(line,sizeof(line),fp); - size_t lineLen = strlen(line); - if (lineLen >= 3 && line[0]=='\xef' && line[1]=='\xbb' && line[2]=='\xbf') - { - fileCp = CP_UTF8; - memmove(line, line + 3, lineLen - 2); - } - TrimString(line); - if(lstrcmpA(line,"Language Pack")) {fclose(fp); return 2;} - //headers - while(!feof(fp)) { - startOfLine=ftell(fp); - if(fgets(line,sizeof(line),fp)==NULL) break; - TrimString(line); - if(IsEmpty(line) || line[0]==';' || line[0]==0) continue; - if(line[0]=='[') break; - pszColon=strchr(line,':'); - if(pszColon==NULL) {fclose(fp); return 3;} - *pszColon=0; - if(!lstrcmpA(line,"Language")) {_snprintf(langPack.language,sizeof(langPack.language),"%s",pszColon+1); TrimString(langPack.language);} - else if(!lstrcmpA(line,"Last-Modified-Using")) {_snprintf(langPack.lastModifiedUsing,sizeof(langPack.lastModifiedUsing),"%s",pszColon+1); TrimString(langPack.lastModifiedUsing);} - else if(!lstrcmpA(line,"Authors")) {_snprintf(langPack.authors,sizeof(langPack.authors),"%s",pszColon+1); TrimString(langPack.authors);} - else if(!lstrcmpA(line,"Author-email")) {_snprintf(langPack.authorEmail,sizeof(langPack.authorEmail),"%s",pszColon+1); TrimString(langPack.authorEmail);} - else if(!lstrcmpA(line,"RTL")) { - _snprintf(line,sizeof(line),"%s",pszColon+1); - TrimString(line); - langPack.rtl=!lstrcmpA(line,"1"); - } - else if(!lstrcmpA(line, "Locale")) { - char szBuf[20], *stopped; - - TrimString(pszColon + 1); - langID = (USHORT)strtol(pszColon + 1, &stopped, 16); - langPack.localeID = MAKELCID(langID, 0); - GetLocaleInfoA(langPack.localeID, LOCALE_IDEFAULTANSICODEPAGE, szBuf, 10); - szBuf[5] = 0; // codepages have max. 5 digits - langPack.defaultANSICp = atoi(szBuf); - if (fileCp == CP_ACP) - fileCp = langPack.defaultANSICp; - } - } - - //body - fseek(fp,startOfLine,SEEK_SET); - entriesAlloced=0; - while(!feof(fp)) { - if(fgets(line,sizeof(line),fp)==NULL) break; - if(IsEmpty(line) || line[0]==';' || line[0]==0) continue; - TrimStringSimple(line); - ConvertBackslashes(line, fileCp); - if(line[0]=='[' && line[lstrlenA(line)-1]==']') { - if(langPack.entryCount && langPack.entry[langPack.entryCount-1].local==NULL) { - if(langPack.entry[langPack.entryCount-1].english!=NULL) free(langPack.entry[langPack.entryCount-1].english); - langPack.entryCount--; - } - pszLine = line+1; - line[lstrlenA(line)-1]='\0'; - TrimStringSimple(line); - if(++langPack.entryCount>entriesAlloced) { - entriesAlloced+=128; - langPack.entry=(struct LangPackEntry*)realloc(langPack.entry,sizeof(struct LangPackEntry)*entriesAlloced); - } - langPack.entry[langPack.entryCount-1].english=NULL; - langPack.entry[langPack.entryCount-1].englishHash=hashstr(pszLine); - langPack.entry[langPack.entryCount-1].local=NULL; - langPack.entry[langPack.entryCount-1].wlocal = NULL; - langPack.entry[langPack.entryCount-1].linePos=linePos++; - } - else if(langPack.entryCount) { - struct LangPackEntry* E = &langPack.entry[langPack.entryCount-1]; - - if(E->local==NULL) { - E->local = _strdup(line); - if (fileCp == CP_UTF8) - Utf8DecodeCP(E->local, langPack.defaultANSICp, NULL); - - { - int iNeeded = MultiByteToWideChar(fileCp, 0, line, -1, 0, 0); - E->wlocal = (wchar_t *)malloc((iNeeded+1) * sizeof(wchar_t)); - MultiByteToWideChar(fileCp, 0, line, -1, E->wlocal, iNeeded); - } - } - else { - size_t iOldLenA = strlen(E->local); - E->local = (char*)realloc(E->local, iOldLenA + strlen(line) + 2); - strcat(E->local, "\n"); - strcat(E->local, line); - if (fileCp == CP_UTF8) - Utf8DecodeCP(E->local + iOldLenA + 1, langPack.defaultANSICp, NULL); - { - int iNeeded = MultiByteToWideChar(fileCp, 0, line, -1, 0, 0); - size_t iOldLen = wcslen(E->wlocal); - E->wlocal = (wchar_t*)realloc(E->wlocal, ( sizeof(wchar_t) * ( iOldLen + iNeeded + 2))); - wcscat(E->wlocal, L"\n"); - MultiByteToWideChar(fileCp, 0, line, -1, E->wlocal + iOldLen+1, iNeeded); - } - } - } - } - fclose(fp); - - qsort(langPack.entry,langPack.entryCount,sizeof(LangPackEntry),(int(*)(const void*,const void*))SortLangPackHashesProc); - - return 0; -} - -char *LangPackTranslateString(const char *szEnglish, const int W) -{ - struct LangPackEntry key,*entry; - - if ( langPack.entryCount == 0 || szEnglish == NULL ) return (char*)szEnglish; - - key.englishHash = W ? hashstrW(szEnglish) : hashstr(szEnglish); - - entry=(struct LangPackEntry*)bsearch(&key,langPack.entry,langPack.entryCount,sizeof(struct LangPackEntry),(int(*)(const void*,const void*))SortLangPackHashesProc2); - if(entry==NULL) return (char*)szEnglish; - while(entry>langPack.entry) - { - entry--; - if(entry->englishHash!=key.englishHash) { - entry++; - return W ? (char *)entry->wlocal : entry->local; - } - } - return W ? (char *)entry->wlocal : entry->local; -} - -#if defined( _UNICODE ) - #define FLAGS 1 -#else - #define FLAGS 0 -#endif - -static void TranslateWindow( HWND hwnd ) -{ - TCHAR title[2048]; - GetWindowText(hwnd, title, SIZEOF( title )); - { - TCHAR* result = ( TCHAR* )LangPackTranslateString(( char* )title, FLAGS ); - if ( result != title ) - SetWindowText(hwnd, result ); - } -} - -static BOOL CALLBACK TranslateDialogEnumProc(HWND hwnd,LPARAM lParam) -{ - TCHAR szClass[32]; - int id = GetDlgCtrlID( hwnd ); - - GetClassName(hwnd,szClass,SIZEOF(szClass)); - - if(!lstrcmpi(szClass,_T("static")) || !lstrcmpi(szClass,_T("hyperlink")) || !lstrcmpi(szClass,_T("button")) || !lstrcmpi(szClass,_T("MButtonClass"))) - TranslateWindow(hwnd); - else if(!lstrcmpi(szClass,_T("edit"))) { - if ( GetWindowLongPtr(hwnd,GWL_STYLE)&ES_READONLY) - TranslateWindow(hwnd); - } - return TRUE; -} - -int TranslateDialog( HWND hwndDlg ) -{ - TranslateWindow( hwndDlg ); - EnumChildWindows( hwndDlg,TranslateDialogEnumProc,0); - return 0; -} - -void TranslateMenu( HMENU hmenu ) -{ - TCHAR title[2048]; - int count = GetMenuItemCount( hmenu ); - for (int i = 0; i < count; i++) - { - if (GetMenuString( hmenu, i, title, 2048, MF_BYPOSITION )) - { - wchar_t * p = wcsstr(title ,_T("\t")); - TCHAR translated[2048] = _T(""); - if (p!=NULL) { - *p = 0; - } - StringCchCat(translated,2048,(LPTSTR)LangPackTranslateString((char*)title, FLAGS)); - if (p!=NULL) { - *p = '\t'; - StringCchCat(translated,2048,p); - } - ModifyMenu( - hmenu, - i, - MF_BYPOSITION | MF_STRING, - GetMenuItemID( hmenu, i ), - translated - ); - } - } -} - - -void LoadLangPackModule(void) -{ - HANDLE hFind; - TCHAR szSearch[MAX_PATH], *str2, szLangPack[MAX_PATH]; - WIN32_FIND_DATA fd; - langPack.rtl = 0; - GetModuleFileName(GetModuleHandle(NULL),szSearch,MAX_PATH); - str2 = _tcsrchr(szSearch, '\\'); - if (str2) *str2 = 0; else str2 = szSearch; - _tcscat(szSearch, _T("\\langpack_*.txt")); - hFind = FindFirstFile(szSearch, &fd); - if (hFind != INVALID_HANDLE_VALUE) - { - FindClose(hFind); - - _tcscpy(str2 + 1, fd.cFileName); - _tcscpy(szLangPack, szSearch); - LoadLangPack(szLangPack); - } -} - -void UnloadLangPackModule(void) -{ - for (int i = 0; i < langPack.entryCount; i++) { - free(langPack.entry[i].english); - free(langPack.entry[i].local); - free(langPack.entry[i].wlocal); - } - if (langPack.entryCount) { - free(langPack.entry); - langPack.entry=0; - langPack.entryCount=0; - } - langPack.rtl = 0; -} diff --git a/microsip/langpack.h b/microsip/langpack.h deleted file mode 100644 index ea51c81c..00000000 --- a/microsip/langpack.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include "const.h" - -#if defined( UNICODE ) && !defined( _UNICODE ) - #define _UNICODE -#endif - -#define SIZEOF(X) (sizeof(X)/sizeof(X[0])) - -struct LangPackEntry { - unsigned linePos; - DWORD englishHash; - char *english; //not currently used, the hash does everything - char *local; - wchar_t *wlocal; -}; - -struct LangPackStruct { - TCHAR filename[MAX_PATH]; - char language[64]; - char lastModifiedUsing[64]; - char authors[256]; - char authorEmail[128]; - bool rtl; - struct LangPackEntry *entry; - int entryCount; - LCID localeID; - UINT defaultANSICp; -}; -extern LangPackStruct langPack; - -void LoadLangPackModule(void); -void UnloadLangPackModule(void); -int TranslateDialog(HWND hwndDlg); -void TranslateMenu(HMENU hmenu); - -char* LangPackTranslateString(const char *szEnglish, const int W); -__inline LPTSTR Translate(LPTSTR source) -{ -#ifdef _UNICODE - return ( LPTSTR )LangPackTranslateString( (char*)source, 1 ); -#else - return ( LPTSTR )LangPackTranslateString( source, 0 ); -#endif - - -} \ No newline at end of file diff --git a/microsip/main.rc b/microsip/main.rc deleted file mode 100644 index 2bba5416..00000000 --- a/microsip/main.rc +++ /dev/null @@ -1,99 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#ifndef APSTUDIO_INVOKED -#include "targetver.h" -#endif -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#ifndef APSTUDIO_INVOKED\r\n" - "#include ""targetver.h""\r\n" - "#endif\r\n" - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "#define _AFX_NO_SPLITTER_RESOURCES\r\n" - "#define _AFX_NO_OLE_RESOURCES\r\n" - "#define _AFX_NO_TRACKER_RESOURCES\r\n" - "#define _AFX_NO_PROPERTY_RESOURCES\r\n" - "\r\n" - "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" - "LANGUAGE 9, 1\r\n" - "#pragma code_page(1252)\r\n" - "#include ""res\\main.rc2"" // non-Microsoft Visual C++ edited resources\r\n" - "#include ""res\\dialog.rc2"" // non-Microsoft Visual C++ edited resources\r\n" - "#include ""res\\menu.rc2"" // non-Microsoft Visual C++ edited resources\r\n" - "#include ""afxres.rc"" // Standard components\r\n" - "#endif\r\n" - "\0" -END - -///////////////////////////////////////////////////////////////////////////// -#endif // APSTUDIO_INVOKED - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE 9, 1 -#pragma code_page(1252) - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_STATUSBAR "Status" -END - -#endif -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// -#define _AFX_NO_SPLITTER_RESOURCES -#define _AFX_NO_OLE_RESOURCES -#define _AFX_NO_TRACKER_RESOURCES -#define _AFX_NO_PROPERTY_RESOURCES - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE 9, 1 -#pragma code_page(1252) -#include "res\main.rc2" // non-Microsoft Visual C++ edited resources -#include "res\dialog.rc2" // non-Microsoft Visual C++ edited resources -#include "res\menu.rc2" // non-Microsoft Visual C++ edited resources -#include "afxres.rc" // Standard components -#endif - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/microsip/mainDlg.cpp b/microsip/mainDlg.cpp deleted file mode 100644 index 2bfcb57a..00000000 --- a/microsip/mainDlg.cpp +++ /dev/null @@ -1,4007 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "mainDlg.h" - -#include "microsip.h" - -#include "Mmsystem.h" -#include "settings.h" -#include "global.h" -#include "ModelessMessageBox.h" -#include "utf.h" -#include "langpack.h" -#include "jumplist.h" -#include "atlenc.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include "atlrx.h" - -using namespace MSIP; - -#ifdef _DEBUG -#define new DEBUG_NEW -#endif - -CmainDlg *mainDlg; - -static UINT WM_SHELLHOOKMESSAGE; - -static UINT BASED_CODE indicators[] = -{ - IDS_STATUSBAR, - IDS_STATUSBAR2 -}; - -static bool timerContactBlinkState = false; - -static CString gethostbyaddrThreadResult; -static DWORD WINAPI gethostbyaddrThread(LPVOID lpParam) -{ - CString *addr = (CString *)lpParam; - gethostbyaddrThreadResult = *addr; - struct hostent *he = NULL; - struct in_addr inaddr; - inaddr.S_un.S_addr = inet_addr(CStringA(*addr)); - if (inaddr.S_un.S_addr != INADDR_NONE && inaddr.S_un.S_addr != INADDR_ANY) { - he = gethostbyaddr((char *)&inaddr, 4, AF_INET); - if (he) { - gethostbyaddrThreadResult = he->h_name; - } - } - delete addr; - return 0; -} - -static void on_reg_state2(pjsua_acc_id acc_id, pjsua_reg_info *info) -{ - if (!IsWindow(mainDlg->m_hWnd)) { - return; - } - CString *str = NULL; - PostMessage(mainDlg->m_hWnd, UM_ON_REG_STATE2, (WPARAM)info->cbparam->code, (LPARAM)str); -} - -LRESULT CmainDlg::onRegState2(WPARAM wParam, LPARAM lParam) -{ - int code = wParam; - - if (code == 200) { - if (accountSettings.usersDirectory.Find(_T("%s")) != -1 || accountSettings.usersDirectory.Find(_T("{")) != -1) { - UsersDirectoryLoad(); - } - } - - UpdateWindowText(_T(""), IDI_DEFAULT, true); - - return 0; -} - -/* Callback from timer when the maximum call duration has been - * exceeded. - */ -static void call_timeout_callback(pj_timer_heap_t *timer_heap, - struct pj_timer_entry *entry) -{ - pjsua_call_id call_id = entry->id; - pjsua_msg_data msg_data_; - pjsip_generic_string_hdr warn; - pj_str_t hname = pj_str("Warning"); - pj_str_t hvalue = pj_str("399 localhost \"Call duration exceeded\""); - - PJ_UNUSED_ARG(timer_heap); - - if (call_id == PJSUA_INVALID_ID) { - PJ_LOG(1, (THIS_FILE, "Invalid call ID in timer callback")); - return; - } - - /* Add warning header */ - pjsua_msg_data_init(&msg_data_); - pjsip_generic_string_hdr_init2(&warn, &hname, &hvalue); - pj_list_push_back(&msg_data_.hdr_list, &warn); - - /* Call duration has been exceeded; disconnect the call */ - PJ_LOG(3, (THIS_FILE, "Duration (%d seconds) has been exceeded " - "for call %d, disconnecting the call", - accountSettings.autoHangUpTime, call_id)); - entry->id = PJSUA_INVALID_ID; - pjsua_call_hangup(call_id, 200, NULL, &msg_data_); -} - -static void on_call_state(pjsua_call_id call_id, pjsip_event *e) -{ - if (!IsWindow(mainDlg->m_hWnd)) { - return; - } - pjsua_call_info *call_info = new pjsua_call_info(); - if (pjsua_call_get_info(call_id, call_info) != PJ_SUCCESS || call_info->state == PJSIP_INV_STATE_NULL) { - return; - } - - call_user_data *user_data = (call_user_data *)pjsua_call_get_user_data(call_info->id); - // reset user_data after call transfer - if (user_data && user_data->call_id != PJSUA_INVALID_ID && user_data->call_id != call_info->id) { - pjsua_call_set_user_data(call_info->id, NULL); - user_data = NULL; - } - if (!user_data) { - user_data = new call_user_data(call_info->id); - pjsua_call_set_user_data(call_info->id, user_data); - } - - switch (call_info->state) { - case PJSIP_INV_STATE_CALLING: - msip_call_unhold(call_info); - break; - case PJSIP_INV_STATE_CONNECTING: - msip_call_unhold(call_info); - break; - case PJSIP_INV_STATE_CONFIRMED: - if (accountSettings.autoHangUpTime > 0) { - /* Schedule timer to hangup call after the specified duration */ - pj_time_val delay; - user_data->auto_hangup_timer.id = call_info->id; - user_data->auto_hangup_timer.cb = &call_timeout_callback; - delay.sec = accountSettings.autoHangUpTime; - delay.msec = 0; - pjsua_schedule_timer(&user_data->auto_hangup_timer, &delay); - } - break; - case PJSIP_INV_STATE_DISCONNECTED: - /* Cancel duration timer, if any */ - if (user_data->auto_hangup_timer.id != PJSUA_INVALID_ID) { - pjsua_cancel_timer(&user_data->auto_hangup_timer); - user_data->auto_hangup_timer.id = PJSUA_INVALID_ID; - } - call_deinit_tonegen(call_info->id); - msip_conference_leave(call_info); - pjsua_call_set_user_data(call_info->id, NULL); - break; - } - PostMessage(mainDlg->m_hWnd, UM_ON_CALL_STATE, (WPARAM)call_info, (LPARAM)user_data); -} - -LRESULT CmainDlg::onCallState(WPARAM wParam, LPARAM lParam) -{ - pjsua_call_info *call_info = (pjsua_call_info *)wParam; - call_user_data *user_data = (call_user_data *)lParam; - - //-- - - CString *str = new CString(); - CString adder; - - if (call_info->state != PJSIP_INV_STATE_DISCONNECTED && call_info->state != PJSIP_INV_STATE_CONNECTING && call_info->remote_contact.slen > 0) { - SIPURI contactURI; - ParseSIPURI(PjToStr(&call_info->remote_contact, TRUE), &contactURI); - CString contactDomain = RemovePort(contactURI.domain); - struct hostent *he = NULL; - if (IsIP(contactDomain)) { - HANDLE hThread; - CString *addr = new CString; - *addr = contactDomain; - hThread = CreateThread(NULL, 0, gethostbyaddrThread, addr, 0, NULL); - if (WaitForSingleObject(hThread, 500) == 0) { - contactDomain = gethostbyaddrThreadResult; - } - } - adder.AppendFormat(_T("%s, "), contactDomain); - } - - unsigned cnt = 0; - unsigned cnt_srtp = 0; - - switch (call_info->state) { - case PJSIP_INV_STATE_CALLING: - str->Format(_T("%s..."), Translate(_T("Calling"))); - break; - case PJSIP_INV_STATE_INCOMING: - str->SetString(Translate(_T("Incoming Call"))); - break; - case PJSIP_INV_STATE_EARLY: - str->SetString(Translate(PjToStr(&call_info->last_status_text).GetBuffer())); - break; - case PJSIP_INV_STATE_CONNECTING: - str->Format(_T("%s..."), Translate(_T("Connecting"))); - break; - case PJSIP_INV_STATE_CONFIRMED: - str->SetString(Translate(_T("Connected"))); - for (unsigned i = 0; i < call_info->media_cnt; i++) { - if (call_info->media[i].dir != PJMEDIA_DIR_NONE && - (call_info->media[i].type == PJMEDIA_TYPE_AUDIO || call_info->media[i].type == PJMEDIA_TYPE_VIDEO)) { - cnt++; - pjsua_call_info call_info_stub; - if (pjsua_var.state == PJSUA_STATE_RUNNING && pjsua_call_get_info(call_info->id, &call_info_stub) == PJ_SUCCESS) { - pjsua_stream_info psi; - if (pjsua_call_get_stream_info(call_info->id, call_info->media[i].index, &psi) == PJ_SUCCESS) { - if (call_info->media[i].type == PJMEDIA_TYPE_AUDIO) { - adder.AppendFormat(_T("%s@%dkHz %dkbit/s%s, "), - PjToStr(&psi.info.aud.fmt.encoding_name), psi.info.aud.fmt.clock_rate / 1000, - psi.info.aud.param->info.avg_bps / 1000, - psi.info.aud.fmt.channel_cnt == 2 ? _T(" Stereo") : _T("") - ); - } - else { - adder.AppendFormat(_T("%s %dkbit/s, "), - PjToStr(&psi.info.vid.codec_info.encoding_name), - psi.info.vid.codec_param->enc_fmt.det.vid.max_bps / 1000 - ); - } - } - pjmedia_transport_info t; - if (pjsua_call_get_med_transport_info(call_info->id, call_info->media[i].index, &t) == PJ_SUCCESS) { - for (unsigned j = 0; j < t.specific_info_cnt; j++) { - if (t.spc_info[j].buffer[0]) { - switch (t.spc_info[j].type) { - case PJMEDIA_TRANSPORT_TYPE_SRTP: - adder.Append(_T("SRTP, ")); - cnt_srtp++; - break; - case PJMEDIA_TRANSPORT_TYPE_ICE: - adder.Append(_T("ICE, ")); - break; - } - } - } - } - } - } - } - if (cnt_srtp && cnt == cnt_srtp) { - user_data->srtp = MSIP_SRTP; - } - else { - user_data->srtp = MSIP_SRTP_DISABLED; - } - break; - case PJSIP_INV_STATE_DISCONNECTED: - //-- - if (call_info->last_status == 200) { - str->SetString(Translate(_T("Call Ended"))); - } - else { - CString rab = PjToStr(&call_info->last_status_text); - if (rab.Find(_T("(PJ_ERESOLVE)")) != -1) { - rab = _T("Cannot get IP address of the called host."); - } - rab = Translate(rab.GetBuffer()); - if (call_info->last_status) { - str->Format(_T("%d %s"), call_info->last_status, rab); - } - else { - str->SetString(rab); - } - } - break; - } - - if (!str->IsEmpty() && !adder.IsEmpty()) { - str->AppendFormat(_T(" (%s)"), adder.Left(adder.GetLength() - 2)); - } - - //-- - - CString number = PjToStr(&call_info->remote_info, TRUE); - SIPURI sipuri; - ParseSIPURI(number, &sipuri); - if (call_info->state == PJSIP_INV_STATE_CONFIRMED) { - PostMessage(WM_TIMER, IDT_TIMER_CALL, NULL); - SetTimer(IDT_TIMER_CALL, 1000, NULL); - if (!accountSettings.cmdCallStart.IsEmpty()) { - ShellExecute(NULL, NULL, accountSettings.cmdCallStart, sipuri.user, NULL, SW_HIDE); - } - if (user_data && !user_data->commands.IsEmpty()) { - SetTimer((UINT_PTR)call_info->id, 1000, (TIMERPROC)DTMFQueueTimerHandler); - } - } - - if (!accountSettings.singleMode) { - if (call_info->state != PJSIP_INV_STATE_CONFIRMED) { - if (call_info->state != PJSIP_INV_STATE_DISCONNECTED) { - UpdateWindowText(*str, call_info->acc_id == account && mainDlg->iconStatusbar == IDI_SECURE ? IDI_SECURE : IDI_ONLINE); - } - else { - PostMessage(UM_UPDATEWINDOWTEXT, 0, 0); - } - } - } - - if (call_info->role == PJSIP_ROLE_UAC && accountSettings.localDTMF) { - if (call_info->last_status == 180 && !call_info->media_cnt) { - if (toneCalls.IsEmpty()) { - PostMessage(WM_TIMER, IDT_TIMER_TONE, NULL); - SetTimer(IDT_TIMER_TONE, 4500, NULL); - toneCalls.AddTail(call_info->id); - } - else if (toneCalls.Find(call_info->id) == NULL) { - toneCalls.AddTail(call_info->id); - } - } - else { - POSITION position = toneCalls.Find(call_info->id); - if (position != NULL) { - toneCalls.RemoveAt(position); - if (toneCalls.IsEmpty()) { - KillTimer(IDT_TIMER_TONE); - PostMessage(UM_ON_PLAYER_STOP, 0, 0); - } - } - } - } - - bool doNotShowMessagesWindow = - call_info->state == PJSIP_INV_STATE_INCOMING || - call_info->state == PJSIP_INV_STATE_EARLY || - call_info->state == PJSIP_INV_STATE_DISCONNECTED || - accountSettings.singleMode || - (accountSettings.silent && !mainDlg->IsWindowVisible()); - MessagesContact* messagesContact = messagesDlg->AddTab(number, _T(""), - (!accountSettings.singleMode && - (call_info->state == PJSIP_INV_STATE_CONFIRMED - || call_info->state == PJSIP_INV_STATE_CONNECTING) - ) - || - (accountSettings.singleMode - && - ( - (call_info->role == PJSIP_ROLE_UAC && call_info->state != PJSIP_INV_STATE_DISCONNECTED) - || - (call_info->role == PJSIP_ROLE_UAS && - (call_info->state == PJSIP_INV_STATE_CONFIRMED - || call_info->state == PJSIP_INV_STATE_CONNECTING) - ) - )) - ? TRUE : FALSE, - call_info, user_data, doNotShowMessagesWindow, call_info->state == PJSIP_INV_STATE_DISCONNECTED - ); - - if (call_info->state == PJSIP_INV_STATE_DISCONNECTED) { - CString number = sipuri.user; - if (call_info->last_status == 200) { - onPlayerPlay(MSIP_SOUND_HANGUP, 0); - } - else { - if (accountSettings.singleMode && call_info->last_status != 487 && (call_info->last_status != 603 || call_info->role == PJSIP_ROLE_UAC)) { - if (messagesContact) { - BaloonPopup(*str, messagesContact->name, NIIF_INFO); - } - else { - BaloonPopup(*str, number, NIIF_INFO); - } - } - } - if (call_info->last_status != 486) { - if (!accountSettings.cmdCallEnd.IsEmpty()) { - ShellExecute(NULL, NULL, accountSettings.cmdCallEnd, number, NULL, SW_HIDE); - } - } - if (call_info->role == PJSIP_ROLE_UAS && call_info->last_status == 487) { - //-- missed call - missed = true; - } - } - - if (messagesContact) { - if (call_info->state == PJSIP_INV_STATE_DISCONNECTED) { - messagesContact->mediaStatus = PJSUA_CALL_MEDIA_ERROR; - } - if (call_info->role == PJSIP_ROLE_UAS) { - if (call_info->state == PJSIP_INV_STATE_CONFIRMED) { - pageCalls->Add(call_info->call_id, messagesContact->number + messagesContact->numberParameters, messagesContact->name, MSIP_CALL_IN); - } - else if (call_info->state == PJSIP_INV_STATE_INCOMING || call_info->state == PJSIP_INV_STATE_EARLY) { - pageCalls->Add(call_info->call_id, messagesContact->number + messagesContact->numberParameters, messagesContact->name, MSIP_CALL_MISS); - } - } - else { - if (call_info->state == PJSIP_INV_STATE_CALLING) { - pageCalls->Add(call_info->call_id, messagesContact->number + messagesContact->numberParameters, messagesContact->name, MSIP_CALL_OUT); - } - } - } - if (call_info->state == PJSIP_INV_STATE_DISCONNECTED) { - pageCalls->SetDuration(call_info->call_id, call_info->connect_duration.sec); - if (call_info->last_status != 200) { - pageCalls->SetInfo(call_info->call_id, *str); - } - } - - if (call_info->role == PJSIP_ROLE_UAS && call_info->state == PJSIP_INV_STATE_CONFIRMED) { - if (!accountSettings.cmdCallAnswer.IsEmpty()) { - ShellExecute(NULL, NULL, accountSettings.cmdCallAnswer, sipuri.user, NULL, SW_HIDE); - } - } - - if (accountSettings.singleMode) { - if (call_info->state == PJSIP_INV_STATE_DISCONNECTED) { - MessagesContact *messagesContactSelected = messagesDlg->GetMessageContact(); - if (!messagesContactSelected || messagesContactSelected->callId == call_info->id || messagesContactSelected->callId == -1) { - pageDialer->Clear(false); - pageDialer->UpdateCallButton(FALSE, 0); - } - PostMessage(UM_UPDATEWINDOWTEXT, 0, 0); - } - else { - if (call_info->state != PJSIP_INV_STATE_CONFIRMED) { - UpdateWindowText(*str, call_info->acc_id == account && mainDlg->iconStatusbar == IDI_SECURE ? IDI_SECURE : IDI_ONLINE); - } - int tabN = 0; - GotoTab(tabN); - messagesDlg->OnChangeTab(call_info, user_data); - } - } - else { - if (call_info->state == PJSIP_INV_STATE_DISCONNECTED) { - pageDialer->PostMessage(WM_COMMAND, MAKELPARAM(IDC_CLEAR, 0), 0); - } - } - - if (messagesContact && !str->IsEmpty()) { - messagesDlg->AddMessage(messagesContact, *str, MSIP_MESSAGE_TYPE_SYSTEM, - call_info->state == PJSIP_INV_STATE_INCOMING || call_info->state == PJSIP_INV_STATE_EARLY - ); - } - - if (call_info->state == PJSIP_INV_STATE_DISCONNECTED) { - messagesDlg->OnEndCall(call_info); - if (pjsua_var.state != PJSUA_STATE_RUNNING || !pjsua_call_get_count()) { -#ifdef _GLOBAL_VIDEO - if (previewWin) { - previewWin->PostMessage(WM_CLOSE, NULL, NULL); - } -#endif - } - } - - if (call_info->role == PJSIP_ROLE_UAS) { - if (call_info->state == PJSIP_INV_STATE_DISCONNECTED || call_info->state == PJSIP_INV_STATE_CONFIRMED) { - int count = ringinDlgs.GetCount(); - if (!count) { - if (call_info->state == PJSIP_INV_STATE_CONFIRMED || (call_info->state == PJSIP_INV_STATE_DISCONNECTED && call_info->connect_duration.sec == 0 && call_info->connect_duration.msec == 0)) { - PlayerStop(); - } - } - else { - for (int i = 0; i < count; i++) { - RinginDlg *ringinDlg = ringinDlgs.GetAt(i); - if (call_info->id == ringinDlg->call_id) { - if (count == 1) { - PlayerStop(); - } - ringinDlgs.RemoveAt(i); - ringinDlg->DestroyWindow(); - break; - } - } - } - } - } - - // --delete user data - if (call_info->state == PJSIP_INV_STATE_DISCONNECTED) { - if (user_data) { - delete user_data; - } - } - // -- - delete call_info; - delete str; - return 0; -} - -static void on_call_media_state(pjsua_call_id call_id) -{ - pjsua_call_info *call_info = new pjsua_call_info(); - if (pjsua_call_get_info(call_id, call_info) != PJ_SUCCESS || call_info->state == PJSIP_INV_STATE_NULL) { - return; - } - - call_user_data *user_data = (call_user_data *)pjsua_call_get_user_data(call_info->id); - - if (call_info->media_status == PJSUA_CALL_MEDIA_ACTIVE - || call_info->media_status == PJSUA_CALL_MEDIA_REMOTE_HOLD - ) { - msip_conference_join(call_info); - pjsua_conf_connect(call_info->conf_slot, 0); - pjsua_conf_connect(0, call_info->conf_slot); - //-- - //-- - ::SetTimer(mainDlg->pageDialer->m_hWnd, IDT_TIMER_VU_METER, 100, NULL); - //-- - } - else { - msip_conference_leave(call_info, true); - pjsua_conf_disconnect(call_info->conf_slot, 0); - pjsua_conf_disconnect(0, call_info->conf_slot); - call_deinit_tonegen(call_id); - //-- - //-- - } - PostMessage(mainDlg->m_hWnd, UM_ON_CALL_MEDIA_STATE, (WPARAM)call_info, (LPARAM)user_data); -} - -LRESULT CmainDlg::onCallMediaState(WPARAM wParam, LPARAM lParam) -{ - pjsua_call_info *call_info = (pjsua_call_info *)wParam; - call_user_data *user_data = (call_user_data *)lParam; - - messagesDlg->UpdateHoldButton(call_info); - - CString message; - CString number = PjToStr(&call_info->remote_info, TRUE); - - MessagesContact* messagesContact = messagesDlg->AddTab(number, _T(""), FALSE, call_info, user_data, TRUE, TRUE); - - if (messagesContact) { - if (call_info->media_status == PJSUA_CALL_MEDIA_REMOTE_HOLD) { - message = _T("Call on Remote Hold"); - } - if (call_info->media_status == PJSUA_CALL_MEDIA_LOCAL_HOLD) { - message = _T("Call on Local Hold"); - } - if (call_info->media_status == PJSUA_CALL_MEDIA_NONE) { - message = _T("Call on Hold"); - } - if (messagesContact->mediaStatus != PJSUA_CALL_MEDIA_ERROR && messagesContact->mediaStatus != call_info->media_status && call_info->media_status == PJSUA_CALL_MEDIA_ACTIVE) { - message = _T("Call is Active"); - } - if (!message.IsEmpty()) { - messagesDlg->AddMessage(messagesContact, Translate(message.GetBuffer()), MSIP_MESSAGE_TYPE_SYSTEM, TRUE); - } - messagesContact->mediaStatus = call_info->media_status; - } - - if (call_info->media_status == PJSUA_CALL_MEDIA_ACTIVE - || call_info->media_status == PJSUA_CALL_MEDIA_REMOTE_HOLD - ) { - onRefreshLevels(0, 0); - } - - delete call_info; - - return 0; -} - -static void on_call_media_event(pjsua_call_id call_id, - unsigned med_idx, - pjmedia_event *event) -{ - char event_name[5]; - - PJ_LOG(5, (THIS_FILE, "Event %s", - pjmedia_fourcc_name(event->type, event_name))); - - //#if PJSUA_HAS_VIDEO - //if (event->type == PJMEDIA_EVENT_FMT_CHANGED) { - // pjsua_call_info ci; - // pjsua_call_get_info(call_id, &ci); - // if ((ci.media[med_idx].type == PJMEDIA_TYPE_VIDEO) && - // (ci.media[med_idx].dir & PJMEDIA_DIR_DECODING)) { - // pjsua_vid_win_id wid; - // pjmedia_rect_size size; - // pjsua_vid_win_info win_info; - - // wid = ci.media[med_idx].stream.vid.win_in; - // pjsua_vid_win_get_info(wid, &win_info); - - // size = event->data.fmt_changed.new_fmt.det.vid.size; - // if (size.w != win_info.size.w || size.h != win_info.size.h) { - // pjsua_vid_win_set_size(wid, &size); - // /* Re-arrange video windows */ - // arrange_window(PJSUA_INVALID_ID); - // } - // } - //} - //#else - // PJ_UNUSED_ARG(call_id); - // PJ_UNUSED_ARG(med_idx); - // PJ_UNUSED_ARG(event); - //#endif -} - -static void on_incoming_call(pjsua_acc_id acc, pjsua_call_id call_id, - pjsip_rx_data *rdata) -{ - pjsua_call_info call_info; - pjsua_call_get_info(call_id, &call_info); - - call_user_data *user_data = (call_user_data *)pjsua_call_get_user_data(call_info.id); - if (!user_data) { - user_data = new call_user_data(call_info.id); - pjsua_call_set_user_data(call_info.id, user_data); - } - - SIPURI sipuri; - ParseSIPURI(PjToStr(&call_info.remote_info, TRUE), &sipuri); - if (accountSettings.forceCodec) { - pjsua_call *call; - pjsip_dialog *dlg; - pj_status_t status; - status = acquire_call("on_incoming_call()", call_id, &call, &dlg); - if (status == PJ_SUCCESS) { - pjmedia_sdp_neg_set_prefer_remote_codec_order(call->inv->neg, PJ_FALSE); - pjsip_dlg_dec_lock(dlg); - } - } - - pjsua_call_id call_ids[PJSUA_MAX_CALLS]; - unsigned calls_count = PJSUA_MAX_CALLS; - unsigned calls_count_cmp = 0; - if (pjsua_enum_calls(call_ids, &calls_count) == PJ_SUCCESS) { - for (unsigned i = 0; i < calls_count; ++i) { - pjsua_call_info call_info_curr; - if (pjsua_call_get_info(call_ids[i], &call_info_curr) == PJ_SUCCESS) { - SIPURI sipuri_curr; - ParseSIPURI(PjToStr(&call_info_curr.remote_info, TRUE), &sipuri_curr); - if (call_info_curr.id != call_info.id && - sipuri.user + _T("@") + sipuri.domain == sipuri_curr.user + _T("@") + sipuri_curr.domain - ) { - // 486 Busy Here - pjsua_call_hangup(call_info.id, 486, NULL, NULL); - return; - } - if (call_info_curr.state != PJSIP_INV_STATE_DISCONNECTED) { - calls_count_cmp++; - } - } - } - } - - if (accountSettings.maxConcurrentCalls > 0 && calls_count_cmp > accountSettings.maxConcurrentCalls) { - // 486 Busy Here - pjsua_call_hangup(call_info.id, 486, NULL, NULL); - return; - } - - if (IsWindow(mainDlg->m_hWnd)) { - // -- diversion - const pj_str_t headerDiversion = { "Diversion",9 }; - pjsip_generic_string_hdr *hsr = NULL; - hsr = (pjsip_generic_string_hdr*)pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &headerDiversion, NULL); - if (hsr) { - CString str = PjToStr(&hsr->hvalue, true); - SIPURI sipuriDiversion; - ParseSIPURI(str, &sipuriDiversion); - user_data->diversion = !sipuriDiversion.user.IsEmpty() ? sipuriDiversion.user : sipuriDiversion.domain; - } - // -- end diversion - if (!mainDlg->callIdIncomingIgnore.IsEmpty() && mainDlg->callIdIncomingIgnore == PjToStr(&call_info.call_id)) { - pjsua_call_answer(call_id, 487, NULL, NULL); - return; - } - - bool reject = false; - if (accountSettings.denyIncoming == _T("all")) { - reject = true; - } - else if (accountSettings.denyIncoming == _T("button")) { - reject = accountSettings.DND; - } - else if (accountSettings.denyIncoming == _T("user")) { - SIPURI sipuri_curr; - ParseSIPURI(PjToStr(&call_info.local_info, TRUE), &sipuri_curr); - if (sipuri_curr.user != get_account_username()) { - reject = true; - } - } - else if (accountSettings.denyIncoming == _T("domain")) { - SIPURI sipuri_curr; - ParseSIPURI(PjToStr(&call_info.local_info, TRUE), &sipuri_curr); - if (accountSettings.accountId) { - if (sipuri_curr.domain != accountSettings.account.domain) { - reject = true; - } - } - } - else if (accountSettings.denyIncoming == _T("rdomain")) { - if (accountSettings.accountId) { - if (sipuri.domain != accountSettings.account.domain) { - reject = true; - } - } - } - else if (accountSettings.denyIncoming == _T("address")) { - SIPURI sipuri_curr; - ParseSIPURI(PjToStr(&call_info.local_info, TRUE), &sipuri_curr); - if (sipuri_curr.user != get_account_username() || (accountSettings.account.domain != _T("") && sipuri_curr.domain != accountSettings.account.domain)) { - reject = true; - } - } - - if (reject) { - pjsua_call_hangup(call_info.id, 486, NULL, NULL); - return; - } - - accountSettings.lastCallNumber = sipuri.user; - accountSettings.lastCallHasVideo = false; - - if (!accountSettings.cmdIncomingCall.IsEmpty()) { - ShellExecute(NULL, NULL, accountSettings.cmdIncomingCall, sipuri.user, NULL, SW_HIDE); - } - - bool autoAnswer = false; - bool noRingDialog = false; - if (accountSettings.autoAnswer == _T("all")) { - autoAnswer = true; - } - else if (accountSettings.autoAnswer == _T("button")) { - autoAnswer = accountSettings.AA; - } - else if (accountSettings.autoAnswer == _T("header")) { - //-- - pjsip_generic_string_hdr *hsr = NULL; - const pj_str_t header = pj_str("X-AUTOANSWER"); - hsr = (pjsip_generic_string_hdr*)pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &header, NULL); - if (hsr) { - CString autoAnswerValue = PjToStr(&hsr->hvalue, TRUE); - autoAnswerValue.MakeLower(); - if (autoAnswerValue == _T("true") || autoAnswerValue == _T("1")) { - autoAnswer = 1; - } - } - //-- - if (!autoAnswer) { - pjsip_generic_string_hdr *hsr = NULL; - const pj_str_t header = pj_str("Call-Info"); - hsr = (pjsip_generic_string_hdr*)pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &header, NULL); - if (hsr) { - CString callInfoValue = PjToStr(&hsr->hvalue, TRUE); - callInfoValue.MakeLower(); - if (callInfoValue.Find(_T("auto answer")) != -1) { - autoAnswer = 1; - } - else { - CAtlRegExp<> regex; - REParseError parseStatus = regex.Parse(_T("answer-after={[0-9]+}"), true); - if (parseStatus == REPARSE_ERROR_OK) { - CAtlREMatchContext<> mc; - if (regex.Match(callInfoValue, &mc) && mc.m_uNumGroups == 1) { - const CAtlREMatchContext<>::RECHAR* szStart = 0; - const CAtlREMatchContext<>::RECHAR* szEnd = 0; - mc.GetMatch(0, &szStart, &szEnd); - ptrdiff_t nLength = szEnd - szStart; - CStringA text(szStart, nLength); - int autoAnswerTimeout = atoi(text); - if (!autoAnswerTimeout) { - autoAnswer = 1; - } - else if (autoAnswerTimeout > 0) { - if (mainDlg->autoAnswerCallId == PJSUA_INVALID_ID) { - noRingDialog = true; - mainDlg->autoAnswerCallId = call_id; - mainDlg->SetTimer(IDT_TIMER_AUTOANSWER, autoAnswerTimeout * 1000, NULL); - } - } - } - } - } - } - } - } - BOOL playBeep = FALSE; - if (autoAnswer && calls_count <= 1) { - mainDlg->AutoAnswer(call_id); - } - else { - if (accountSettings.hidden) { - mainDlg->PostMessage(UM_CALL_HANGUP, (WPARAM)call_id, NULL); - } - else { - if (!noRingDialog) { - //-- - const pj_str_t headerUserAgent = { "User-Agent",10 }; - pjsip_generic_string_hdr *hsr = NULL; - hsr = (pjsip_generic_string_hdr*)pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &headerUserAgent, NULL); - if (hsr) { - user_data->userAgent = PjToStr(&hsr->hvalue, true); - } - //-- - mainDlg->PostMessage(UM_CREATE_RINGING, (WPARAM)call_id, NULL); - } - pjsua_call_answer(call_id, 180, NULL, NULL); - if (call_get_count_noincoming()) { - playBeep = TRUE; - } - else { - if (!accountSettings.ringingSound.GetLength()) { - mainDlg->PostMessage(UM_ON_PLAYER_PLAY, MSIP_SOUND_RINGIN, 0); - } - else { - mainDlg->PostMessage(UM_ON_PLAYER_PLAY, MSIP_SOUND_CUSTOM, (LPARAM)&accountSettings.ringingSound); - } - } - } - } - if (playBeep) { - mainDlg->PostMessage(UM_ON_PLAYER_PLAY, MSIP_SOUND_RINGIN2, 0); - } - } -} - -static void on_nat_detect(const pj_stun_nat_detect_result *res) -{ - if (res->status != PJ_SUCCESS) { - pjsua_perror(THIS_FILE, "NAT detection failed", res->status); - } - else { - if (res->nat_type == PJ_STUN_NAT_TYPE_SYMMETRIC) { - if (IsWindow(mainDlg->m_hWnd)) { - CString message; - pjsua_acc_config acc_cfg; - pj_pool_t *pool; - pool = pjsua_pool_create("acc_cfg-pjsua", 1000, 1000); - if (pool) { - pjsua_acc_id ids[PJSUA_MAX_ACC]; - unsigned count = PJSUA_MAX_ACC; - if (pjsua_enum_accs(ids, &count) == PJ_SUCCESS) { - for (unsigned i = 0; i < count; i++) { - if (pjsua_acc_get_config(ids[i], pool, &acc_cfg) == PJ_SUCCESS) { - acc_cfg.sip_stun_use = PJSUA_STUN_USE_DISABLED; - acc_cfg.media_stun_use = PJSUA_STUN_USE_DISABLED; - if (pjsua_acc_modify(ids[i], &acc_cfg) == PJ_SUCCESS) { - message = _T("STUN was automatically disabled."); - message.Append(_T(" For more info visit MicroSIP website, help page.")); - - } - } - } - } - pj_pool_release(pool); - } - mainDlg->BaloonPopup(_T("Symmetric NAT detected!"), message); - } - } - PJ_LOG(3, (THIS_FILE, "NAT detected as %s", res->nat_type_name)); - } -} - -static void on_buddy_state(pjsua_buddy_id buddy_id) -{ - if (IsWindow(mainDlg->m_hWnd)) { - pjsua_buddy_info buddy_info; - if (pjsua_buddy_get_info(buddy_id, &buddy_info) == PJ_SUCCESS) { - Contact *contact = (Contact *)pjsua_buddy_get_user_data(buddy_id); - if (contact) { - int image; - bool ringing = false; - switch (buddy_info.status) - { - case PJSUA_BUDDY_STATUS_OFFLINE: - image = MSIP_CONTACT_ICON_OFFLINE; - break; - case PJSUA_BUDDY_STATUS_ONLINE: - /* - if (buddy_info.rpid.activity == PJRPID_ACTIVITY_ON_THE_PHONE) { - image = MSIP_CONTACT_ICON_ON_THE_PHONE; - if (PjToStr(&buddy_info.status_text).Left(4) == _T("Ring")) { - ringing = true; - } - } - else*/ - if (buddy_info.rpid.activity == PJRPID_ACTIVITY_AWAY) - { - image = MSIP_CONTACT_ICON_AWAY; - } - else if (buddy_info.rpid.activity == PJRPID_ACTIVITY_BUSY) - { - image = MSIP_CONTACT_ICON_BUSY; - - } - else - { - image = MSIP_CONTACT_ICON_ONLINE; - } - break; - default: - image = MSIP_CONTACT_ICON_UNKNOWN; - break; - } - contact->image = image; - contact->ringing = ringing; - contact->presenceNote = PjToStr(&buddy_info.status_text); - mainDlg->PostMessage(UM_ON_BUDDY_STATE, (WPARAM)contact); - } - } - } -} - -LRESULT CmainDlg::onBuddyState(WPARAM wParam, LPARAM lParam) -{ - Contact *contact = (Contact *)wParam; - CListCtrl *list = (CListCtrl*)pageContacts->GetDlgItem(IDC_CONTACTS); - int n = list->GetItemCount(); - bool found = false; - for (int i = 0; i < n; i++) { - if (contact == (Contact *)list->GetItemData(i)) { - list->SetItem(i, 0, LVIF_IMAGE, 0, contact->image, 0, 0, 0); - list->SetItemText(i, 1, contact->presenceNote); - found = true; - } - } - if (found && contact->ringing) { - OnTimerContactBlink(); - SetTimer(IDT_TIMER_CONTACTS_BLINK, 500, NULL); - } - return 0; -} - -static void on_pager2(pjsua_call_id call_id, const pj_str_t *from, const pj_str_t *to, const pj_str_t *contact, const pj_str_t *mime_type, const pj_str_t *body, pjsip_rx_data *rdata, pjsua_acc_id acc_id) -{ - if (IsWindow(mainDlg->m_hWnd)) { - CString *number = new CString(); - CString *message = new CString(); - number->SetString(PjToStr(from, TRUE)); - message->SetString(PjToStr(body, TRUE)); - message->Trim(); - //-- fix wrong domain - SIPURI sipuri; - ParseSIPURI(*number, &sipuri); - if (accountSettings.accountId && account == acc_id) { - if (IsIP(sipuri.domain)) { - sipuri.domain = accountSettings.account.domain; - } - if (!sipuri.user.IsEmpty()) { - number->Format(_T("%s@%s"), sipuri.user, sipuri.domain); - } - else { - number->SetString(sipuri.domain); - } - } - //-- - mainDlg->PostMessage(UM_ON_PAGER, (WPARAM)number, (LPARAM)message); - } -} - -static void on_pager_status2(pjsua_call_id call_id, const pj_str_t *to, const pj_str_t *body, void *user_data, pjsip_status_code status, const pj_str_t *reason, pjsip_tx_data *tdata, pjsip_rx_data *rdata, pjsua_acc_id acc_id) -{ - if (status != 200) { - if (IsWindow(mainDlg->m_hWnd)) { - CString *number = new CString(); - CString *message = new CString(); - number->SetString(PjToStr(to, TRUE)); - message->SetString(PjToStr(reason, TRUE)); - message->Trim(); - //-- fix wrong domain - SIPURI sipuri; - ParseSIPURI(*number, &sipuri); - if (accountSettings.accountId && account == acc_id) { - if (IsIP(sipuri.domain)) { - sipuri.domain = accountSettings.account.domain; - } - if (!sipuri.user.IsEmpty()) { - number->Format(_T("%s@%s"), sipuri.user, sipuri.domain); - } - else { - number->SetString(sipuri.domain); - } - } - //-- - mainDlg->PostMessage(UM_ON_PAGER_STATUS, (WPARAM)number, (LPARAM)message); - } - } -} - -static void on_call_transfer_status(pjsua_call_id call_id, - int status_code, - const pj_str_t *status_text, - pj_bool_t final, - pj_bool_t *p_cont) -{ - pjsua_call_info *call_info = new pjsua_call_info(); - if (pjsua_call_get_info(call_id, call_info) != PJ_SUCCESS || call_info->state == PJSIP_INV_STATE_NULL) { - return; - } - - call_user_data *user_data = (call_user_data *)pjsua_call_get_user_data(call_info->id); - - CString *str = new CString(); - str->Format(_T("%s: %s"), - Translate(_T("Call Transfer")), - PjToStr(status_text, TRUE) - ); - if (final) { - str->AppendFormat(_T(" [%s]"), Translate(_T("Final"))); - } - - if (status_code / 100 == 2) { - *p_cont = PJ_FALSE; - } - - call_info->last_status = (pjsip_status_code)status_code; - - call_info->call_id.ptr = (char *)user_data; - call_info->call_id.slen = 0; - - PostMessage(mainDlg->m_hWnd, UM_ON_CALL_TRANSFER_STATUS, (WPARAM)call_info, (LPARAM)str); -} - -LRESULT CmainDlg::onCallTransferStatus(WPARAM wParam, LPARAM lParam) -{ - pjsua_call_info *call_info = (pjsua_call_info *)wParam; - call_user_data *user_data = (call_user_data *)call_info->call_id.ptr; - CString *str = (CString *)lParam; - - - MessagesContact* messagesContact = NULL; - CString number = PjToStr(&call_info->remote_info, TRUE); - messagesContact = mainDlg->messagesDlg->AddTab(number, _T(""), FALSE, call_info, user_data, TRUE, TRUE); - if (messagesContact) { - mainDlg->messagesDlg->AddMessage(messagesContact, *str); - } - if (call_info->last_status / 100 == 2) { - if (messagesContact) { - messagesDlg->AddMessage(messagesContact, Translate(_T("Call transfered successfully, disconnecting call"))); - } - msip_call_hangup_fast(call_info->id); - } - delete call_info; - delete str; - return 0; -} - -static void on_call_transfer_request2(pjsua_call_id call_id, const pj_str_t *dst, pjsip_status_code *code, pjsua_call_setting *opt) -{ - SIPURI sipuri; - ParseSIPURI(PjToStr(dst, TRUE), &sipuri); - // display transfer request - pj_bool_t cont; - CString number = sipuri.user; - if (number.IsEmpty()) { - number = sipuri.domain; - } - else if (!accountSettings.accountId || sipuri.domain != accountSettings.account.domain) { - number.Append(_T("@") + sipuri.domain); - } - pj_str_t status_text = StrToPjStr(number); - on_call_transfer_status(call_id, - 0, - &status_text, - PJ_FALSE, - &cont); - //-- - if (!code) { - // if our function call - return; - } - // deny transfer if we already have a call with same dest address - pjsua_call_id call_ids[PJSUA_MAX_CALLS]; - unsigned calls_count = PJSUA_MAX_CALLS; - unsigned calls_count_cmp = 0; - if (pjsua_enum_calls(call_ids, &calls_count) == PJ_SUCCESS) { - for (unsigned i = 0; i < calls_count; ++i) { - pjsua_call_info call_info_curr; - if (pjsua_call_get_info(call_ids[i], &call_info_curr) == PJ_SUCCESS) { - SIPURI sipuri_curr; - ParseSIPURI(PjToStr(&call_info_curr.remote_info, TRUE), &sipuri_curr); - if (sipuri.user + _T("@") + sipuri.domain == sipuri_curr.user + _T("@") + sipuri_curr.domain - ) { - *code = PJSIP_SC_DECLINE; - break; - } - } - } - } -} - -static void on_call_replace_request2(pjsua_call_id call_id, pjsip_rx_data *rdata, int *st_code, pj_str_t *st_text, pjsua_call_setting *opt) -{ - pjsua_call_info call_info; - if (pjsua_call_get_info(call_id, &call_info) == PJ_SUCCESS) { - if (!call_info.rem_vid_cnt) { - opt->vid_cnt = 0; - } - } - else { - opt->vid_cnt = 0; - } -} - -static void on_call_replaced(pjsua_call_id old_call_id, pjsua_call_id new_call_id) -{ - pjsua_call_info call_info; - if (pjsua_call_get_info(new_call_id, &call_info) == PJ_SUCCESS) { - on_call_transfer_request2(old_call_id, &call_info.remote_info, NULL, NULL); - } -} - -static void on_mwi_info(pjsua_acc_id acc_id, pjsua_mwi_info *mwi_info) -{ - if (mwi_info->rdata->msg_info.ctype) { - const pjsip_ctype_hdr *ctype = mwi_info->rdata->msg_info.ctype; - if (pj_strcmp2(&ctype->media.type, "application") != 0 || pj_strcmp2(&ctype->media.subtype, "simple-message-summary") != 0) { - return; - } - } - if (!mwi_info->rdata->msg_info.msg->body || !mwi_info->rdata->msg_info.msg->body->len) { - return; - } - pjsip_msg_body *body = mwi_info->rdata->msg_info.msg->body; - pj_scanner scanner; - - pj_scan_init(&scanner, (char*)body->data, body->len, PJ_SCAN_AUTOSKIP_WS, 0); - bool hasMail = false; - while (!pj_scan_is_eof(&scanner)) { - pj_str_t key; - pj_scan_get_until_chr(&scanner, ":", &key); - pj_strtrim(&key); - if (key.slen && !pj_scan_is_eof(&scanner)) { - scanner.curptr++; - pj_str_t value; - pj_scan_get_until_chr(&scanner, "\r\n", &value); - pj_strtrim(&value); - if (pj_stricmp2(&key, "Messages-Waiting") == 0) { - hasMail = pj_stricmp2(&value, "yes") == 0; - break; - } - } - } - pj_scan_fini(&scanner); - PostMessage(mainDlg->m_hWnd, UM_ON_MWI_INFO, (WPARAM)hasMail, 0); -} - -LRESULT CmainDlg::onMWIInfo(WPARAM wParam, LPARAM lParam) -{ - bool hasMail = (bool)wParam; - pageDialer->UpdateVoicemailButton(hasMail); - return 0; -} - -static void on_dtmf_digit(pjsua_call_id call_id, int digit) -{ - char signal[2]; - signal[0] = digit; - signal[1] = 0; - call_play_digit(-1, signal); -} - -static void on_call_tsx_state(pjsua_call_id call_id, pjsip_transaction *tsx, pjsip_event *e) -{ - const pjsip_method info_method = { - PJSIP_OTHER_METHOD, - { "INFO", 4 } - }; - if (pjsip_method_cmp(&tsx->method, &info_method) == 0) { - /* - * Handle INFO method. - */ - if (tsx->role == PJSIP_ROLE_UAS && tsx->state == PJSIP_TSX_STATE_TRYING) { - if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) { - pjsip_rx_data *rdata = e->body.tsx_state.src.rdata; - pjsip_msg_body *body = rdata->msg_info.msg->body; - int code = 0; - if (body && body->len - && pj_strcmp2(&body->content_type.type, "application") == 0 - && pj_strcmp2(&body->content_type.subtype, "dtmf-relay") == 0) { - code = 400; - pj_scanner scanner; - pj_scan_init(&scanner, (char*)body->data, body->len, PJ_SCAN_AUTOSKIP_WS, 0); - char digit; - int duration = 250; - while (!pj_scan_is_eof(&scanner)) { - pj_str_t key; - pj_scan_get_until_chr(&scanner, "=", &key); - pj_strtrim(&key); - if (key.slen && !pj_scan_is_eof(&scanner)) { - scanner.curptr++; - pj_str_t value; - pj_scan_get_until_chr(&scanner, "\r\n", &value); - pj_strtrim(&value); - if (pj_stricmp2(&key, "Signal") == 0) { - if (value.slen == 1) { - digit = *value.ptr; - code = 200; - } - } - else if (pj_stricmp2(&key, "Duration") == 0) { - int res = 0; - for (int i = 0; i < (unsigned)value.slen; ++i) { - res = res * 10 + (value.ptr[i] - '0'); - res = res; - } - if (res >= 100 || res <= 5000) { - duration = res; - } - } - } - } - pj_scan_fini(&scanner); - if (code == 200) { - on_dtmf_digit(-1, digit); - } - } - else if (!body || !body->len) { - /* 200/OK */ - code = 200; - } - if (code) { - /* Answer incoming INFO */ - pjsip_tx_data *tdata; - if (pjsip_endpt_create_response(tsx->endpt, rdata, - code, NULL, &tdata) == PJ_SUCCESS - ) { - pjsip_tsx_send_msg(tsx, tdata); - } - } - } - } - } - else { - if (tsx->state == PJSIP_TSX_STATE_COMPLETED) { - // display declined REFER status - const pjsip_method refer_method = { - PJSIP_OTHER_METHOD, - { "REFER", 5 } - }; - if (pjsip_method_cmp(&tsx->method, &refer_method) == 0 && tsx->status_code / 100 != 2) { - pj_bool_t cont; - on_call_transfer_status(call_id, - tsx->status_code, - &tsx->status_text, - PJ_FALSE, - &cont); - } - } - } -} - -CmainDlg::~CmainDlg(void) -{ -} - -void CmainDlg::OnDestroy() -{ - if (mmNotificationClient) { - delete mmNotificationClient; - } - WTSUnRegisterSessionNotification(m_hWnd); - - PJDestroy(); - - accountSettings.SettingsSave(); - - RemoveJumpList(); - if (tnd.hWnd) { - Shell_NotifyIcon(NIM_DELETE, &tnd); - } - UnloadLangPackModule(); - - CBaseDialog::OnDestroy(); -} - -void CmainDlg::PostNcDestroy() -{ - CBaseDialog::PostNcDestroy(); - delete this; -} - -void CmainDlg::DoDataExchange(CDataExchange* pDX) -{ - CBaseDialog::DoDataExchange(pDX); - // DDX_Control(pDX, IDD_MAIN, *mainDlg); - DDX_Control(pDX, IDC_MAIN_MENU, m_ButtonMenu); -} - -BEGIN_MESSAGE_MAP(CmainDlg, CBaseDialog) - ON_WM_CREATE() - ON_WM_SYSCOMMAND() - ON_WM_QUERYENDSESSION() - ON_WM_TIMER() - ON_WM_MOVE() - ON_WM_SIZE() - ON_WM_CLOSE() - ON_WM_CONTEXTMENU() - ON_WM_DEVICECHANGE() - ON_WM_WTSSESSION_CHANGE() - ON_WM_DESTROY() - ON_BN_CLICKED(IDOK, OnBnClickedOk) - ON_BN_CLICKED(IDC_MAIN_MENU, OnBnClickedMenu) - ON_MESSAGE(UM_UPDATEWINDOWTEXT, OnUpdateWindowText) - ON_MESSAGE(UM_NOTIFYICON, onTrayNotify) - ON_MESSAGE(UM_CREATE_RINGING, onCreateRingingDlg) - ON_MESSAGE(UM_REFRESH_LEVELS, onRefreshLevels) - ON_MESSAGE(UM_ON_REG_STATE2, onRegState2) - ON_MESSAGE(UM_ON_CALL_STATE, onCallState) - ON_MESSAGE(UM_ON_MWI_INFO, onMWIInfo) - ON_MESSAGE(UM_ON_CALL_MEDIA_STATE, onCallMediaState) - ON_MESSAGE(UM_ON_CALL_TRANSFER_STATUS, onCallTransferStatus) - ON_MESSAGE(UM_ON_PLAYER_PLAY, onPlayerPlay) - ON_MESSAGE(UM_ON_PLAYER_STOP, onPlayerStop) - ON_MESSAGE(UM_ON_PAGER, onPager) - ON_MESSAGE(UM_ON_PAGER_STATUS, onPagerStatus) - ON_MESSAGE(UM_ON_BUDDY_STATE, onBuddyState) - ON_MESSAGE(UM_USERS_DIRECTORY, onUsersDirectoryLoaded) - ON_MESSAGE(WM_POWERBROADCAST, onPowerBroadcast) - ON_MESSAGE(WM_COPYDATA, onCopyData) - ON_MESSAGE(UM_CALL_ANSWER, onCallAnswer) - ON_MESSAGE(UM_CALL_HANGUP, onCallHangup) - ON_MESSAGE(UM_TAB_ICON_UPDATE, onTabIconUpdate) - ON_MESSAGE(UM_SET_PANE_TEXT, onSetPaneText) - ON_MESSAGE(UM_ON_ACCOUNT, OnAccount) - ON_COMMAND(ID_ACCOUNT_ADD, OnMenuAccountAdd) - ON_COMMAND_RANGE(ID_ACCOUNT_CHANGE_RANGE, ID_ACCOUNT_CHANGE_RANGE + 99, OnMenuAccountChange) - ON_COMMAND_RANGE(ID_ACCOUNT_EDIT_RANGE, ID_ACCOUNT_EDIT_RANGE + 99, OnMenuAccountEdit) - ON_COMMAND_RANGE(ID_CUSTOM_RANGE, ID_CUSTOM_RANGE + 99, OnMenuCustomRange) - ON_COMMAND(ID_SETTINGS, OnMenuSettings) - ON_COMMAND(ID_SHORTCUTS, OnMenuShortcuts) - ON_COMMAND(ID_ALWAYS_ON_TOP, OnMenuAlwaysOnTop) - ON_COMMAND(ID_LOG, OnMenuLog) - ON_COMMAND(ID_EXIT, OnMenuExit) - ON_NOTIFY(TCN_SELCHANGE, IDC_MAIN_TAB, &CmainDlg::OnTcnSelchangeTab) - ON_NOTIFY(TCN_SELCHANGING, IDC_MAIN_TAB, &CmainDlg::OnTcnSelchangingTab) - ON_COMMAND(ID_MENU_WEBSITE, OnMenuWebsite) - ON_COMMAND(ID_MENU_HELP, OnMenuHelp) - ON_COMMAND(ID_MENU_ADDL, OnMenuAddl) -END_MESSAGE_MAP() - - -BOOL CmainDlg::PreTranslateMessage(MSG* pMsg) -{ - if (accountSettings.enableMediaButtons) { - if (pMsg->message == WM_SHELLHOOKMESSAGE) { - onShellHookMessage(pMsg->wParam, pMsg->lParam); - } - } - return CBaseDialog::PreTranslateMessage(pMsg); -} - -// CmainDlg message handlers - -void CmainDlg::OnBnClickedOk() -{ -} - -void CmainDlg::OnBnClickedMenu() -{ - m_ButtonMenu.ModifyStyle(BS_DEFPUSHBUTTON, BS_PUSHBUTTON); - MainPopupMenu(); - TabFocusSet(); -} - -CmainDlg::CmainDlg(CWnd* pParent /*=NULL*/) - : CBaseDialog(CmainDlg::IDD, pParent) -{ -#ifdef _DEBUG - if (AllocConsole()) { - HANDLE console = NULL; - console = GetStdHandle(STD_OUTPUT_HANDLE); - freopen("CONOUT$", "wt", stdout); - } -#endif - - this->m_hWnd = NULL; - mmNotificationClient = NULL; - - mainDlg = this; - widthAdd = 0; - heightAdd = 0; - - m_tabPrev = -1; - newMessages = false; - missed = false; - - CString audioCodecsCaptions = _T("opus/48000/2;Opus 24 kHz;\ -PCMA/8000/1;G.711 A-law;\ -PCMU/8000/1;G.711 u-law;\ -G722/16000/1;G.722 16 kHz;\ -G723/8000/1;G.723 8 kHz;\ -G729/8000/1;G.729 8 kHz;\ -GSM/8000/1;GSM 8 kHz;\ -GSM-EFR/8000/1;GSM-EFR 8 kHz;\ -AMR/8000/1;AMR 8 kHz;\ -AMR-WB/16000/1;AMR-WB 16 kHz;\ -iLBC/8000/1;iLBC 8 kHz;\ -speex/32000/1;Speex 32 kHz;\ -speex/16000/1;Speex 16 kHz;\ -speex/8000/1;Speex 8 kHz;\ -SILK/24000/1;SILK 24 kHz;\ -SILK/16000/1;SILK 16 kHz;\ -SILK/12000/1;SILK 12 kHz;\ -SILK/8000/1;SILK 8 kHz;\ -L16/44100/1;LPCM 44 kHz;\ -L16/44100/2;LPCM 44 kHz Stereo"); - int pos = 0; - CString resToken = audioCodecsCaptions.Tokenize(_T(";"), pos); - while (!resToken.IsEmpty()) { - audioCodecList.AddTail(resToken); - resToken = audioCodecsCaptions.Tokenize(_T(";"), pos); - } - - wchar_t szBuf[STR_SZ]; - wchar_t szLocale[STR_SZ]; - ::GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SENGLANGUAGE, szBuf, STR_SZ); - _tcscpy(szLocale, szBuf); - ::GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SENGCOUNTRY, szBuf, STR_SZ); - if (_tcsclen(szBuf) != 0) { - _tcscat(szLocale, _T("_")); - _tcscat(szLocale, szBuf); - } - ::GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE, szBuf, STR_SZ); - if (_tcsclen(szBuf) != 0) { - _tcscat(szLocale, _T(".")); - _tcscat(szLocale, szBuf); - } - _tsetlocale(LC_ALL, szLocale); // e.g. szLocale = "English_United States.1252" - - LoadLangPackModule(); - - Create(IDD, pParent); -} - -int CmainDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - - ShortcutsLoad(); - shortcutsEnabled = accountSettings.enableShortcuts; - shortcutsBottom = accountSettings.shortcutsBottom; - if (accountSettings.enableShortcuts) { - if (shortcutsBottom) { - heightAdd += 10 + shortcuts.GetCount() * 25; - } - else { - widthAdd += 140; - } - } - int heightFix = 0; - if (widthAdd || heightAdd || heightFix) { - SetWindowPos(NULL, 0, 0, lpCreateStruct->cx + widthAdd, lpCreateStruct->cy + heightAdd + heightFix, SWP_NOMOVE | SWP_NOZORDER); - } - - if (accountSettings.noResize) { - ModifyStyle(WS_MAXIMIZEBOX | WS_THICKFRAME, WS_BORDER); - } - - if (langPack.rtl) { - ModifyStyleEx(0, WS_EX_LAYOUTRTL); - } - - return CBaseDialog::OnCreate(lpCreateStruct); -} - -BOOL CmainDlg::OnInitDialog() -{ - CBaseDialog::OnInitDialog(); - - if (lstrcmp(theApp.m_lpCmdLine, _T("/hidden")) == 0) { - accountSettings.hidden = TRUE; - theApp.m_lpCmdLine = NULL; - } - - WTSRegisterSessionNotification(m_hWnd, NOTIFY_FOR_THIS_SESSION); - mmNotificationClient = new CMMNotificationClient(); - - pj_ready = false; - - autoAnswerCallId = PJSUA_INVALID_ID; - - settingsDlg = NULL; - shortcutsDlg = NULL; - messagesDlg = new MessagesDlg(this); - transferDlg = NULL; - accountDlg = NULL; - - m_lastInputTime = 0; - m_idleCounter = 0; - m_PresenceStatus = PJRPID_ACTIVITY_UNKNOWN; - -#ifdef _GLOBAL_VIDEO - previewWin = NULL; -#endif - - if (!accountSettings.hidden) { - - SetupJumpList(); - - m_hIcon = theApp.LoadIcon(IDR_MAINFRAME); - iconSmall = (HICON)LoadImage( - AfxGetInstanceHandle(), - MAKEINTRESOURCE(IDR_MAINFRAME), - IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); - PostMessage(WM_SETICON, ICON_SMALL, (LPARAM)iconSmall); - - TranslateDialog(this->m_hWnd); - - // Set the icon for this dialog. The framework does this automatically - // when the application's main window is not a dialog - SetIcon(m_hIcon, TRUE); // Set big icon - SetIcon(m_hIcon, FALSE); // Set small icon - - // TODO: Add extra initialization here - - // add tray icon - CString str; - str.Format(_T("%s %s"), _T(_GLOBAL_NAME_NICE), _T(_GLOBAL_VERSION)); - tnd.cbSize = sizeof(NOTIFYICONDATA); - tnd.hWnd = this->GetSafeHwnd(); - tnd.uID = IDR_MAINFRAME; - tnd.uCallbackMessage = UM_NOTIFYICON; - tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; - iconMissed = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_MISSED)); - iconInactive = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_INACTIVE)); - tnd.hIcon = iconInactive; - lstrcpyn(tnd.szTip, (LPCTSTR)str, sizeof(tnd.szTip)); - DWORD dwMessage = NIM_ADD; - Shell_NotifyIcon(dwMessage, &tnd); - } - else { - tnd.hWnd = NULL; - } - - m_bar.Create(this); - m_bar.SetIndicators(indicators, sizeof(indicators) / sizeof(indicators[0])); - m_bar.SetPaneInfo(0, IDS_STATUSBAR, SBPS_STRETCH, 0); - m_bar.SetPaneInfo(1, IDS_STATUSBAR2, SBPS_NOBORDERS, 0); - RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, IDS_STATUSBAR); - - AutoMove(m_bar.m_hWnd, 0, 100, 100, 0); - - //--set window pos - CRect screenRect; - GetScreenRect(&screenRect); - CRect rect; - GetWindowRect(&rect); - - windowSize.x = rect.Width(); - windowSize.y = rect.Height(); - - int mx; - int my; - int mW = accountSettings.mainW > 0 ? accountSettings.mainW : rect.Width(); - int mH = accountSettings.mainH > 0 ? accountSettings.mainH : rect.Height(); - // coors not specified, first run - if (!accountSettings.mainX && !accountSettings.mainY) { - CRect primaryScreenRect; - SystemParametersInfo(SPI_GETWORKAREA, 0, &primaryScreenRect, 0); - mx = primaryScreenRect.Width() - mW - widthAdd; - my = primaryScreenRect.Height() - mH; - } - else { - int maxLeft = screenRect.right - mW; - if (accountSettings.mainX > maxLeft) { - mx = maxLeft; - } - else { - mx = accountSettings.mainX < screenRect.left ? screenRect.left : accountSettings.mainX; - } - int maxTop = screenRect.bottom - mH; - if (accountSettings.mainY > maxTop) { - my = maxTop; - } - else { - my = accountSettings.mainY < screenRect.top ? screenRect.top : accountSettings.mainY; - } - } - - //--set messages window pos/size - messagesDlg->GetWindowRect(&rect); - int messagesX; - int messagesY; - int messagesW = accountSettings.messagesW > 0 ? accountSettings.messagesW : 550; - int messagesH = accountSettings.messagesH > 0 ? accountSettings.messagesH : mH; - // coors not specified, first run - if (!accountSettings.messagesX && !accountSettings.messagesY) { - accountSettings.messagesX = mx - messagesW; - accountSettings.messagesY = my; - } - int maxLeft = screenRect.right - messagesW; - if (accountSettings.messagesX > maxLeft) { - messagesX = maxLeft; - } - else { - messagesX = accountSettings.messagesX < screenRect.left ? screenRect.left : accountSettings.messagesX; - } - int maxTop = screenRect.bottom - messagesH; - if (accountSettings.messagesY > maxTop) { - messagesY = maxTop; - } - else { - messagesY = accountSettings.messagesY < screenRect.top ? screenRect.top : accountSettings.messagesY; - } - - messagesDlg->SetWindowPos(NULL, messagesX, messagesY, messagesW, messagesH, SWP_NOZORDER); - - SetWindowPos(accountSettings.alwaysOnTop ? &CWnd::wndTopMost : &CWnd::wndNoTopMost, mx, my, mW, mH, NULL); - - CTabCtrl* tab = (CTabCtrl*)GetDlgItem(IDC_MAIN_TAB); - CRect tabRect; - tab->GetWindowRect(&tabRect); - ScreenToClient(&tabRect); - TC_ITEM tabItem; - CRect lineRect; - lineRect.bottom = 3; - MapDialogRect(&lineRect); - CSize size; - size.SetSize(0, tabRect.Height() - lineRect.bottom - 3); - tab->SetItemSize(size); - - tabItem.mask = TCIF_TEXT | TCIF_PARAM; - - m_ButtonMenu.SetIcon(LoadImageIcon(IDI_DROPDOWN)); - - if (widthAdd) { - CRect pageRect; - m_ButtonMenu.GetWindowRect(pageRect); - ScreenToClient(pageRect); - m_ButtonMenu.SetWindowPos(NULL, pageRect.left + widthAdd, pageRect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE); - //-- - tabRect.right += widthAdd; - tab->SetWindowPos(NULL, 0, 0, tabRect.Width(), tabRect.Height(), SWP_NOZORDER | SWP_NOMOVE); - } - - AutoMove(tab->m_hWnd, 0, 0, 100, 0); - AutoMove(m_ButtonMenu.m_hWnd, 100, 0, 0, 0); - - BYTE offset = tabRect.bottom - 1; - - pageDialer = new Dialer(this); - tabItem.pszText = Translate(_T("Phone")); - tabItem.iImage = 0; - tabItem.lParam = (LPARAM)pageDialer; - tab->InsertItem(99, &tabItem); - pageDialer->SetWindowPos(NULL, 0, offset, 0, 0, SWP_NOSIZE | SWP_NOZORDER); - AutoMove(pageDialer->m_hWnd, 40, 40, 20, 20); - - CRect pageRect; - pageCalls = new Calls(this); - pageCalls->OnCreated(); - tabItem.pszText = Translate(_T("Logs")); - tabItem.iImage = 1; - tabItem.lParam = (LPARAM)pageCalls; - tab->InsertItem(99, &tabItem); - pageCalls->GetWindowRect(pageRect); - pageCalls->SetWindowPos(NULL, 0, offset, pageRect.Width() + widthAdd, pageRect.Height() + heightAdd, SWP_NOZORDER); - AutoMove(pageCalls->m_hWnd, 0, 0, 100, 100); - - pageContacts = new Contacts(this); - pageContacts->OnCreated(); - tabItem.pszText = Translate(_T("Contacts")); - tabItem.iImage = 2; - tabItem.lParam = (LPARAM)pageContacts; - tab->InsertItem(99, &tabItem); - pageContacts->GetWindowRect(pageRect); - pageContacts->SetWindowPos(NULL, 0, offset, pageRect.Width() + widthAdd, pageRect.Height() + heightAdd, SWP_NOZORDER); - AutoMove(pageContacts->m_hWnd, 0, 0, 100, 100); - - - tab->SetCurSel(accountSettings.activeTab); - - BOOL minimized = !lstrcmp(theApp.m_lpCmdLine, _T("/minimized")); - if (minimized) { - theApp.m_lpCmdLine = _T(""); - } - if (accountSettings.silent) { - minimized = true; - } - - m_startMinimized = (!firstRun && minimized) || accountSettings.hidden; - - SetWindowText(_T(_GLOBAL_NAME_NICE)); - UpdateWindowText(); - return TRUE; // return TRUE unless you set the focus to a control -} - -void CmainDlg::OnCreated() -{ - SetPaneText2(); - if (!m_startMinimized) { - ShowWindow(SW_SHOW); - } - TabFocusSet(); - - //-- PJSIP create - while (!pj_ready) { - PJCreate(); - if (pj_ready) { - break; - } - if (AfxMessageBox(_T("Unable to initialize network sockets."), MB_RETRYCANCEL | MB_ICONEXCLAMATION) != IDRETRY) { - DestroyWindow(); - return; - } - } - if (lstrlen(theApp.m_lpCmdLine)) { - CommandLine(theApp.m_lpCmdLine); - theApp.m_lpCmdLine = NULL; - } - PJAccountAdd(); - //-- - WM_SHELLHOOKMESSAGE = RegisterWindowMessage(_T("SHELLHOOK")); - if (WM_SHELLHOOKMESSAGE) { - RegisterShellHookWindow(m_hWnd); - } -} - -void CmainDlg::BaloonPopup(CString title, CString message, DWORD flags) -{ - if (tnd.hWnd) { - lstrcpyn(tnd.szInfo, message, sizeof(tnd.szInfo)); - lstrcpyn(tnd.szInfoTitle, title, sizeof(tnd.szInfoTitle)); - tnd.uFlags = tnd.uFlags | NIF_INFO; - tnd.dwInfoFlags = flags; - DWORD dwMessage = NIM_MODIFY; - Shell_NotifyIcon(dwMessage, &tnd); - } -} - -void CmainDlg::OnMenuAccountAdd() -{ - if (!accountSettings.hidden) { - if (!accountDlg) { - accountDlg = new AccountDlg(this); - } - else { - accountDlg->SetForegroundWindow(); - } - accountDlg->Load(0); - } -} -void CmainDlg::OnMenuAccountChange(UINT nID) -{ - if (accountSettings.accountId) { - PJAccountDelete(true); - } - int idNew = nID - ID_ACCOUNT_CHANGE_RANGE + 1; - if (accountSettings.accountId != idNew) { - accountSettings.accountId = idNew; - accountSettings.AccountLoad(accountSettings.accountId, &accountSettings.account); - } - else { - accountSettings.accountId = 0; - } - accountSettings.SettingsSave(); - mainDlg->PJAccountAdd(); -} - -void CmainDlg::OnMenuAccountEdit(UINT nID) -{ - if (!accountDlg) { - accountDlg = new AccountDlg(this); - } - else { - accountDlg->SetForegroundWindow(); - } - int id = accountSettings.accountId > 0 ? accountSettings.accountId : nID - ID_ACCOUNT_EDIT_RANGE + 1; - accountDlg->Load(id); -} - -void CmainDlg::OnMenuCustomRange(UINT nID) -{ -} - -void CmainDlg::OnMenuSettings() -{ - if (!accountSettings.hidden) { - if (!settingsDlg) - { - settingsDlg = new SettingsDlg(this); - } - else { - settingsDlg->SetForegroundWindow(); - } - } -} - -void CmainDlg::OnMenuShortcuts() -{ - if (!shortcutsDlg) - { - shortcutsDlg = new ShortcutsDlg(this); - } - else { - shortcutsDlg->SetForegroundWindow(); - } -} - -void CmainDlg::OnMenuAlwaysOnTop() -{ - accountSettings.alwaysOnTop = 1 - accountSettings.alwaysOnTop; - AccountSettingsPendingSave(); - SetWindowPos(accountSettings.alwaysOnTop ? &this->wndTopMost : &this->wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); -} - -void CmainDlg::OnMenuLog() -{ - ShellExecute(NULL, NULL, accountSettings.logFile, NULL, NULL, SW_SHOWNORMAL); -} - -void CmainDlg::OnMenuExit() -{ - this->DestroyWindow(); -} - -LRESULT CmainDlg::onTrayNotify(WPARAM wParam, LPARAM lParam) -{ - UINT uMsg = (UINT)lParam; - switch (uMsg) - { - case NIN_BALLOONUSERCLICK: - onTrayNotify(NULL, WM_LBUTTONUP); - break; - case WM_LBUTTONUP: - if (this->IsWindowVisible() && !IsIconic()) - { - if (wParam) { - ShowWindow(SW_HIDE); - } - else { - SetForegroundWindow(); - } - } - else - { - bool blockRestore = false; - if (accountSettings.hidden) { - blockRestore = true; - } - if (!blockRestore) { - if (IsIconic()) { - ShowWindow(SW_RESTORE); - } - else { - ShowWindow(SW_SHOW); - } - SetForegroundWindow(); - if (missed) { - GotoTabLParam((LPARAM)pageCalls); - missed = false; - UpdateWindowText(); - } - // -- show ringing dialogs - int count = ringinDlgs.GetCount(); - for (int i = 0; i < count; i++) { - RinginDlg *ringinDlg = ringinDlgs.GetAt(i); - ringinDlg->ShowWindow(SW_SHOWNORMAL); - } - // -- show messages dialog - if (accountSettings.silent && ((!accountSettings.singleMode && call_get_count_noincoming()) || newMessages)) { - newMessages = false; - messagesDlg->ShowWindow(SW_SHOW); - } - //-- - TabFocusSet(); - } - } - break; - case WM_RBUTTONUP: - MainPopupMenu(); - break; - } - return TRUE; -} - -void CmainDlg::MainPopupMenu() -{ - CString str; - CPoint point; - GetCursorPos(&point); - CMenu menu; - menu.CreatePopupMenu(); - CMenu* tracker = &menu; - - // -- add - tracker->AppendMenu(MF_STRING, ID_ACCOUNT_ADD, Translate(_T("Add Account..."))); - //-- edit - CMenu editMenu; - editMenu.CreatePopupMenu(); - Account acc; - int i = 0; - bool checked = false; - while (true) { - if (!accountSettings.AccountLoad(i + 1, &acc)) { - break; - } - - if (!acc.label.IsEmpty()) { - str = acc.label; - } - else { - str.Format(_T("%s@%s"), acc.username, acc.domain); - } - tracker->InsertMenu(ID_ACCOUNT_ADD, (accountSettings.accountId == i + 1 ? MF_CHECKED : 0), ID_ACCOUNT_CHANGE_RANGE + i, str); - editMenu.AppendMenu(MF_STRING, ID_ACCOUNT_EDIT_RANGE + i, str); - if (!checked) { - checked = accountSettings.accountId == i + 1; - } - i++; - } - str = Translate(_T("Edit Account")); - str.Append(_T("\tCtrl+M")); - if (i == 1) { - MENUITEMINFO menuItemInfo; - menuItemInfo.cbSize = sizeof(MENUITEMINFO); - menuItemInfo.fMask = MIIM_STRING; - menuItemInfo.dwTypeData = Translate(_T("Make Active")); - tracker->SetMenuItemInfo(ID_ACCOUNT_CHANGE_RANGE, &menuItemInfo); - tracker->InsertMenu(ID_ACCOUNT_ADD, 0, ID_ACCOUNT_EDIT_RANGE, str); - } - else if (i > 1) { - tracker->InsertMenu(ID_ACCOUNT_ADD, MF_SEPARATOR); - if (checked) { - tracker->InsertMenu(ID_ACCOUNT_ADD, 0, ID_ACCOUNT_EDIT_RANGE, str); - } - else { - tracker->InsertMenu(ID_ACCOUNT_ADD, MF_POPUP, (UINT_PTR)editMenu.m_hMenu, Translate(_T("Edit Account"))); - } - } - - str = Translate(_T("Settings")); - str.Append(_T("\tCtrl+P")); - tracker->AppendMenu(MF_STRING, ID_SETTINGS, str); - tracker->AppendMenu(MF_SEPARATOR); - str = Translate(_T("Shortcuts")); - str.Append(_T("\tCtrl+S")); - tracker->AppendMenu(MF_STRING, ID_SHORTCUTS, str); - - bool separator = false; - if (!separator) { - tracker->AppendMenu(MF_SEPARATOR); - separator = true; - } - tracker->AppendMenu(MF_STRING | (accountSettings.alwaysOnTop ? MF_CHECKED : 0), ID_ALWAYS_ON_TOP, Translate(_T("Always on Top"))); - if (!separator) { - tracker->AppendMenu(MF_SEPARATOR); - separator = true; - } - tracker->AppendMenu(MF_STRING | (!accountSettings.enableLog ? MF_DISABLED | MF_GRAYED : 0), ID_LOG, Translate(_T("View Log File"))); - - separator = false; - - if (!separator) { - tracker->AppendMenu(MF_SEPARATOR); - separator = true; - } - str = Translate(_T("Visit Website")); - str.Append(_T("\tCtrl+W")); - tracker->AppendMenu(MF_STRING, ID_MENU_WEBSITE, str); - - if (!separator) { - tracker->AppendMenu(MF_SEPARATOR); - separator = true; - } - tracker->AppendMenu(MF_STRING, ID_MENU_HELP, Translate(_T("Help"))); - - tracker->AppendMenu(MF_SEPARATOR); - str = Translate(_T("Exit")); - str.Append(_T("\tCtrl+Q")); - tracker->AppendMenu(MF_STRING, ID_EXIT, str); - - SetForegroundWindow(); - tracker->TrackPopupMenu(0, point.x, point.y, this); - PostMessage(WM_NULL, 0, 0); -} - -LRESULT CmainDlg::onCreateRingingDlg(WPARAM wParam, LPARAM lParam) -{ - pjsua_call_id call_id = wParam; - pjsua_call_info call_info; - - if (pjsua_var.state != PJSUA_STATE_RUNNING || pjsua_call_get_info(call_id, &call_info) != PJ_SUCCESS) { - return 0; - } - - call_user_data *user_data = (call_user_data *)pjsua_call_get_user_data(call_info.id); - - RinginDlg* ringinDlg = new RinginDlg(this); - - ringinDlg->remoteHasVideo = call_info.rem_vid_cnt; - if (call_info.rem_vid_cnt) { - ((CButton*)ringinDlg->GetDlgItem(IDC_VIDEO))->EnableWindow(TRUE); - } - - ringinDlg->call_id = call_info.id; - SIPURI sipuri; - CStringW rab; - CString str; - CString info; - - info = PjToStr(&call_info.remote_info, TRUE); - - ParseSIPURI(info, &sipuri); - - CString name = pageContacts->GetNameByNumber(GetSIPURI(sipuri.user, true)); - if (name.IsEmpty()) { - name = !sipuri.name.IsEmpty() ? sipuri.name : (!sipuri.user.IsEmpty() ? sipuri.user : sipuri.domain); - } - if (user_data && !user_data->diversion.IsEmpty()) { - name.Format(_T("%s -> %s"), user_data->diversion, name); - } - ringinDlg->GetDlgItem(IDC_CALLER_NAME)->SetWindowText(name); - - int c = 0; - int len = 0; - - info = (!sipuri.user.IsEmpty() ? sipuri.user + _T("@") : _T("")) + sipuri.domain; - if (!sipuri.name.IsEmpty() && sipuri.name != name) { - info = sipuri.name + _T(" <") + info + _T(">"); - } - len += info.GetLength(); - str.Format(_T("%s\r\n\r\n"), info); - - info = PjToStr(&call_info.local_info, TRUE); - ParseSIPURI(info, &sipuri); - info = (!sipuri.user.IsEmpty() ? sipuri.user + _T("@") : _T("")) + sipuri.domain; - len += info.GetLength(); - str.AppendFormat(_T("%s: %s\r\n\r\n"), Translate(_T("To")), info); - - if (len < 70) { - c++; - } - - if (user_data && !user_data->userAgent.IsEmpty()) { - str.AppendFormat(_T("%s: %s"), Translate(_T("User-Agent")), user_data->userAgent); - } - else { - c++; - } - - for (int i = 0; i < c; i++) { - str = _T("\r\n") + str; - } - - - if (str != name) { - ringinDlg->GetDlgItem(IDC_CALLER_ADDR)->SetWindowText(str); - } - else { - ringinDlg->GetDlgItem(IDC_CALLER_ADDR)->EnableWindow(FALSE); - } - ringinDlgs.Add(ringinDlg); - if (!accountSettings.bringToFrontOnIncoming) { - if (GetForegroundWindow()->GetTopLevelParent() != this) { - BaloonPopup(Translate(_T("Incoming Call")), name, NIIF_INFO); - } - } - return 0; -} - -LRESULT CmainDlg::onRefreshLevels(WPARAM wParam, LPARAM lParam) -{ - pageDialer->OnHScroll(0, 0, NULL); - return 0; -} - -LRESULT CmainDlg::onPager(WPARAM wParam, LPARAM lParam) -{ - CString *number = (CString *)wParam; - CString *message = (CString *)lParam; - bool doNotShowMessagesWindow = accountSettings.silent && !mainDlg->IsWindowVisible(); - if (doNotShowMessagesWindow) { - newMessages = true; - } - MessagesContact* messagesContact = messagesDlg->AddTab(*number, - CString(), FALSE, NULL, NULL, - doNotShowMessagesWindow - ); - if (messagesContact) { - messagesDlg->AddMessage(messagesContact, *message, MSIP_MESSAGE_TYPE_REMOTE); - onPlayerPlay(MSIP_SOUND_MESSAGE_IN, 0); - } - delete number; - delete message; - return 0; -} - -LRESULT CmainDlg::onPagerStatus(WPARAM wParam, LPARAM lParam) -{ - CString *number = (CString *)wParam; - CString *message = (CString *)lParam; - bool doNotShowMessagesWindow = accountSettings.silent && !mainDlg->IsWindowVisible(); - MessagesContact* messagesContact = mainDlg->messagesDlg->AddTab(*number, - CString(), FALSE, NULL, NULL, - doNotShowMessagesWindow); - if (messagesContact) { - mainDlg->messagesDlg->AddMessage(messagesContact, *message); - } - delete number; - delete message; - return 0; -} - -LRESULT CmainDlg::onPowerBroadcast(WPARAM wParam, LPARAM lParam) -{ - if (wParam == PBT_APMRESUMEAUTOMATIC) { - PJAccountAdd(); - } - else if (wParam == PBT_APMSUSPEND) { - PJAccountDelete(); - } - return TRUE; -} - -LRESULT CmainDlg::OnAccount(WPARAM wParam, LPARAM lParam) -{ - if (!accountDlg) { - accountDlg = new AccountDlg(this); - } - else { - accountDlg->SetForegroundWindow(); - } - accountDlg->Load(accountSettings.accountId); - if (wParam && accountDlg) { - CEdit *edit = (CEdit*)accountDlg->GetDlgItem(IDC_EDIT_PASSWORD); - if (edit) { - edit->SetFocus(); - int nLength = edit->GetWindowTextLength(); - edit->SetSel(nLength, nLength); - } - } - return 0; -} - -void CmainDlg::OnTimerCall() -{ - pjsua_call_id call_id; - int duration = messagesDlg->GetCallDuration(&call_id); - if (duration != -1) { - CString str; - str.Format(_T("%s %s"), Translate(_T("Connected")), GetDuration(duration, true)); - call_user_data *user_data; - if (pjsua_var.state == PJSUA_STATE_RUNNING) { - user_data = (call_user_data *)pjsua_call_get_user_data(call_id); - } - else { - user_data = NULL; - } - unsigned icon = IDI_ACTIVE; - if (user_data) { - if (user_data->srtp == MSIP_SRTP) { - icon = IDI_ACTIVE_SECURE; - } - } - UpdateWindowText(str, icon); - } - else { - KillTimer(IDT_TIMER_CALL); - } -} - -void CmainDlg::OnTimerContactBlink() -{ - CListCtrl *list = (CListCtrl*)pageContacts->GetDlgItem(IDC_CONTACTS); - int n = list->GetItemCount(); - bool ringing = false; - for (int i = 0; i < n; i++) { - Contact *contact = (Contact *)list->GetItemData(i); - if (contact->ringing) { - list->SetItem(i, 0, LVIF_IMAGE, 0, timerContactBlinkState ? MSIP_CONTACT_ICON_BLANK : contact->image, 0, 0, 0); - ringing = true; - } - else { - list->SetItem(i, 0, LVIF_IMAGE, 0, contact->image, 0, 0, 0); - } - } - if (!ringing) { - KillTimer(IDT_TIMER_CONTACTS_BLINK); - timerContactBlinkState = false; - } - else { - timerContactBlinkState = !timerContactBlinkState; - } -} - -void CmainDlg::OnTimer(UINT_PTR TimerVal) -{ - if (TimerVal == IDT_TIMER_AUTOANSWER) { - KillTimer(IDT_TIMER_AUTOANSWER); - if (pjsua_var.state == PJSUA_STATE_RUNNING) { - AutoAnswer(autoAnswerCallId); - } - autoAnswerCallId = PJSUA_INVALID_ID; - } - else if (TimerVal == IDT_TIMER_SWITCH_DEVICES) { - KillTimer(IDT_TIMER_SWITCH_DEVICES); - if (pjsua_var.state == PJSUA_STATE_RUNNING) { - PJ_LOG(3, (THIS_FILE, "Execute refresh devices")); - bool snd_is_active = pjsua_snd_is_active(); - bool is_ring; - if (snd_is_active) { - int in, out; - if (pjsua_get_snd_dev(&in, &out) == PJ_SUCCESS) { - is_ring = (out == msip_audio_ring); - } - else { - is_ring = false; - } - pjsua_set_null_snd_dev(); - } - pjmedia_aud_dev_refresh(); - UpdateSoundDevicesIds(); -#ifdef _GLOBAL_VIDEO - pjmedia_vid_subsys *vid_subsys = pjmedia_get_vid_subsys(); - if (vid_subsys->init_count) { - pjmedia_vid_dev_refresh(); - } -#endif - if (snd_is_active) { - msip_set_sound_device(is_ring ? msip_audio_ring : msip_audio_output, true); - } - } - } - else if (TimerVal == IDT_TIMER_SAVE) { - KillTimer(IDT_TIMER_SAVE); - accountSettings.SettingsSave(); - } - else if (TimerVal == IDT_TIMER_DIRECTORY) { - UsersDirectoryLoad(); - } - else if (TimerVal == IDT_TIMER_CONTACTS_BLINK) { - OnTimerContactBlink(); - } - else if (TimerVal == IDT_TIMER_CALL) { - OnTimerCall(); - } - else - if (TimerVal == IDT_TIMER_IDLE) { - if (pjsua_var.state == PJSUA_STATE_RUNNING && m_PresenceStatus != PJRPID_ACTIVITY_BUSY) { - //-- - LASTINPUTINFO lii; - lii.cbSize = sizeof(LASTINPUTINFO); - if (GetLastInputInfo(&lii)) { - if (lii.dwTime != m_lastInputTime) { - m_lastInputTime = lii.dwTime; - m_idleCounter = 0; - if (m_PresenceStatus == PJRPID_ACTIVITY_AWAY) { - PublishStatus(); - } - } - else { - m_idleCounter++; - if (m_idleCounter == 120) { - PublishStatus(false); - } - } - } - //-- - } - } - else - if (TimerVal = IDT_TIMER_TONE) { - onPlayerPlay(MSIP_SOUND_RINGOUT, 0); - } -} - -void CmainDlg::PJCreate() -{ - player_id = PJSUA_INVALID_ID; - - pageContacts->isSubscribed = FALSE; - - // check updates - if (accountSettings.updatesInterval != _T("never")) - { - CTime t = CTime::GetCurrentTime(); - time_t time = t.GetTime(); - int days; - if (accountSettings.updatesInterval == _T("daily")) - { - days = 1; - } - else if (accountSettings.updatesInterval == _T("monthly")) - { - days = 30; - } - else if (accountSettings.updatesInterval == _T("quarterly")) - { - days = 90; - } - else - { - days = 7; - } - if (accountSettings.checkUpdatesTime + days * 86400 < time) - { - CheckUpdates(); - accountSettings.checkUpdatesTime = time; - accountSettings.SettingsSave(); - } - } - - // pj create - pj_status_t status; - pjsua_config ua_cfg; - pjsua_media_config media_cfg; - pjsua_transport_config cfg; - - // Must create pjsua before anything else! - status = pjsua_create(); - if (status != PJ_SUCCESS) { - return; - } - - // Initialize configs with default settings. - pjsua_config_default(&ua_cfg); - pjsua_media_config_default(&media_cfg); - - CString userAgent; - if (accountSettings.userAgent.IsEmpty()) { - userAgent.Format(_T("%s/%s"), _T(_GLOBAL_NAME_NICE), _T(_GLOBAL_VERSION)); - ua_cfg.user_agent = StrToPjStr(userAgent); - } - else { - ua_cfg.user_agent = StrToPjStr(accountSettings.userAgent); - } - - ua_cfg.cb.on_reg_state2 = &on_reg_state2; - ua_cfg.cb.on_call_state = &on_call_state; - ua_cfg.cb.on_dtmf_digit = &on_dtmf_digit; - ua_cfg.cb.on_call_tsx_state = &on_call_tsx_state; - - ua_cfg.cb.on_call_media_state = &on_call_media_state; - ua_cfg.cb.on_call_media_event = &on_call_media_event; - ua_cfg.cb.on_incoming_call = &on_incoming_call; - ua_cfg.cb.on_nat_detect = &on_nat_detect; - ua_cfg.cb.on_buddy_state = &on_buddy_state; - ua_cfg.cb.on_pager2 = &on_pager2; - ua_cfg.cb.on_pager_status2 = &on_pager_status2; - ua_cfg.cb.on_call_transfer_request2 = &on_call_transfer_request2; - ua_cfg.cb.on_call_transfer_status = &on_call_transfer_status; - - ua_cfg.cb.on_call_replace_request2 = &on_call_replace_request2; - ua_cfg.cb.on_call_replaced = &on_call_replaced; - - ua_cfg.cb.on_mwi_info = &on_mwi_info; - - ua_cfg.srtp_secure_signaling = 0; - - /* - TODO: accountSettings.account: public_addr - */ - - if (accountSettings.enableSTUN && !accountSettings.stun.IsEmpty()) - { - ua_cfg.stun_srv_cnt = 1; - ua_cfg.stun_srv[0] = StrToPjStr(accountSettings.stun); - } - - media_cfg.enable_ice = PJ_FALSE; - media_cfg.no_vad = accountSettings.vad ? PJ_FALSE : PJ_TRUE; - media_cfg.ec_tail_len = accountSettings.ec ? PJSUA_DEFAULT_EC_TAIL_LEN : 0; - if (accountSettings.ec) { -#ifndef _DEBUG - media_cfg.clock_rate = 48000; -#else - media_cfg.clock_rate = 16000; -#endif - media_cfg.channel_count = 1; - } - else { - media_cfg.clock_rate = 44100; - media_cfg.channel_count = 2; - } - - if (accountSettings.dnsSrv) { - ua_cfg.nameserver_count = 4; - ua_cfg.nameserver[0] = StrToPjStr(_T("8.8.8.8")); - ua_cfg.nameserver[1] = StrToPjStr(_T("8.8.4.4")); - ua_cfg.nameserver[2] = StrToPjStr(_T("2001:4860:4860::8888")); - ua_cfg.nameserver[3] = StrToPjStr(_T("2001:4860:4860::8844")); - } - - // Initialize pjsua - if (accountSettings.enableLog) { - pjsua_logging_config log_cfg; - pjsua_logging_config_default(&log_cfg); - //-- - CStringA buf; - int len = accountSettings.logFile.GetLength() + 1; - LPSTR pBuf = buf.GetBuffer(len); - WideCharToMultiByte(CP_ACP, 0, accountSettings.logFile.GetBuffer(), -1, pBuf, len, NULL, NULL); - log_cfg.log_filename = pj_str(pBuf); - log_cfg.decor |= PJ_LOG_HAS_CR; - accountSettings.logFile = pBuf; - buf.ReleaseBuffer(); - //-- - status = pjsua_init(&ua_cfg, &log_cfg, &media_cfg); - } - else { - status = pjsua_init(&ua_cfg, NULL, &media_cfg); - } - - if (status != PJ_SUCCESS) { - pjsua_destroy(); - return; - } - - // Start pjsua - status = pjsua_start(); - - if (status != PJ_SUCCESS) { - pjsua_destroy(); - return; - } - - if (!accountSettings.rport) { - pjsip_cfg()->endpt.disable_rport = PJ_TRUE; - } - - pj_ready = true; - - // Set snd devices - UpdateSoundDevicesIds(); - - //Set aud codecs prio - PJ_LOG(3, (THIS_FILE, "Set audio codecs")); - if (accountSettings.audioCodecs.IsEmpty()) - { - accountSettings.audioCodecs = _T(_GLOBAL_CODECS_ENABLED); - } - if (accountSettings.audioCodecs.GetLength()) - { - // add unknown new codecs to the list - pjsua_codec_info codec_info[64]; - unsigned count = 64; - if (pjsua_enum_codecs(codec_info, &count) == PJ_SUCCESS) { - for (unsigned i = 0; i < count; i++) { - pjsua_codec_set_priority(&codec_info[i].codec_id, PJMEDIA_CODEC_PRIO_DISABLED); - CString rab = PjToStr(&codec_info[i].codec_id); - if (!audioCodecList.Find(rab)) { - audioCodecList.AddTail(rab); - rab.Append(_T("~")); - audioCodecList.AddTail(rab); - } - } - } - // remove unsupported codecs from list - POSITION pos = audioCodecList.GetHeadPosition(); - while (pos) { - POSITION posKey = pos; - CString key = audioCodecList.GetNext(pos); - POSITION posValue = pos; - CString value = audioCodecList.GetNext(pos); - pj_str_t codec_id = StrToPjStr(key); - pjmedia_codec_param param; - if (pjsua_codec_get_param(&codec_id, ¶m) != PJ_SUCCESS) { - audioCodecList.RemoveAt(posKey); - audioCodecList.RemoveAt(posValue); - } - }; - - int curPos = 0; - int i = PJMEDIA_CODEC_PRIO_NORMAL; - CString resToken = accountSettings.audioCodecs.Tokenize(_T(" "), curPos); - while (!resToken.IsEmpty()) { - pj_str_t codec_id = StrToPjStr(resToken); - /* - if (pj_strcmp2(&codec_id,"opus/48000/2") == 0) { - pjmedia_codec_param param; - pjsua_codec_get_param(&codec_id, ¶m); - //param.info.clock_rate = 16000; - param.info.avg_bps = 16000; - param.info.max_bps = param.info.avg_bps * 2; - //param.setting.dec_fmtp.param[param.setting.dec_fmtp.cnt].name=pj_str("maxplaybackrate"); - //param.setting.dec_fmtp.param[param.setting.dec_fmtp.cnt].val = pj_str("8000"); - //param.setting.dec_fmtp.cnt++; - param.setting.dec_fmtp.param[param.setting.dec_fmtp.cnt].name=pj_str("sprop-maxcapturerate"); - param.setting.dec_fmtp.param[param.setting.dec_fmtp.cnt].val = pj_str("8000"); - param.setting.dec_fmtp.cnt++; - pjsua_codec_set_param(&codec_id, ¶m); - } - */ - pjsua_codec_set_priority(&codec_id, i); - resToken = accountSettings.audioCodecs.Tokenize(_T(" "), curPos); - i--; - } - } - -#ifdef _GLOBAL_VIDEO - //Set vid codecs prio - PJ_LOG(3, (THIS_FILE, "Set video codecs")); - if (accountSettings.videoCodec.GetLength()) - { - pj_str_t codec_id = StrToPjStr(accountSettings.videoCodec); - pjsua_vid_codec_set_priority(&codec_id, 255); - } - int bitrate; - if (!accountSettings.videoH264) { - pjsua_vid_codec_set_priority(&pj_str("H264"), 0); - } - else - { - const pj_str_t codec_id = { "H264", 4 }; - pjmedia_vid_codec_param param; - pjsua_vid_codec_get_param(&codec_id, ¶m); - if (accountSettings.videoBitrate) { - bitrate = 1000 * accountSettings.videoBitrate; - param.enc_fmt.det.vid.avg_bps = bitrate; - param.enc_fmt.det.vid.max_bps = bitrate; - } - /* - param.enc_fmt.det.vid.size.w = 140; - param.enc_fmt.det.vid.size.h = 80; - param.enc_fmt.det.vid.fps.num = 30; - param.enc_fmt.det.vid.fps.denum = 1; - param.dec_fmt.det.vid.size.w = 640; - param.dec_fmt.det.vid.size.h = 480; - param.dec_fmt.det.vid.fps.num = 30; - param.dec_fmt.det.vid.fps.denum = 1; - */ - /* - // Defaut (level 1e, 30): - param.dec_fmtp.cnt = 2; - param.dec_fmtp.param[0].name = pj_str("profile-level-id"); - param.dec_fmtp.param[0].val = pj_str("42e01e"); - param.dec_fmtp.param[1].name = pj_str("packetization-mode"); - param.dec_fmtp.param[1].val = pj_str("1"); - //*/ - pjsua_vid_codec_set_param(&codec_id, ¶m); - } - if (!accountSettings.videoH263) { - pjsua_vid_codec_set_priority(&pj_str("H263"), 0); - } - else { - if (accountSettings.videoBitrate) { - bitrate = 1000 * accountSettings.videoBitrate; - const pj_str_t codec_id = { "H263", 4 }; - pjmedia_vid_codec_param param; - pjsua_vid_codec_get_param(&codec_id, ¶m); - param.enc_fmt.det.vid.avg_bps = bitrate; - param.enc_fmt.det.vid.max_bps = bitrate; - pjsua_vid_codec_set_param(&codec_id, ¶m); - } - } - if (!accountSettings.videoVP8) { - pjsua_vid_codec_set_priority(&pj_str("VP8"), 0); - } - else { - if (accountSettings.videoBitrate) { - bitrate = 1000 * accountSettings.videoBitrate; - const pj_str_t codec_id = { "VP8", 4 }; - pjmedia_vid_codec_param param; - pjsua_vid_codec_get_param(&codec_id, ¶m); - param.enc_fmt.det.vid.avg_bps = bitrate; - param.enc_fmt.det.vid.max_bps = bitrate; - pjsua_vid_codec_set_param(&codec_id, ¶m); - } - } -#endif - - // Create transport - PJ_LOG(3, (THIS_FILE, "Create transport")); - transport_udp_local = -1; - transport_udp = -1; - transport_tcp = -1; - transport_tls = -1; - - pjsua_transport_config_default(&cfg); - - if (accountSettings.sourcePort) { - cfg.port = accountSettings.sourcePort; - status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, &transport_udp); - if (status != PJ_SUCCESS) { - cfg.port = 0; - pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, &transport_udp); - } - if (MACRO_ENABLE_LOCAL_ACCOUNT) { - if (accountSettings.sourcePort == 5060) { - transport_udp_local = transport_udp; - } - else { - cfg.port = 5060; - status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, &transport_udp_local); - if (status != PJ_SUCCESS) { - transport_udp_local = transport_udp; - } - } - } - } - else { - if (MACRO_ENABLE_LOCAL_ACCOUNT) { - cfg.port = 5060; - status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, &transport_udp_local); - if (status != PJ_SUCCESS) { - transport_udp_local = -1; - } - } - cfg.port = 0; - pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, &transport_udp); - if (transport_udp_local == -1) { - transport_udp_local = transport_udp; - } -} - - cfg.port = MACRO_ENABLE_LOCAL_ACCOUNT ? 5060 : 0; - status = pjsua_transport_create(PJSIP_TRANSPORT_TCP, &cfg, &transport_tcp); - if (status != PJ_SUCCESS && cfg.port) { - cfg.port = 0; - pjsua_transport_create(PJSIP_TRANSPORT_TCP, &cfg, &transport_tcp); - } - - cfg.port = MACRO_ENABLE_LOCAL_ACCOUNT ? 5061 : 0; - status = pjsua_transport_create(PJSIP_TRANSPORT_TLS, &cfg, &transport_tls); - if (status != PJ_SUCCESS && cfg.port) { - cfg.port = 0; - pjsua_transport_create(PJSIP_TRANSPORT_TLS, &cfg, &transport_tls); - } - - if (accountSettings.usersDirectory.Find(_T("%s")) == -1 && accountSettings.usersDirectory.Find(_T("{")) == -1) { - UsersDirectoryLoad(); - } - - SetTimer(IDT_TIMER_IDLE, 5000, NULL); - - account = PJSUA_INVALID_ID; - account_local = PJSUA_INVALID_ID; - - PJAccountAddLocal(); - -} - -void CmainDlg::UpdateSoundDevicesIds() -{ - msip_audio_input = -1; - msip_audio_output = -2; - msip_audio_ring = -2; - - unsigned count = 128; - pjmedia_aud_dev_info aud_dev_info[128]; - pjsua_enum_aud_devs(aud_dev_info, &count); - for (unsigned i = 0; i < count; i++) - { - CString audDevName(aud_dev_info[i].name); - if (aud_dev_info[i].input_count && !accountSettings.audioInputDevice.Compare(audDevName)) { - msip_audio_input = i; - } - if (aud_dev_info[i].output_count) { - if (!accountSettings.audioOutputDevice.Compare(audDevName)) { - msip_audio_output = i; - } - if (!accountSettings.audioRingDevice.Compare(audDevName)) { - msip_audio_ring = i; - } - } - } -} - -void CmainDlg::PJDestroy() -{ - KillTimer(IDT_TIMER_IDLE); - KillTimer(IDT_TIMER_CALL); - - if (pj_ready) { - if (pageContacts) { - pageContacts->PresenceUnsubsribe(); - } - call_deinit_tonegen(-1); - - toneCalls.RemoveAll(); - - if (IsWindow(m_hWnd)) { - KillTimer(IDT_TIMER_TONE); - } - - PlayerStop(); - - if (accountSettings.accountId) { - PJAccountDelete(); - } - - pj_ready = false; - - //if (transport_udp_local!=PJSUA_INVALID_ID && transport_udp_local!=transport_udp) { - // pjsua_transport_close(transport_udp_local,PJ_TRUE); - //} - if (transport_udp != PJSUA_INVALID_ID) { - //pjsua_transport_close(transport_udp,PJ_TRUE); - } - //if (transport_tcp!=PJSUA_INVALID_ID) { - // pjsua_transport_close(transport_tcp,PJ_TRUE); - //} - //if (transport_tls!=PJSUA_INVALID_ID) { - // pjsua_transport_close(transport_tls,PJ_TRUE); - //} - pjsua_destroy(); -} -} - -void CmainDlg::PJAccountConfig(pjsua_acc_config *acc_cfg) -{ - pjsua_acc_config_default(acc_cfg); -#ifdef _GLOBAL_VIDEO - acc_cfg->vid_in_auto_show = PJ_TRUE; - acc_cfg->vid_out_auto_transmit = PJ_TRUE; - acc_cfg->vid_cap_dev = VideoCaptureDeviceId(); - acc_cfg->vid_wnd_flags = PJMEDIA_VID_DEV_WND_BORDER | PJMEDIA_VID_DEV_WND_RESIZABLE; -#endif - - if (accountSettings.rtpPortMin > 0) { - acc_cfg->rtp_cfg.port = accountSettings.rtpPortMin; - if (accountSettings.rtpPortMax > accountSettings.rtpPortMin) { - acc_cfg->rtp_cfg.port_range = accountSettings.rtpPortMax - accountSettings.rtpPortMin; - } - } -} - -/** - * Add account is not exists. - */ -void CmainDlg::PJAccountAdd() -{ - if (pjsua_acc_is_valid(account)) { - return; - } - CString str; - - if (!accountSettings.accountId) { - return; - } - if (accountSettings.account.username.IsEmpty()) { - if (!accountSettings.silent) { - OnAccount(0, 0); - } - return; - } - - CString title = _T(_GLOBAL_NAME_NICE); - CString titleAdder; - CString usernameLocal; - usernameLocal = accountSettings.account.username; - if (!accountSettings.account.label.IsEmpty()) - { - titleAdder = accountSettings.account.label; - } - else if (!accountSettings.account.displayName.IsEmpty()) - { - titleAdder = accountSettings.account.displayName; - } - else if (!usernameLocal.IsEmpty()) - { - titleAdder = usernameLocal; - } - if (!titleAdder.IsEmpty()) { - title.AppendFormat(_T(" - %s"), titleAdder); - } - SetPaneText2(titleAdder); - SetWindowText(title); - - pjsua_acc_config acc_cfg; - PJAccountConfig(&acc_cfg); - - if (accountSettings.account.disableSessionTimer) { - acc_cfg.use_timer = PJSUA_SIP_TIMER_INACTIVE; - } - - if (accountSettings.account.srtp == _T("optional")) { - acc_cfg.use_srtp = PJMEDIA_SRTP_OPTIONAL; - } - else if (accountSettings.account.srtp == _T("mandatory")) { - acc_cfg.use_srtp = PJMEDIA_SRTP_MANDATORY; - } - else { - acc_cfg.use_srtp = PJMEDIA_SRTP_DISABLED; - } - if (!accountSettings.enableSTUN || accountSettings.stun.IsEmpty()) { - acc_cfg.rtp_cfg.public_addr = StrToPjStr(accountSettings.account.publicAddr); - } - acc_cfg.ice_cfg_use = PJSUA_ICE_CONFIG_USE_CUSTOM; - acc_cfg.ice_cfg.enable_ice = accountSettings.account.ice ? PJ_TRUE : PJ_FALSE; - acc_cfg.allow_via_rewrite = accountSettings.account.allowRewrite ? PJ_TRUE : PJ_FALSE; - acc_cfg.allow_sdp_nat_rewrite = acc_cfg.allow_via_rewrite; - acc_cfg.allow_contact_rewrite = acc_cfg.allow_via_rewrite ? 2 : PJ_FALSE; - acc_cfg.publish_enabled = accountSettings.account.publish ? PJ_TRUE : PJ_FALSE; - - if (!accountSettings.account.voicemailNumber.IsEmpty()) { - acc_cfg.mwi_enabled = PJ_TRUE; - } - - transport = MSIP_TRANSPORT_AUTO; - if (accountSettings.account.transport == _T("udp") && transport_udp != -1) { - acc_cfg.transport_id = transport_udp; - } - else if (accountSettings.account.transport == _T("tcp") && transport_tcp != -1) { - transport = MSIP_TRANSPORT_TCP; - } - else if (accountSettings.account.transport == _T("tls") && transport_tls != -1) { - transport = MSIP_TRANSPORT_TLS; - } - - str.Format(_T("%s..."), Translate(_T("Connecting"))); - UpdateWindowText(str); - - acc_cfg.cred_count = 1; - acc_cfg.cred_info[0].username = StrToPjStr(!accountSettings.account.authID.IsEmpty() ? accountSettings.account.authID : get_account_username()); - acc_cfg.cred_info[0].realm = pj_str("*"); - acc_cfg.cred_info[0].scheme = pj_str("Digest"); - acc_cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD; - acc_cfg.cred_info[0].data = StrToPjStr(get_account_password()); - - CString proxy; - if (!accountSettings.account.proxy.IsEmpty()) { - acc_cfg.proxy_cnt = 1; - proxy.Format(_T("sip:%s"), accountSettings.account.proxy); - AddTransportSuffix(proxy); - acc_cfg.proxy[0] = StrToPjStr(proxy); - } - - //-- port knocker - if (!accountSettings.portKnockerPorts.IsEmpty()) { - CString host; - CString ip; - if (!accountSettings.portKnockerHost.IsEmpty()) { - host = accountSettings.portKnockerHost; - } - else { - host = RemovePort(get_account_server()); - } - if (!host.IsEmpty()) { - AfxSocketInit(); - if (IsIP(host)) { - ip = host; - } - else { - hostent *he = gethostbyname(CStringA(host)); - if (he) { - ip = inet_ntoa(*((struct in_addr *) he->h_addr_list[0])); - } - } - CSocket udpSocket; - if (!ip.IsEmpty() && udpSocket.Create(0, SOCK_DGRAM, 0)) { - int pos = 0; - CString strPort = accountSettings.portKnockerPorts.Tokenize(_T(","), pos); - while (pos != -1) { - strPort.Trim(); - if (!strPort.IsEmpty()) { - int port = StrToInt(strPort); - if (port > 0 && port <= 65535) { - udpSocket.SendToEx(0, 0, port, ip); - } - } - strPort = accountSettings.portKnockerPorts.Tokenize(_T(","), pos); - } - udpSocket.Close(); - } - } - } - //-- - pj_status_t status = PJ_SUCCESS; - //-- - CString localURI; - if (!accountSettings.account.displayName.IsEmpty()) { - localURI = _T("\"") + accountSettings.account.displayName + _T("\" "); - } - localURI += GetSIPURI(get_account_username()); - acc_cfg.id = StrToPjStr(localURI); - //-- - if (get_account_server().IsEmpty()) { - acc_cfg.register_on_acc_add = PJ_FALSE; - } - else { - CString regURI; - regURI.Format(_T("sip:%s"), get_account_server()); - AddTransportSuffix(regURI); - acc_cfg.reg_uri = StrToPjStr(regURI); - } - //-- - status = pjsua_acc_add(&acc_cfg, PJ_TRUE, &account); - - if (account == PJSUA_INVALID_ID) { - ShowErrorMessage(status); - UpdateWindowText(_T(""), IDI_DEFAULT, true); - } - - PublishStatus(true, acc_cfg.register_on_acc_add); - - } - -void CmainDlg::PJAccountAddLocal() -{ - if (MACRO_ENABLE_LOCAL_ACCOUNT) { - pj_status_t status; - pjsua_acc_config acc_cfg; - PJAccountConfig(&acc_cfg); - acc_cfg.priority--; - pjsua_transport_data *t = &pjsua_var.tpdata[0]; - CString localURI; - localURI.Format(_T(""), PjToStr(&t->local_name.host)); - acc_cfg.id = StrToPjStr(localURI); - pjsua_acc_add(&acc_cfg, PJ_TRUE, &account_local); - acc_cfg.priority++; - } -} - -/** - * Delete account if exists. - */ -void CmainDlg::PJAccountDelete(bool deep) -{ - if (pageContacts) { - pageContacts->PresenceUnsubsribe(); - } - if (pjsua_acc_is_valid(account)) { - pjsua_acc_del(account); - account = PJSUA_INVALID_ID; - } - onMWIInfo(0, 0); - SetPaneText2(); - SetWindowText(_T(_GLOBAL_NAME_NICE)); - UpdateWindowText(); -} - -void CmainDlg::PJAccountDeleteLocal() -{ - if (pjsua_acc_is_valid(account_local)) { - pjsua_acc_del(account_local); - account_local = PJSUA_INVALID_ID; - } -} - -void CmainDlg::OnTcnSelchangeTab(NMHDR *pNMHDR, LRESULT *pResult) -{ - CTabCtrl* tab = (CTabCtrl*)GetDlgItem(IDC_MAIN_TAB); - int nTab = tab->GetCurSel(); - TC_ITEM tci; - tci.mask = TCIF_PARAM; - tab->GetItem(nTab, &tci); - if (tci.lParam > 0) { - CWnd* pWnd = (CWnd *)tci.lParam; - if (m_tabPrev != -1) { - tab->GetItem(m_tabPrev, &tci); - if (tci.lParam > 0) { - ((CWnd *)tci.lParam)->ShowWindow(SW_HIDE); - } - } - pWnd->ShowWindow(SW_SHOW); - if (IsWindowVisible()) { - pWnd->SetFocus(); - } - if (nTab != accountSettings.activeTab) { - accountSettings.activeTab = nTab; - AccountSettingsPendingSave(); - } - if (pWnd == pageCalls && missed) { - missed = false; - UpdateWindowText(); - } - } - else { - } - *pResult = 0; -} - -void CmainDlg::OnTcnSelchangingTab(NMHDR *pNMHDR, LRESULT *pResult) -{ - CTabCtrl* tab = (CTabCtrl*)GetDlgItem(IDC_MAIN_TAB); - m_tabPrev = tab->GetCurSel(); - *pResult = FALSE; -} - -LRESULT CmainDlg::OnUpdateWindowText(WPARAM wParam, LPARAM lParam) -{ - UpdateWindowText(_T("-")); - return TRUE; -} - -void CmainDlg::TabFocusSet() -{ - CTabCtrl* tab = (CTabCtrl*)GetDlgItem(IDC_MAIN_TAB); - int nTab = tab->GetCurSel(); - TC_ITEM tci; - tci.mask = TCIF_PARAM; - tab->GetItem(nTab, &tci); - CWnd* pWnd = (CWnd *)tci.lParam; - pWnd->SetFocus(); -} - -void CmainDlg::UpdateWindowText(CString text, int icon, bool afterRegister) -{ - if (text.IsEmpty() && pjsua_var.state == PJSUA_STATE_RUNNING && pjsua_call_get_count()) { - return; - } - CString str; - bool showAccountDlg = false; - if (text.IsEmpty() || text == _T("-")) { - if (pjsua_var.state == PJSUA_STATE_RUNNING && pjsua_acc_is_valid(account)) { - pjsua_acc_info info; - pjsua_acc_get_info(account, &info); - str = PjToStr(&info.status_text); - if (str != _T("Default status message")) { - if (!info.has_registration || str == _T("OK")) - { - if (m_PresenceStatus == PJRPID_ACTIVITY_BUSY) { - icon = IDI_BUSY; - str = Translate(_T("Do Not Disturb")); - } else { - if (m_PresenceStatus == PJRPID_ACTIVITY_AWAY) { - icon = IDI_AWAY; - str = Translate(_T("Away")); - } - else { - if (info.has_registration && transport == MSIP_TRANSPORT_TLS) { - icon = IDI_SECURE; - } - else { - icon = IDI_ONLINE; - } - str = Translate(_T("Online")); - } - if (accountSettings.autoAnswer == _T("button") && accountSettings.AA) { - str.AppendFormat(_T(" (%s)"), Translate(_T("Auto Answer"))); - } - } - if (!info.has_registration) { - str.AppendFormat(_T(" (%s)"), Translate(_T("outgoing"))); - } - pageContacts->PresenceSubsribe(); - if (!dialNumberDelayed.IsEmpty()) - { - DialNumber(dialNumberDelayed); - dialNumberDelayed = _T(""); - } - } - else if (str == _T("In Progress")) { - str.Format(_T("%s..."), Translate(_T("Connecting"))); - } - else if (info.status == 401 || info.status == 403) { - onTrayNotify(NULL, WM_LBUTTONUP); - if (afterRegister) { - showAccountDlg = true; - } - icon = IDI_OFFLINE; - str = Translate(_T("Incorrect Password")); - } - else { - str = Translate(str.GetBuffer()); - } - str = str.GetBuffer(); - } - else { - str.Format(_T("%s: %d"), Translate(_T("Response Code")), info.status); - } - } - else { - if (afterRegister) { - showAccountDlg = true; - } - str = _T(_GLOBAL_NAME_NICE); - icon = IDI_DEFAULT; - } - } - else - { - str = text; - } - - CString* pPaneText = new CString(); - *pPaneText = str; - PostMessage(UM_SET_PANE_TEXT, NULL, (LPARAM)pPaneText); - - if (icon != -1) { - HICON hIcon = (HICON)LoadImage( - AfxGetInstanceHandle(), - MAKEINTRESOURCE(icon), - IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); - m_bar.GetStatusBarCtrl().SetIcon(0, hIcon); - iconStatusbar = icon; - - //-- - tnd.uFlags = tnd.uFlags & ~NIF_INFO; - if ((pjsua_var.state == PJSUA_STATE_RUNNING && !pjsua_acc_is_valid(account) && MACRO_ENABLE_LOCAL_ACCOUNT) || (icon != IDI_DEFAULT && icon != IDI_OFFLINE)) { - if (missed) { - if (tnd.hIcon != iconMissed) { - tnd.uFlags = tnd.uFlags & ~NIF_INFO; - tnd.hIcon = iconMissed; - Shell_NotifyIcon(NIM_MODIFY, &tnd); - } - } - else { - - if (tnd.hIcon != iconSmall) { - tnd.hIcon = iconSmall; - Shell_NotifyIcon(NIM_MODIFY, &tnd); - } - } - } - else { - if (tnd.hIcon != iconInactive) { - tnd.hIcon = iconInactive; - Shell_NotifyIcon(NIM_MODIFY, &tnd); - } - } - //-- - } - if (showAccountDlg) { - PostMessage(UM_ON_ACCOUNT, 1); - } -} - -void CmainDlg::PublishStatus(bool online, bool init) -{ - bool busy = (accountSettings.denyIncoming == _T("button") && accountSettings.DND); - pjrpid_activity presenceStatusNew; - pj_str_t note = pj_str(""); - if (m_PresenceStatus == PJRPID_ACTIVITY_BUSY) { - if (!busy) { - presenceStatusNew = PJRPID_ACTIVITY_UNKNOWN; - note = pj_str("Idle"); - } - } - else { - if (busy) { - presenceStatusNew = PJRPID_ACTIVITY_BUSY; - note = pj_str("Busy"); - } - else { - presenceStatusNew = online ? PJRPID_ACTIVITY_UNKNOWN : PJRPID_ACTIVITY_AWAY; - note = online ? pj_str("Idle") : pj_str("Away"); - } - } - if (note.slen) { - pjsua_acc_id ids[PJSUA_MAX_ACC]; - unsigned count = PJSUA_MAX_ACC; - if (pjsua_enum_accs(ids, &count) == PJ_SUCCESS) { - pjrpid_element pr; - pr.type = PJRPID_ELEMENT_TYPE_PERSON; - pr.id = pj_str(NULL); - pr.note = pj_str(NULL); - pr.note = note; - pr.activity = presenceStatusNew; - for (unsigned i = 0; i < count; i++) { - pjsua_acc_set_online_status2(ids[i], PJ_TRUE, &pr); - } - } - m_PresenceStatus = presenceStatusNew; - } - if (!init) { - UpdateWindowText(); - } -} - -LRESULT CmainDlg::onCopyData(WPARAM wParam, LPARAM lParam) -{ - if (pj_ready) { - COPYDATASTRUCT *s = (COPYDATASTRUCT*)lParam; - if (s && s->dwData == 1) { - CString params = (LPCTSTR)s->lpData; - CommandLine(params); - } - } - return 0; -} - -void CmainDlg::CommandLine(CString params) { - params.Trim(); - if (!params.IsEmpty()) { - int pos = params.Find(_T("msip:")); - if (pos == 0) { - CString cmd = params.Mid(5); - if (cmd == _T("minimize")) { - ShowWindow(SW_HIDE); - } - else if (cmd == _T("answer")) { - msip_call_answer(); - } - else if (cmd == _T("hangupall")) { - call_hangup_all_noincoming(); - } - else if (cmd == _T("hold")) { - messagesDlg->OnBnClickedHold(); - } - else if (cmd.Find(_T("transfer_")) == 0) { - messagesDlg->CallAction(MSIP_ACTION_TRANSFER, cmd.Mid(9)); - } - else if (cmd == _T("micmute")) { - pageDialer->OnBnClickedMuteInput(); - } - else if (cmd == _T("speakmute")) { - pageDialer->OnBnClickedMuteOutput(); - } - else if (cmd == _T("micup")) { - pageDialer->OnBnClickedPlusInput(); - } - else if (cmd == _T("micdown")) { - pageDialer->OnBnClickedMinusInput(); - } - else if (cmd == _T("speakup")) { - pageDialer->OnBnClickedPlusOutput(); - } - else if (cmd == _T("speakdown")) { - pageDialer->OnBnClickedMinusOutput(); - } - else if (!cmd.IsEmpty()) { - DialNumberFromCommandLine(cmd); - } - } - else { - if (params == _T("/answer")) { - msip_call_answer(); - } - else if (params == _T("/hangupall")) { - call_hangup_all_noincoming(); - } - else { - DialNumberFromCommandLine(params); - } - } - } -} - -bool CmainDlg::GotoTabLParam(LPARAM lParam) { - CTabCtrl* tab = (CTabCtrl*)GetDlgItem(IDC_MAIN_TAB); - for (int i = 0; i < tab->GetItemCount(); i++) { - TC_ITEM tci; - tci.mask = TCIF_PARAM; - tab->GetItem(i, &tci); - if (tci.lParam == lParam) { - return GotoTab(i, tab); - } - } - return false; -} - -bool CmainDlg::GotoTab(int i, CTabCtrl* tab) { - if (!tab) { - tab = (CTabCtrl*)GetDlgItem(IDC_MAIN_TAB); - } - int nTab = tab->GetCurSel(); - if (nTab != i) { - LRESULT pResult; - OnTcnSelchangingTab(NULL, &pResult); - tab->SetCurSel(i); - OnTcnSelchangeTab(NULL, &pResult); - return true; - } - return false; -} - - -void CmainDlg::DialNumberFromCommandLine(CString number) { - GotoTab(0); - pjsua_acc_info info; - number.Trim('"'); - if (number.Mid(0, 4).CompareNoCase(_T("tel:")) == 0 || number.Mid(0, 4).CompareNoCase(_T("sip:")) == 0) { - number = number.Mid(4); - } - else if (number.Mid(0, 7).CompareNoCase(_T("callto:")) == 0) { - number = number.Mid(7); - } - if (accountSettings.accountId > 0) { - if (pjsua_acc_is_valid(account) && - (get_account_server().IsEmpty() || - (pjsua_acc_get_info(account, &info) == PJ_SUCCESS && info.status == 200) - ) - ) { - DialNumber(number); - } - else { - dialNumberDelayed = number; - } - } - else { - if (pjsua_acc_is_valid(account_local)) { - DialNumber(number); - } - else if (accountSettings.enableLocalAccount) { - dialNumberDelayed = number; - } - } -} - -void CmainDlg::DialNumber(CString params) -{ - CString number; - CString message; - int i = params.Find(_T(" ")); - if (i != -1) { - number = params.Mid(0, i); - message = params.Mid(i + 1); - message.Trim(); - } - else { - number = params; - } - number.Trim(); - if (!number.IsEmpty()) { - if (message.IsEmpty()) { - MakeCall(number); - } - else { - messagesDlg->SendInstantMessage(NULL, message, number); - } - } -} - -bool CmainDlg::MakeCall(CString number, bool hasVideo) -{ - if (accountSettings.singleMode && call_get_count_noincoming()) { - GotoTab(0); - } - else { - accountSettings.lastCallNumber = number; - accountSettings.lastCallHasVideo = hasVideo; - CString commands; - CString numberFormated = FormatNumber(number, &commands); - pj_status_t pj_status = pjsua_verify_sip_url(StrToPj(numberFormated)); - if (pj_status == PJ_SUCCESS) { - bool doNotShowMessagesWindow = accountSettings.singleMode || - (accountSettings.silent && !mainDlg->IsWindowVisible()); - messagesDlg->AddTab(numberFormated, _T(""), TRUE, NULL, NULL, doNotShowMessagesWindow); - messagesDlg->Call(hasVideo, commands); - return true; - } - else { - ShowErrorMessage(pj_status); - } - } - return false; -} - -bool CmainDlg::MessagesOpen(CString number) -{ - CString commands; - CString numberFormated = FormatNumber(number, &commands); - pj_status_t pj_status = pjsua_verify_sip_url(StrToPj(numberFormated)); - if (pj_status == PJ_SUCCESS) { - messagesDlg->AddTab(numberFormated, _T(""), TRUE); - return true; - } - else { - ShowErrorMessage(pj_status); - } - return false; -} - -void CmainDlg::AutoAnswer(pjsua_call_id call_id) -{ - pjsua_call_info call_info; - if (pjsua_call_get_info(call_id, &call_info) != PJ_SUCCESS || (call_info.state != PJSIP_INV_STATE_INCOMING && call_info.state != PJSIP_INV_STATE_EARLY)) { - return; - } - mainDlg->PostMessage(UM_CALL_ANSWER, (WPARAM)call_id, (LPARAM)call_info.rem_vid_cnt); - if (!accountSettings.hidden) { - mainDlg->PostMessage(UM_ON_PLAYER_PLAY, MSIP_SOUND_RINGIN2, 0); - } -} - -void CmainDlg::ShortcutAction(Shortcut *shortcut) -{ - switch (shortcut->type) { - case MSIP_SHORTCUT_CALL: - mainDlg->MakeCall(shortcut->number); - break; - case MSIP_SHORTCUT_VIDEOCALL: -#ifdef _GLOBAL_VIDEO - mainDlg->MakeCall(shortcut->number, true); -#else - mainDlg->MakeCall(shortcut->number); -#endif - break; - case MSIP_SHORTCUT_MESSAGE: - mainDlg->MessagesOpen(shortcut->number); - break; - case MSIP_SHORTCUT_DTMF: - mainDlg->pageDialer->DTMF(shortcut->number); - break; - case MSIP_SHORTCUT_TRANSFER: - MessagesContact* messagesContactSelected = mainDlg->messagesDlg->GetMessageContact(); - if (messagesContactSelected && messagesContactSelected->callId != -1) { - pj_str_t pj_uri = StrToPjStr(GetSIPURI(shortcut->number, true)); - call_user_data *user_data; - user_data = (call_user_data *)pjsua_call_get_user_data(messagesContactSelected->callId); - if (!user_data || !user_data->inConference) { - pjsua_call_xfer(messagesContactSelected->callId, &pj_uri, NULL); - } - } - break; - } -} - -LRESULT CmainDlg::onPlayerPlay(WPARAM wParam, LPARAM lParam) -{ - CString filename; - BOOL noLoop; - BOOL inCall; - if (wParam == MSIP_SOUND_CUSTOM) { - filename = *(CString*)lParam; - noLoop = FALSE; - inCall = FALSE; - } - else { - filename = accountSettings.pathExe + _T("\\"); - switch (wParam) { - case MSIP_SOUND_MESSAGE_IN: - filename.Append(_T("messagein.wav")); - noLoop = TRUE; - inCall = FALSE; - break; - case MSIP_SOUND_MESSAGE_OUT: - filename.Append(_T("messageout.wav")); - noLoop = TRUE; - inCall = FALSE; - break; - case MSIP_SOUND_HANGUP: - filename.Append(_T("hangup.wav")); - noLoop = TRUE; - inCall = TRUE; - break; - case MSIP_SOUND_RINGIN: - filename.Append(_T("ringin.wav")); - noLoop = FALSE; - inCall = FALSE; - break; - case MSIP_SOUND_RINGIN2: - filename.Append(_T("ringin2.wav")); - noLoop = TRUE; - inCall = TRUE; - break; - case MSIP_SOUND_RINGOUT: - filename.Append(_T("ringout.wav")); - noLoop = TRUE; - inCall = TRUE; - break; - default: - noLoop = TRUE; - inCall = FALSE; - } - } - PlayerPlay(filename, noLoop, inCall); - return 0; -} - -LRESULT CmainDlg::onPlayerStop(WPARAM wParam, LPARAM lParam) -{ - PlayerStop(); - return 0; -} - - -struct pjsua_player_eof_data -{ - pj_pool_t *pool; - pjsua_player_id player_id; -}; - -static PJ_DEF(pj_status_t) on_pjsua_wav_file_end_callback(pjmedia_port* media_port, void* args) -{ - mainDlg->PostMessage(UM_ON_PLAYER_STOP, 0, 0); - return -1;//Here it is important to return value other than PJ_SUCCESS -} - -void CmainDlg::PlayerPlay(CString filename, bool noLoop, bool inCall) -{ - PlayerStop(); - if (pjsua_var.state != PJSUA_STATE_NULL && !filename.IsEmpty()) { - pj_str_t file = StrToPjStr(filename); - if (pjsua_var.mconf && pjsua_player_create(&file, noLoop ? PJMEDIA_FILE_NO_LOOP : 0, &player_id) == PJ_SUCCESS) { - pjmedia_port *player_media_port; - if (pjsua_player_get_port(player_id, &player_media_port) == PJ_SUCCESS) { - if (noLoop) { - pj_pool_t *pool = pjsua_pool_create("microsip_eof_data", 512, 512); - struct pjsua_player_eof_data *eof_data = PJ_POOL_ZALLOC_T(pool, struct pjsua_player_eof_data); - eof_data->pool = pool; - eof_data->player_id = player_id; - pjmedia_wav_player_set_eof_cb(player_media_port, eof_data, &on_pjsua_wav_file_end_callback); - } - if ( - (!tone_gen && pjsua_conf_get_active_ports() <= 2) - || - (tone_gen && pjsua_conf_get_active_ports() <= 3) - ) { - msip_set_sound_device(inCall ? msip_audio_output : msip_audio_ring); - } - pjsua_conf_connect(pjsua_player_get_conf_port(player_id), 0); - } - } - } -} - -void CmainDlg::PlayerStop() -{ - if (player_id != PJSUA_INVALID_ID) { - if (pjsua_var.state != PJSUA_STATE_NULL) { - pjsua_conf_disconnect(pjsua_player_get_conf_port(player_id), 0); - if (pjsua_player_destroy(player_id) == PJ_SUCCESS) { - player_id = PJSUA_INVALID_ID; - } - } - else { - player_id = PJSUA_INVALID_ID; - } - } -} - -LRESULT CmainDlg::onShellHookMessage(WPARAM wParam, LPARAM lParam) -{ - if (wParam == HSHELL_APPCOMMAND) { - int nCmd = GET_APPCOMMAND_LPARAM(lParam); - if (nCmd == APPCOMMAND_MEDIA_PLAY || - nCmd == APPCOMMAND_MEDIA_PLAY_PAUSE || - nCmd == APPCOMMAND_MEDIA_STOP) { - if (ringinDlgs.GetCount()) { - RinginDlg *ringinDlg = ringinDlgs.GetAt(0); - if (nCmd == APPCOMMAND_MEDIA_STOP) { - ringinDlg->OnBnClickedDecline(); - } - else { - ringinDlg->CallAccept(ringinDlg->remoteHasVideo); - } - } - else { - if (nCmd == APPCOMMAND_MEDIA_STOP) { - messagesDlg->OnBnClickedEnd(); - } - else { - CButton* callButton = (CButton*)pageDialer->GetDlgItem(IDC_CALL); - if (callButton->IsWindowVisible() && callButton->IsWindowEnabled()) { - pageDialer->OnBnClickedCall(); - } - else { - messagesDlg->OnBnClickedHold(); - } - } - } - } - else if (nCmd == APPCOMMAND_MEDIA_PAUSE) { - messagesDlg->OnBnClickedHold(); - } - } - return 0; -} - -LRESULT CmainDlg::onCallAnswer(WPARAM wParam, LPARAM lParam) -{ - if (pjsua_var.state == PJSUA_STATE_RUNNING) { - pjsua_call_id call_id = wParam; - if (lParam < 0) { - pjsua_call_answer(call_id, -lParam, NULL, NULL); - return 0; - } - pjsua_call_info call_info; - if (pjsua_call_get_info(call_id, &call_info) == PJ_SUCCESS) { - if (call_info.role == PJSIP_ROLE_UAS && (call_info.state == PJSIP_INV_STATE_INCOMING || call_info.state == PJSIP_INV_STATE_EARLY)) { - if (accountSettings.singleMode) { - call_hangup_all_noincoming(); - } - msip_set_sound_device(msip_audio_output); -#ifdef _GLOBAL_VIDEO - if (lParam > 0) { - createPreviewWin(); - } -#endif - pjsua_call_setting call_setting; - pjsua_call_setting_default(&call_setting); - call_setting.vid_cnt = lParam > 0 ? 1 : 0; - if (pjsua_call_answer2(call_id, &call_setting, 200, NULL, NULL) == PJ_SUCCESS) { - callIdIncomingIgnore = PjToStr(&call_info.call_id); - } - PlayerStop(); - if (!accountSettings.silent) { - onTrayNotify(NULL, WM_LBUTTONUP); - } - } - } -} - return 0; - } - -LRESULT CmainDlg::onCallHangup(WPARAM wParam, LPARAM lParam) -{ - if (pjsua_var.state == PJSUA_STATE_RUNNING) { - pjsua_call_id call_id = wParam; - msip_call_hangup_fast(call_id); - } - return 0; -} - -LRESULT CmainDlg::onTabIconUpdate(WPARAM wParam, LPARAM lParam) -{ - if (messagesDlg) { - pjsua_call_id call_id = wParam; - for (int i = 0; i < messagesDlg->tab->GetItemCount(); i++) { - MessagesContact* messagesContact = messagesDlg->GetMessageContact(i); - if (messagesContact->callId == call_id) { - pjsua_call_info call_info; - if (pjsua_call_get_info(call_id, &call_info) == PJ_SUCCESS) { - messagesDlg->UpdateTabIcon(messagesContact, i, &call_info); - } - break; - } - } - } - return 0; -} - -LRESULT CmainDlg::onSetPaneText(WPARAM wParam, LPARAM lParam) -{ - CString* pString = (CString*)lParam; - ASSERT(pString != NULL); - m_bar.SetPaneText(0, *pString); - delete pString; - return 0; -} - -void CmainDlg::SetPaneText2(CString str) -{ - if (str.IsEmpty()) { - m_bar.SetPaneInfo(1, IDS_STATUSBAR2, SBPS_NOBORDERS, 0); - } - else { - CSize size = m_bar.GetDC()->GetTextExtent(str); - int width = size.cx; - m_bar.SetPaneInfo(1, IDS_STATUSBAR2, SBPS_NORMAL, width); - } - m_bar.SetPaneText(1, str); - RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, IDS_STATUSBAR); -} - -BOOL CmainDlg::CopyStringToClipboard(IN const CString & str) -{ - // Open the clipboard - if (!OpenClipboard()) - return FALSE; - - // Empty the clipboard - if (!EmptyClipboard()) - { - CloseClipboard(); - return FALSE; - } - - // Number of bytes to copy (consider +1 for end-of-string, and - // properly scale byte size to sizeof(TCHAR)) - SIZE_T textCopySize = (str.GetLength() + 1) * sizeof(TCHAR); - - // Allocate a global memory object for the text - HGLOBAL hTextCopy = GlobalAlloc(GMEM_MOVEABLE, textCopySize); - if (hTextCopy == NULL) - { - CloseClipboard(); - return FALSE; - } - - // Lock the handle, and copy source text to the buffer - TCHAR * textCopy = reinterpret_cast(GlobalLock( - hTextCopy)); - ASSERT(textCopy != NULL); - StringCbCopy(textCopy, textCopySize, str.GetString()); - GlobalUnlock(hTextCopy); - textCopy = NULL; // avoid dangling references - - // Place the handle on the clipboard -#if defined( _UNICODE ) - UINT textFormat = CF_UNICODETEXT; // Unicode text -#else - UINT textFormat = CF_TEXT; // ANSI text -#endif // defined( _UNICODE ) - - if (SetClipboardData(textFormat, hTextCopy) == NULL) - { - // Failed - CloseClipboard(); - return FALSE; - } - - // Release the clipboard - CloseClipboard(); - - // All right - return TRUE; -} - -void CmainDlg::OnSysCommand(UINT nID, LPARAM lParam) -{ - if (nID == SC_CLOSE) { - ShowWindow(SW_HIDE); - } - else { - __super::OnSysCommand(nID, lParam); - } - } - -BOOL CmainDlg::OnQueryEndSession() -{ - return TRUE; -} - -void CmainDlg::OnClose() -{ - DestroyWindow(); -} - -void CmainDlg::OnContextMenu(CWnd *pWnd, CPoint point) -{ - CPoint local = point; - ScreenToClient(&local); - CRect rect; - GetClientRect(&rect); - int height = 16; - CDC *pDC = GetDC(); - if (pDC) { - int dpiY = GetDeviceCaps(pDC->m_hDC, LOGPIXELSY); - height = MulDiv(height, dpiY, 96); - ReleaseDC(pDC); - } - - if (rect.Height() - local.y <= height) { - MainPopupMenu(); - } - else { - DefWindowProc(WM_CONTEXTMENU, NULL, MAKELPARAM(point.x, point.y)); - } -} - -BOOL CmainDlg::OnDeviceChange(UINT nEventType, DWORD_PTR dwData) -{ - if (nEventType == DBT_DEVNODES_CHANGED) { - if (pj_ready) { - if (dwData == 1) { - PJ_LOG(3, (THIS_FILE, "OnDeviceStateChanged event, schedule refresh devices")); - } - else { - PJ_LOG(3, (THIS_FILE, "WM_DEVICECHANGE received, schedule refresh devices")); - } - KillTimer(IDT_TIMER_SWITCH_DEVICES); - SetTimer(IDT_TIMER_SWITCH_DEVICES, 1500, NULL); - } - } - return FALSE; -} - -void CmainDlg::OnSessionChange(UINT nSessionState, UINT nId) -{ - if (nSessionState == WTS_REMOTE_CONNECT || nSessionState == WTS_CONSOLE_CONNECT) { - if (pj_ready) { - PJ_LOG(3, (THIS_FILE, "WM_WTSSESSION_CHANGE received, schedule refresh devices")); - KillTimer(IDT_TIMER_SWITCH_DEVICES); - SetTimer(IDT_TIMER_SWITCH_DEVICES, 1500, NULL); - } - } -} - -void CmainDlg::OnMove(int x, int y) -{ - if (IsWindowVisible() && !IsZoomed() && !IsIconic()) { - CRect cRect; - GetWindowRect(&cRect); - accountSettings.mainX = cRect.left; - accountSettings.mainY = cRect.top; - AccountSettingsPendingSave(); - } -} - -void CmainDlg::OnSize(UINT type, int w, int h) -{ - CBaseDialog::OnSize(type, w, h); - if (this->IsWindowVisible() && type == SIZE_RESTORED) { - CRect cRect; - GetWindowRect(&cRect); - accountSettings.mainW = cRect.Width(); - accountSettings.mainH = cRect.Height(); - AccountSettingsPendingSave(); - } -} - -void CmainDlg::SetupJumpList() -{ - JumpList jl(_T(_GLOBAL_NAME_NICE)); - jl.AddTasks(); -} - -void CmainDlg::RemoveJumpList() -{ - JumpList jl(_T(_GLOBAL_NAME_NICE)); - jl.DeleteJumpList(); -} - -void CmainDlg::OnMenuWebsite() -{ - OpenURL(_T(_GLOBAL_MENU_WEBSITE)); -} - -void CmainDlg::OnMenuHelp() -{ - OpenURL(_T(_GLOBAL_MENU_HELP)); -} - -void CmainDlg::OnMenuAddl() -{ -} - -LRESULT CmainDlg::onUsersDirectoryLoaded(WPARAM wParam, LPARAM lParam) -{ - PJ_LOG(3, (THIS_FILE, "Users directory loaded")); - URLGetAsyncData *response = (URLGetAsyncData *)wParam; - int expires = 0; - if (response->statusCode == 200 && !response->body.IsEmpty()) { - CXMLFile xmlFile; - if (xmlFile.LoadFromStream((BYTE*)response->body.GetBuffer(), response->body.GetLength())) { - BOOL ok = FALSE; - bool changed = false; - pageContacts->SetCanditates(); - CXMLElement *root = xmlFile.GetRoot(); - CXMLElement *directory = root->GetFirstChild(); - while (directory) { - if (directory->GetElementType() == XET_TAG) { - CXMLElement *entry = directory->GetFirstChild(); - while (entry) { - if (entry->GetElementType() == XET_TAG) { - CXMLElement *data = entry->GetFirstChild(); - CString number; - CString name; - char presence = -1; - while (data) { - if (data->GetElementType() == XET_TAG) { - CString dataName = data->GetElementName(); - CXMLElement *value = data->GetFirstChild(); - if (value->GetElementType() == XET_TEXT) { - if (dataName.CompareNoCase(_T("name")) == 0) { - name = Utf8DecodeUni(UnicodeToAnsi(value->GetElementName())); - } - else if (dataName.CompareNoCase(_T("extension")) == 0 || dataName.CompareNoCase(_T("number")) == 0 || dataName.CompareNoCase(_T("telephone")) == 0) { - number = Utf8DecodeUni(UnicodeToAnsi(value->GetElementName())); - } - else if (dataName.CompareNoCase(_T("presence")) == 0) { - CString rab = value->GetElementName(); - presence = !(rab.IsEmpty() || rab == _T("0") - || rab.CompareNoCase(_T("no")) == 0 - || rab.CompareNoCase(_T("false")) == 0 - || rab.CompareNoCase(_T("null")) == 0); - } - } - } - data = entry->GetNextChild(); - } - if (!number.IsEmpty()) { - if (pageContacts->ContactAdd(number, name, presence, 1, FALSE, TRUE) && !changed) { - changed = true; - } - if (!ok) { - ok = TRUE; - } - } - } - entry = directory->GetNextChild(); - } - } - directory = root->GetNextChild(); - } - if (ok) { - if (pageContacts->DeleteCanditates() || changed) { - pageContacts->ContactsSave(); - } - } - } - response->headers.MakeLower(); - CString search = _T("\r\ncache-control:"); - int n = response->headers.Find(search); - if (n > 0) { - n = n + search.GetLength(); - int l = response->headers.Find(_T("\r\n"), n); - if (l > 0) { - response->headers = response->headers.Mid(n, l - n); - search = _T("max-age="); - n = response->headers.Find(search); - if (n != -1) { - response->headers = response->headers.Mid(n + search.GetLength()); - expires = atoi(CStringA(response->headers)); - } - } - } - } - if (expires <= 0) { - expires = 3600; - } - else if (expires < 60) { - expires = 60; - } - else if (expires > 86400) { - expires = 86400; - } - SetTimer(IDT_TIMER_DIRECTORY, 1000 * expires, NULL); - - PJ_LOG(3, (THIS_FILE, "End UsersDirectoryLoad")); - delete response; - return 0; -} - -void CmainDlg::UsersDirectoryLoad() -{ - KillTimer(IDT_TIMER_DIRECTORY); - if (!accountSettings.usersDirectory.IsEmpty()) { - PJ_LOG(3, (THIS_FILE, "Users directory load")); - CString url; - url.Format(accountSettings.usersDirectory, accountSettings.account.username, accountSettings.account.password, get_account_server()); - url = msip_url_mask(url); - PJ_LOG(3, (THIS_FILE, "Begin UsersDirectoryLoad")); - URLGetAsync(url, m_hWnd, UM_USERS_DIRECTORY); - } -} - -void CmainDlg::AccountSettingsPendingSave() -{ - KillTimer(IDT_TIMER_SAVE); - SetTimer(IDT_TIMER_SAVE, 5000, NULL); -} - -void CmainDlg::CheckUpdates() -{ - CInternetSession session; - try { - CHttpFile* pFile; - CString url = _T("http://update.microsip.org/?version="); - url.Append(_T(_GLOBAL_VERSION)); -#ifndef _GLOBAL_VIDEO - url.Append(_T("&lite=1")); -#endif - pFile = (CHttpFile*)session.OpenURL(url, NULL, INTERNET_FLAG_TRANSFER_ASCII | INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE); - if (pFile) - { - DWORD dwStatusCode; - pFile->QueryInfoStatusCode(dwStatusCode); - if (dwStatusCode == 202) { - CString caption; - caption.Format(_T("%s %s"), _T(_GLOBAL_NAME), Translate(_T("Update Available"))); - CString message = Translate(_T("Do you want to update now?")); - CStringA body; - int i; - UINT len = 0; - do { - LPSTR p = body.GetBuffer(len + 1024); - i = pFile->Read(p + len, 1024); - len += i; - body.ReleaseBuffer(len); - } while (i>0); - //-- - if (!body.IsEmpty()) { - message.AppendFormat(_T("\r\n\r\n%s"), CString(body)); - } - if (::MessageBox(this->m_hWnd, message, caption, MB_YESNO | MB_ICONQUESTION) == IDYES) - { - OpenURL(_T("http://www.microsip.org/downloads")); -} -} - pFile->Close(); -} - session.Close(); - } - catch (CInternetException *e) {} -} - -#ifdef _GLOBAL_VIDEO -int CmainDlg::VideoCaptureDeviceId(CString name) -{ - unsigned count = 64; - pjmedia_vid_dev_info vid_dev_info[64]; - pjsua_vid_enum_devs(vid_dev_info, &count); - for (unsigned i = 0; i < count; i++) { - if (vid_dev_info[i].fmt_cnt && (vid_dev_info[i].dir == PJMEDIA_DIR_ENCODING || vid_dev_info[i].dir == PJMEDIA_DIR_ENCODING_DECODING)) { - CString vidDevName(vid_dev_info[i].name); - if ((!name.IsEmpty() && name == vidDevName) - || - (name.IsEmpty() && accountSettings.videoCaptureDevice == vidDevName)) { - return vid_dev_info[i].id; - } - } - } - return PJMEDIA_VID_DEFAULT_CAPTURE_DEV; -} - -void CmainDlg::createPreviewWin() -{ - if (!previewWin) { - previewWin = new Preview(this); - } - previewWin->Start(VideoCaptureDeviceId()); -} -#endif diff --git a/microsip/mainDlg.h b/microsip/mainDlg.h deleted file mode 100644 index d707a265..00000000 --- a/microsip/mainDlg.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#pragma once - -#include "stdafx.h" - -#include - -#include "define.h" -#include -#include - -#ifndef _WIN64 -#ifdef NDEBUG -#ifdef _GLOBAL_VIDEO -#pragma comment(lib, "libpjproject-i386-Win32-vc14-Release-Static-Video.lib") -#else -#pragma comment(lib, "libpjproject-i386-Win32-vc14-Release-Static-NoVideo.lib") -#endif -#else -#pragma comment(lib, "libpjproject-i386-Win32-vc14-Debug-Static.lib") -#endif -#else -#ifdef NDEBUG -#ifdef _GLOBAL_VIDEO -#pragma comment(lib, "libpjproject-x86_64-x64-vc14-Release-Static-Video.lib") -#else -#pragma comment(lib, "libpjproject-x86_64-x64-vc14-Release-Static-NoVideo.lib") -#endif -#else -#pragma comment(lib, "libpjproject-x86_64-x64-vc14-Debug-Static.lib") -#endif -#endif - -#include "MMNotificationClient.h" - -#include "BaseDialog.h" -#include "RinginDlg.h" -#include "AccountDlg.h" -#include "SettingsDlg.h" -#include "ShortcutsDlg.h" -#include "MessagesDlg.h" - -#include "Dialer.h" -#include "Contacts.h" -#include "Calls.h" -#include "Preview.h" -#include "Transfer.h" -#include "addons.h" - -// CmainDlg dialog -class CmainDlg : public CBaseDialog -{ - // Construction -public: - CmainDlg(CWnd* pParent = NULL); // standard constructor - ~CmainDlg(); - - // Dialog Data - enum { IDD = IDD_MAIN }; - - bool m_startMinimized; - CPoint windowSize; - CButton m_ButtonMenu; - SettingsDlg* settingsDlg; - bool shortcutsEnabled; - bool shortcutsBottom; - ShortcutsDlg* shortcutsDlg; - MessagesDlg* messagesDlg; - Transfer* transferDlg; - AccountDlg* accountDlg; - - Dialer* pageDialer; - Contacts* pageContacts; - Calls* pageCalls; - - BOOL notStopRinging; - CArray ringinDlgs; - CString dialNumberDelayed; - pjsua_call_id autoAnswerCallId; - pjsua_acc_config acc_cfg; - - pjsua_transport_id transport_udp_local; - pjsua_transport_id transport_udp; - pjsua_transport_id transport_tcp; - pjsua_transport_id transport_tls; - pjsua_player_id player_id; - - int iconStatusbar; - int widthAdd; - int heightAdd; - bool missed; - - CString callIdIncomingIgnore; - CList toneCalls; - CList attendedCalls; - CList audioCodecList; - CList confernceCalls; - - void OnCreated(); - void PJCreate(); - void PJDestroy(); - void PJAccountAdd(); - void PJAccountAddLocal(); - void PJAccountDelete(bool deep = false); - void PJAccountDeleteLocal(); - void PJAccountConfig(pjsua_acc_config *acc_cfg); - - void CommandLine(CString params); - void TabFocusSet(); - void UpdateWindowText(CString = CString(), int icon = IDI_DEFAULT, bool afterRegister = false); - void PublishStatus(bool online = true, bool init=false); - void BaloonPopup(CString title, CString message, DWORD flags = NIIF_WARNING); - bool GotoTabLParam(LPARAM lParam); - bool GotoTab(int i, CTabCtrl* tab = NULL); - void DialNumberFromCommandLine(CString number); - void DialNumber(CString params); - bool MakeCall(CString number, bool hasVideo = false); - bool MessagesOpen(CString number); - void AutoAnswer(pjsua_call_id call_id); - void ShortcutAction(Shortcut *shortcut); - void PlayerPlay(CString filename, bool noLoop = false, bool inCall = false); - BOOL CopyStringToClipboard( IN const CString & str ); - void OnTimerCall (); - - void UsersDirectoryLoad(); - void OnTimerContactBlink(); - afx_msg LRESULT onUsersDirectoryLoaded(WPARAM wParam,LPARAM lParam); - void SetupJumpList(); - void RemoveJumpList(); - void MainPopupMenu(); - void SetPaneText2(CString str = _T("")); - void AccountSettingsPendingSave(); - void UpdateSoundDevicesIds(); - void PlayerStop(); - -#ifdef _GLOBAL_VIDEO - Preview* previewWin; - int VideoCaptureDeviceId(CString name=_T("")); -#endif - -protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - - // Implementation -protected: - HICON m_hIcon; - HICON iconSmall; - HICON iconInactive; - HICON iconMissed; - NOTIFYICONDATA tnd; - CStatusBar m_bar; - - CMMNotificationClient *mmNotificationClient; - - unsigned char m_tabPrev; - - DWORD m_lastInputTime; - int m_idleCounter; - pjrpid_activity m_PresenceStatus; - bool newMessages; - - afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); - afx_msg void OnDestroy(); - virtual BOOL OnInitDialog(); - virtual void PostNcDestroy(); - virtual BOOL PreTranslateMessage(MSG* pMsg); - - // Generated message map functions - afx_msg LRESULT OnUpdateWindowText(WPARAM wParam,LPARAM lParam); - afx_msg LRESULT onTrayNotify(WPARAM, LPARAM); - afx_msg LRESULT onCreateRingingDlg(WPARAM, LPARAM); - afx_msg LRESULT onRefreshLevels(WPARAM wParam,LPARAM lParam); - afx_msg LRESULT onRegState2(WPARAM wParam,LPARAM lParam); - afx_msg LRESULT onCallState(WPARAM wParam,LPARAM lParam); - afx_msg LRESULT onMWIInfo(WPARAM wParam,LPARAM lParam); - afx_msg LRESULT onCallMediaState(WPARAM, LPARAM); - afx_msg LRESULT onCallTransferStatus(WPARAM, LPARAM); - afx_msg LRESULT onPager(WPARAM, LPARAM); - afx_msg LRESULT onPagerStatus(WPARAM, LPARAM); - afx_msg LRESULT onBuddyState(WPARAM, LPARAM); - afx_msg LRESULT onCopyData(WPARAM, LPARAM); - afx_msg LRESULT CreationComplete(WPARAM, LPARAM); - DECLARE_MESSAGE_MAP() -public: - afx_msg LRESULT onPowerBroadcast(WPARAM, LPARAM); - afx_msg void OnSysCommand(UINT nID, LPARAM lParam); - afx_msg BOOL OnQueryEndSession(); - afx_msg void OnBnClickedOk(); - afx_msg void OnBnClickedMenu(); - afx_msg void OnClose(); - afx_msg void OnContextMenu(CWnd *pWnd, CPoint point ); - afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD_PTR dwData); - afx_msg void OnSessionChange(UINT nSessionState, UINT nId); - afx_msg void OnMove(int x, int y); - afx_msg void OnSize(UINT type, int w, int h); - afx_msg LRESULT onShellHookMessage(WPARAM wParam,LPARAM lParam); - afx_msg LRESULT onCallAnswer(WPARAM wParam,LPARAM lParam); - afx_msg LRESULT onCallHangup(WPARAM wParam,LPARAM lParam); - afx_msg LRESULT onTabIconUpdate(WPARAM wParam,LPARAM lParam); - afx_msg LRESULT onSetPaneText(WPARAM wParam,LPARAM lParam); - afx_msg LRESULT onPlayerPlay(WPARAM wParam,LPARAM lParam); - afx_msg LRESULT onPlayerStop(WPARAM wParam,LPARAM lParam); - afx_msg LRESULT OnAccount(WPARAM wParam,LPARAM lParam); - afx_msg void OnMenuAccountAdd(); - afx_msg void OnMenuAccountChange(UINT nID); - afx_msg void OnMenuAccountEdit(UINT nID); - afx_msg void OnMenuCustomRange(UINT nID); - afx_msg void OnMenuSettings(); - afx_msg void OnMenuShortcuts(); - afx_msg void OnMenuAlwaysOnTop(); - afx_msg void OnMenuLog(); - afx_msg void OnMenuExit(); - afx_msg void OnTimer (UINT_PTR TimerVal); - afx_msg void OnTcnSelchangeTab(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnTcnSelchangingTab(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnMenuWebsite(); - afx_msg void OnMenuHelp(); - afx_msg void OnMenuAddl(); - afx_msg void CheckUpdates(); -#ifdef _GLOBAL_VIDEO - afx_msg void createPreviewWin(); -#endif -}; - -extern CmainDlg *mainDlg; diff --git a/microsip/microsip.cpp b/microsip/microsip.cpp deleted file mode 100644 index 8fafd690..00000000 --- a/microsip/microsip.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -// microsip.cpp : Defines the class behaviors for the application. -// -#include "stdafx.h" -#include "microsip.h" -#include "mainDlg.h" -#include "const.h" -#include "settings.h" - -#include "Strsafe.h" - -#include -#include -#include -//#include "SDL.h" - -#pragma comment(lib, "Psapi") -#pragma comment(lib, "Dbghelp") - -#ifdef _DEBUG -#define new DEBUG_NEW -#endif - - -// CmicrosipApp - -BEGIN_MESSAGE_MAP(CmicrosipApp, CWinApp) - ON_COMMAND(ID_HELP, &CWinApp::OnHelp) -END_MESSAGE_MAP() - - -// CmicrosipApp construction - -CmicrosipApp::CmicrosipApp() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - - -// The one and only CmicrosipApp object - -CmicrosipApp theApp; - -// CmicrosipApp initialization - -CStringA wineVersion() { - static const char * (CDECL *pwine_get_version)(void); - HMODULE hntdll = GetModuleHandle(_T("ntdll.dll")); - if (hntdll) { - pwine_get_version = (const char* (*)())(void *)GetProcAddress(hntdll, "wine_get_version"); - if (pwine_get_version) { - return pwine_get_version(); - } - } - return "n/a"; -} - -LONG WINAPI ExceptionFilter(EXCEPTION_POINTERS *ExceptionInfo) -{ - CTime tm = CTime::GetCurrentTime(); - CString filename; - CFile file; - // mini dump - filename.Format(_T("%sdump%s.dmp"), accountSettings.pathLocal, tm.Format(_T("%Y%m%d%H%M%S"))); - if (file.Open(filename, CFile::modeCreate | CFile::modeReadWrite)) { - MINIDUMP_EXCEPTION_INFORMATION MinidumpExceptionInfo; - MinidumpExceptionInfo.ThreadId = GetCurrentThreadId(); - MinidumpExceptionInfo.ExceptionPointers = ExceptionInfo; - MinidumpExceptionInfo.ClientPointers = FALSE; - if (MiniDumpWriteDump( - GetCurrentProcess(), - GetCurrentProcessId(), - file.m_hFile, - MiniDumpNormal, - //MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory | MiniDumpWithFullMemory), - &MinidumpExceptionInfo, - NULL, - NULL - )) { - } - file.Close(); - } - if (pj_ready && pjsua_var.state == PJSUA_STATE_RUNNING && tm.GetTime() - startTime.GetTime() > 10) { - // automatic restart after sip crash - ShellExecute(NULL, NULL, accountSettings.exeFile, NULL, NULL, SW_SHOWDEFAULT); - return EXCEPTION_EXECUTE_HANDLER; - } - else { - AfxMessageBox(_T("We are sorry but microsip crash happened.\r\nIf this problem is permanent and you know how to reproduce it, please contact us with details for fixing this error. Email: info@microsip.org"), MB_ICONERROR); - return EXCEPTION_EXECUTE_HANDLER; - } - return EXCEPTION_CONTINUE_SEARCH; -} - -struct MsipEnumWindowsProcData { - HINSTANCE hInst; - HWND hWnd; -}; - -BOOL CALLBACK MsipEnumWindowsProc(HWND hWnd, LPARAM lParam) -{ - MsipEnumWindowsProcData *data = (MsipEnumWindowsProcData *)lParam; - HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE); - if (hInstance && hInstance == data->hInst && GetWindow(hWnd, GW_OWNER) == (HWND)0) { - TCHAR className[256]; - if (GetClassName(hWnd, className, 256)) { - if (StrCmp(className, _T(_GLOBAL_NAME)) == 0) { - //-- - DWORD dwProcessID; - GetWindowThreadProcessId(hWnd, &dwProcessID); - HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | - PROCESS_VM_READ, FALSE, dwProcessID); - if (hProcess) { - TCHAR exeFilePath[MAX_PATH]; - if (GetModuleFileNameEx(hProcess, NULL, exeFilePath, MAX_PATH)) { - if (StrCmpI (exeFilePath, accountSettings.exeFile) == 0) { - data->hWnd = hWnd; - return FALSE; - } - } - CloseHandle(hProcess); - } - //-- - } - } - } - return TRUE; -} - -BOOL CmicrosipApp::InitInstance() -{ - SetUnhandledExceptionFilter(ExceptionFilter); - MsipEnumWindowsProcData data; - data.hInst = AfxGetInstanceHandle(); - HWND hWndRunning = NULL; - if (!EnumWindows(MsipEnumWindowsProc, (LPARAM)&data)) { - hWndRunning = data.hWnd; - } - if (hWndRunning) { - if ( lstrcmp(theApp.m_lpCmdLine, _T("/exit"))==0) { - ::SendMessage(hWndRunning, WM_CLOSE, NULL, NULL); - } else if ( lstrcmp(theApp.m_lpCmdLine, _T("/minimized"))==0) { - } else if ( lstrcmp(theApp.m_lpCmdLine, _T("/hidden"))==0) { - } else { - if (!accountSettings.silent) { - ::ShowWindow(hWndRunning, SW_SHOW); - ::SetForegroundWindow(hWndRunning); - } - if (lstrlen(theApp.m_lpCmdLine)) { - COPYDATASTRUCT cd; - cd.dwData = 1; - cd.lpData = theApp.m_lpCmdLine; - cd.cbData = sizeof(TCHAR) * (lstrlen(theApp.m_lpCmdLine) + 1); - ::SendMessage(hWndRunning, WM_COPYDATA, NULL, (LPARAM)&cd); - } - } - return FALSE; - } else { - if ( lstrcmp(theApp.m_lpCmdLine, _T("/exit"))==0 - || lstrcmp(theApp.m_lpCmdLine, _T("/answer")) == 0 - || lstrcmp(theApp.m_lpCmdLine, _T("/hangupall")) == 0 - ) { - return FALSE; - } - } - - // InitCommonControlsEx() is required on Windows XP if an application - // manifest specifies use of ComCtl32.dll version 6 or later to enable - // visual styles. Otherwise, any window creation will fail. - // Set this to include all the common control classes you want to use - // in your application. - INITCOMMONCONTROLSEX InitCtrls; - InitCtrls.dwSize = sizeof(InitCtrls); - InitCtrls.dwICC = ICC_LISTVIEW_CLASSES | - ICC_LINK_CLASS | - ICC_BAR_CLASSES | - ICC_LINK_CLASS | - ICC_STANDARD_CLASSES | - ICC_TAB_CLASSES | - ICC_UPDOWN_CLASS; - - InitCommonControlsEx(&InitCtrls); - - //AfxEnableControlContainer(); - - CoInitializeEx(NULL, COINIT_MULTITHREADED); - - AfxInitRichEdit2(); - - WNDCLASS wc; - // Get the info for this class. - // #32770 is the default class name for dialogs boxes. - ::GetClassInfo(AfxGetInstanceHandle(), L"#32770", &wc); - wc.lpszClassName = _T(_GLOBAL_NAME); - // Register this class so that MFC can use it. - if (!::AfxRegisterClass(&wc)) return FALSE; - - CmainDlg *mainDlg = new CmainDlg; - m_pMainWnd = mainDlg; - - if (!m_pMainWnd) { - // Since the dialog has been closed, return FALSE so that we exit the - // application, rather than start the application's message pump. - return FALSE; - } - - //-- - LRESULT pResult; - mainDlg->OnTcnSelchangeTab(NULL, &pResult); - - mainDlg->OnCreated(); - - //-- - - return TRUE; - -} diff --git a/microsip/microsip.h b/microsip/microsip.h deleted file mode 100644 index 4c857b0e..00000000 --- a/microsip/microsip.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -// microsip.h : main header file for the PROJECT_NAME application -// - -#pragma once - -#ifndef __AFXWIN_H__ - #error "include 'stdafx.h' before including this file for PCH" -#endif - -#include "resource.h" // main symbols - -// CmicrosipApp: -// See microsip.cpp for the implementation of this class -// - -class CmicrosipApp : public CWinApp -{ -public: - CmicrosipApp(); - -// Overrides - public: - virtual BOOL InitInstance(); -// Implementation - - DECLARE_MESSAGE_MAP() -}; - -extern CmicrosipApp theApp; diff --git a/microsip/microsip.vcxproj b/microsip/microsip.vcxproj deleted file mode 100644 index 0019b1cc..00000000 --- a/microsip/microsip.vcxproj +++ /dev/null @@ -1,346 +0,0 @@ -īģŋ - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {BB46A3FD-3E25-44BF-9DED-36A8E838A095} - microsip - MFCProj - 8.1 - - - - Application - Static - true - Unicode - v140_xp - - - Application - Static - true - Unicode - v140_xp - - - Application - Static - Unicode - v140_xp - - - Application - Static - Unicode - v140_xp - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>14.0.25431.1 - - - MinimumRecommendedRules.ruleset - - - - - MinimumRecommendedRules.ruleset - - - - - MinimumRecommendedRules.ruleset - - - - - MinimumRecommendedRules.ruleset - - - - - - _DEBUG;%(PreprocessorDefinitions) - false - true - - - ..\lib\pjproject\pjlib\include;..\lib\pjproject\pjsip\include;..\lib\pjproject\pjmedia\include;..\lib\pjproject\pjnath\include;..\lib\pjproject\pjlib-util\include;..\lib\pjproject\third_party\sdl\include;..\lib\pjproject\third_party\openssl\Win32\include;.;%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - EditAndContinue - Disabled - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - $(IntDir);%(AdditionalIncludeDirectories) - - - vpxmt.lib;opus.lib;Wtsapi32.lib;%(AdditionalDependencies) - ..\lib\opus\win32\VS2015\Win32\Debug\;..\lib\vp8vfw\vp8\lib\x64;..\lib\pjproject\lib;..\lib\pjproject\third_party\lib\;..\lib\pjproject\third_party\openssl\$(Platform)\lib\;..\lib\pjproject\third_party\ipp\$(Platform)\;..\lib\pjproject\third_party\opus\$(Platform)\;..\lib\pjproject\third_party\silk\$(Platform)\$(Configuration)\;..\lib\pjproject\third_party\ffmpeg\$(Platform)\;..\lib\pjproject\third_party\vpx\$(Platform)\;..\lib\pjproject\third_party\sdl\$(Platform)\;..\lib\pjproject\third_party\opencore-amrnb\$(Platform)\;..\lib\pjproject\third_party\vo-amrwbenc\$(Platform)\;..\lib\pjproject\third_party\opencore-amrwb\$(Platform)\;%(AdditionalLibraryDirectories) - Windows - false - /OPT:NOLBR %(AdditionalOptions) - - - - - false - - - - - _DEBUG;%(PreprocessorDefinitions) - false - - - ..\pjlib\include;..\pjsip\include;..\pjmedia\include;..\pjnath\include;..\pjlib-util\include;..\third_party\sdl\include;..\third_party\openssl\Win32\include;.;%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - EditAndContinue - Disabled - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - $(IntDir);%(AdditionalIncludeDirectories) - - - vpxmt.lib;opus.lib;Wtsapi32.lib;%(AdditionalDependencies) - ..\lib\;..\third_party\lib\;..\third_party\openssl\$(Platform)\lib\;..\third_party\ipp\$(Platform)\;..\third_party\opus\$(Platform)\;..\third_party\silk\$(Platform)\$(Configuration)\;..\third_party\ffmpeg\$(Platform)\;..\third_party\vpx\$(Platform)\;..\third_party\sdl\$(Platform)\;..\third_party\opencore-amrnb\$(Platform)\;..\third_party\vo-amrwbenc\$(Platform)\;..\third_party\opencore-amrwb\$(Platform)\;%(AdditionalLibraryDirectories) - Windows - /OPT:NOLBR %(AdditionalOptions) - - - - - false - - - - - NDEBUG;%(PreprocessorDefinitions) - false - true - - - ..\pjlib\include;..\pjsip\include;..\pjmedia\include;..\pjnath\include;..\pjlib-util\include;..\third_party\sdl\include;..\third_party\openssl\Win32\include;.;%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) - MultiThreaded - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - $(IntDir);%(AdditionalIncludeDirectories) - - - vpxmt.lib;opus.lib;Wtsapi32.lib;%(AdditionalDependencies) - ..\lib\;..\third_party\lib\;..\third_party\openssl\$(Platform)\lib\;..\third_party\ipp\$(Platform)\;..\third_party\opus\$(Platform)\;..\third_party\silk\$(Platform)\$(Configuration)\;..\third_party\ffmpeg\$(Platform)\;..\third_party\vpx\$(Platform)\;..\third_party\sdl\$(Platform)\;..\third_party\opencore-amrnb\$(Platform)\;..\third_party\vo-amrwbenc\$(Platform)\;..\third_party\opencore-amrwb\$(Platform)\;%(AdditionalLibraryDirectories) - true - true - Windows - /OPT:NOLBR %(AdditionalOptions) - - - - - false - - - - - NDEBUG;%(PreprocessorDefinitions) - false - - - ..\pjlib\include;..\pjsip\include;..\pjmedia\include;..\pjnath\include;..\pjlib-util\include;..\third_party\sdl\include;..\third_party\openssl\Win32\include;.;%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) - MultiThreaded - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - $(IntDir);%(AdditionalIncludeDirectories) - - - vpxmt.lib;opus.lib;Wtsapi32.lib;%(AdditionalDependencies) - ..\lib\;..\third_party\lib\;..\third_party\openssl\$(Platform)\lib\;..\third_party\ipp\$(Platform)\;..\third_party\opus\$(Platform)\;..\third_party\silk\$(Platform)\$(Configuration)\;..\third_party\ffmpeg\$(Platform)\;..\third_party\vpx\$(Platform)\;..\third_party\sdl\$(Platform)\;..\third_party\opencore-amrnb\$(Platform)\;..\third_party\vo-amrwbenc\$(Platform)\;..\third_party\opencore-amrwb\$(Platform)\;%(AdditionalLibraryDirectories) - true - true - Windows - /OPT:NOLBR %(AdditionalOptions) - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/microsip/microsip.vcxproj.filters b/microsip/microsip.vcxproj.filters deleted file mode 100644 index 153125c3..00000000 --- a/microsip/microsip.vcxproj.filters +++ /dev/null @@ -1,328 +0,0 @@ -īģŋ - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - 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 - - - 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 - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - - - Resource Files - - - Resource Files - - - Resource Files - - - - - - - Resource Files - - - - - Resource Files - - - Resource Files - - - Resource Files - - - - - - \ No newline at end of file diff --git a/microsip/microsip.vcxproj.user b/microsip/microsip.vcxproj.user deleted file mode 100644 index abe8dd89..00000000 --- a/microsip/microsip.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ -īģŋ - - - \ No newline at end of file diff --git a/microsip/res/active-secure.ico b/microsip/res/active-secure.ico deleted file mode 100644 index 33e077f1c564d6a4ba9d51764ca6071d9674de07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmbu9SxggA6o#(|Xp|t)s4)aJ`of#O=(F*`U9j2~3*thIOAIOy5)g~lZkio&&ixQ-#zD^J9ikH$FGP8 z#_wy{sbI!dFvg;}xQlyc{M-m**|1tnXD@~&>wklm-iOTV1fBAq%Ug`EEmODN2 zvR<#s{N6(I6m}NJ^Yn;!$_k=QZ0wHMuCHMiICOA3%YK*iS3#pEKyA$ywZntIaOGnrAAoA zH-wdpW1Dv33-OQo9xqNYrbDV%Ag=b%ALVmC?!_op={$%u15t`pL`lzJjRjbv_dxOT z(`VvuwHGW%Zb=bxiagc8*8oX}7n{0)%>%%Or#;xHbs@SJhV10I zpS-k=_`1U|PgtQD`iN_NpHbX9g^O?fNE`4X-9C=vP9I7-N5+WHFl9ql8!zybSHaoW zA8fq+K-;7p4LS{8nJsX82EluUW@{5{P4)OXHF=l#g!-d?s#{*0fW5i{XdZ1r;8y^& z{!CL2I$Z7OvbW*QU>j`1HZ&UQVKg=(5D4u2n~&jat~DRu1K(kI*Cf=D)Nle19p$jQ zI^cG@(cj+>v&{^xOE=BSizHsGf4gQ6bVD^l-9H1?yE!}2Z|+ThGtCVEM27RF3C%3IEh%D6uY#s zpzl#+L`%M7ydM-xjL3`j#+%!@X{{NM=;gC=)1H!#-cgJgKi3x6?*(5lLBG}F ztVW2#LWm;-a*=1-Pe!go6+$rn=eob#zcsY_c=N&XK&Uoi(A}8t3He@L+jLI4B>3L< z;%dm7_37>`-K7kRSL*ZBoGE67Ibnxw;v_5yheUI-1q^;R#jWsUE+DYj>n~;tF}gNZ z(KXu*bKEZXD;`^8%!1l*1Hph}5d+*)?HE{j)DwI+bU>Zc`?_!6xtXqAG3&+~;eGDI zlMi8u>vMj2#`#$f2Hyq?{K1uAs4;FS#O6926Q_{=@)R4n4XCyDV;!#4Y1EIOK>wSE zAr+r=fhFlE)M_X0tM3bvHo88B$j7L>A6^|n%VZmx;x;fx@mXiC)tYpoA=-rLuQSO1 z&LgmJOV-4>bWC?rPOY#eoH7n`O8Exj`sV}4<#R|;?wki}&m69a&sW;+kw%b~lArmO1;r@p3G;2Tr{*I4xEI_L1D(-I z`VPMzL3ifjE-v#;@n)3vk7t2r!kuo1F=|F##0Z{8m9MhwYfGQmH9tznn~S&oo{U${ zD(j|rf9KZ=-lO)H+P_$kER bYUvUj>>xoS^xB%TZMe$yT5pwJOK$N8z@y#u diff --git a/microsip/res/away.ico b/microsip/res/away.ico deleted file mode 100644 index 5727cb350033a1781b2f12a9c457eb770b9049e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmbu7O-LJ25XVPS4<00*DnbvYP^fqk3Q{cCYtEjFy@;h%{Gh0fw(+ZAqOz0{ONb2y zL?}Uu2C*dyS)(GxlzJ%r041e0_Ub{&p}v1-5*J=fa%RYm-+ zrAOC@t`pI1hC>|5#o5q(&Rt~znA|?XsV5FhFyeD;s-RadRZ=GfX@D~1V)`j#Y#D#u z8vwbOfeYAoo7@2~@_O`Aq~c`-x>md3oOfbyeF*X2ta--tF+U5puH_tUkV3L8s0Vp>LMnhmU1V%#u76SkOGcZts E0nhd!VgLXD diff --git a/microsip/res/busy.ico b/microsip/res/busy.ico deleted file mode 100644 index 66eed48f2cab62b04d968a1052dcadc3f4c5ce39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmbu7KWGzi6vtnQ9Xj;SP*VEe2!bJ$kU@%csB0&O4244ISP`YPgGv=erL<`ysn8^b z=#la=`s#%lNNOwq~`=rto zbC1-8PYcCR=oB{FF}k~t(be^b<8Lf3p703xO*1Ab-Z0&O@wej`S{=fJ_YaXy7h$#L z(a}+W!%>9YuA#LxkEW(9c6KzF{C5eFR0L!3G4ML@^2=*@y&6VFiby1YSggXvMj3AR z38tr2vww;Z_!_{(y9v-Og0j5|pRWXur)=^klfdwB0W&iNv;T4B`QDFSxMOaFx5L=q z2fuq6y}f|bS)r$=jLuGt_pxO1*FUSr((V%I5kYc^{?C3yqkzi=^z~J6I?GU$Qq}%7 z&o*Q2+ZyOLnV3t?VfP@1JHBc2wPF2m9sK>OxHNkiHzFQ=j~@vavjm6E`3Iyp1Z;>Z2j1R zBj~7!)TK}N7-Rpdeq`0`*?f7%c}QLQj6OXdj1I=--^={UAoVjvYhz#zuJz@P!dKp~(AL>x#lH~{6y0grB-`@d~k?*AP#3jRNP zaQ#2AW`NXgos#u`Y8co5T?LB&cK|VnPmKO!>nHs0^koL?dDv_9|52aye-J%6g!BK? zdspz9v3Ehu|4AVn|1UQig7ty)g7Cd=i~sXt1pZ$?wGF5KU31F*PY>t*f2+d`Y~P+D zWw5?um74$i1KIxXoK=id@BXEYV87n&vHH$ImquIcY@SUj}Zf#aiLNF z|EyG16nB8+&+lCdw-=-b9e~tKix&MqKS>%zFSe2^I+j86?Ia{t>I82+&{F#KU= uVE6&VAAsx!{0s~SfHpJ&aWjz548lM;W<~}Eb_WKA^A8yq{(lBypgaJaVoeJG diff --git a/microsip/res/callmiss.ico b/microsip/res/callmiss.ico deleted file mode 100644 index 9031fd528db037b659ca7925fcce7349d55bdcd3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmcgq%PT}t82?0Bva+_c_kP93Tz6>R_dk$qY$O{NUL`5=iV*TBLPWAK4I*hW9?9Ft zV?m^p(j?8#cg~pcoN2OfZ@+ua{l4#azQ^wnMerLNOZ<(ek|?4$B1&Mei7h@mFOgps{laCl~h!_Y4tR-)cu{{xI?kTMU={4~IWIRd^*FfRt}Y?HXE_y;^M^UoQPLYFieOr1YS)Y6gz=v!LA3=`DG_+4{s>kE|h7uFo?(IK7p# zGFt9o(_WFGPD1qYIVRLzXrwdj$Qc!wFHu}E88&xw?^@RSp%IX-j(_3j6xi_{{(34K z7oZsT13DF&uTWGz@q_Qv-=|}iekR~AtDc2wItl12bf0$|2K*wA$Q_Ko>O6-yBV8Rs zwtoIseM9m6eK>coFlXQYlGpG1-g~mr_iLO#{y$eV5P74CUL%P-j7Q#I#1M&FUc;zk PMAm&En)llbuwCE{L|->| diff --git a/microsip/res/callout.ico b/microsip/res/callout.ico deleted file mode 100644 index 07aff89b8b959c343e7e1859ea7821db08d82380..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmbV~-%FEW6vvOOZT`ybCa2R2C0IiLK$qP*Co$doZg(Pd;hlF<1i~0(C{46xItoi7 z2!uHohL$-m)Dea@G_j}@6ua!Qi|Fe)&*)*oyJ5XA-@VU!-t+lB=Q(FY6@0th#J?@n zcY&y$h}u{j;z%LR54z6Z{^#00`hq(P2@JlT#NLlXoYzBgZ@+qg#<32#(m}ZAg6jP| zd~zd&=DY2RvF}D;|HR^F*>i8H|OntHw1DP>24g1maVi1daxsvRY zTw3{8elQ`t)KG4(;vVLYzp7qUZ5VLuMBteWK+aK|Q*JFYa?J--k7`yzh|JtN!_ICm zLuBQVJJ?aR>KSpLJre<)E1WNB!Z#kW^yp8Gpl+c{LGg7IuX^Vc5rqI%tclY4UI zp`ksl#toHo^JNSdm%8=urJQ@-KT$=8* z?0K<=`XBNceWP7^59!O=x4f>+s!tM=`v3B>E|q5$m;7S+rp$lhtvn@$A)-G{qTe>6 jU#y?JK5!9b**(gNO%vJp-DYQ15ILhnTZhc8viSQcghe%Y diff --git a/microsip/res/close.ico b/microsip/res/close.ico deleted file mode 100644 index cfc26b7cb2fb9358159edbcc5e45515c17f82897..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 198 zcmZQzU<5(|0VXiLfq{WR42U&=SOAC>fEXkX0u5jiLNFn*|NsAw#3PRhG6Eg{KF`4L acRoq_sSt4ct diff --git a/microsip/res/close2.ico b/microsip/res/close2.ico deleted file mode 100644 index 0a4d931fc1b4670cc27ee7ddf0b25ca1b45d7ef2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lH~{5F0bN3%9*Zp?F>K;kl!Aqj z)sm_g+04P97uhe!Zo|dK=4MjOz-9KRI8q4w|IfgHj(?wLVE8*9C~nWd@DCX3fA%vl L{Jf8;4x|qNQH&=O diff --git a/microsip/res/conference-secure.ico b/microsip/res/conference-secure.ico deleted file mode 100644 index 4c29252c0643d8e633a0aad33631765d41b4a3e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmb7@O-NKx6vwaFBFIdN5*fs(&8(_T(xw)ziWX*=QlNok1np{75ehOT2t^R7ITD(Z zqJvruqcwgE>4;;-bH;JL9Gy=;p6JWb5@lxo-Sei0A~@uI{NFkE-19s4yvu!zrSK;s zgYoxCcK-llCm3UDE*|2MM4TIW96Q7q>3;?Qb?s2Vbh*|Z$=BL`-Dq-4h0PwRxM@-< zY;;7l=HN)OIv8(om$cfW=~Ye~)mV}FavE7&nN>C%uXf>P+sx`-JbE6DL(qDzcl&Wf zJBRe#d&`_@Bb7d$}D2$1tx zLYXOmqfVO#J)-Ye2-km%ej^k{SwM;kVQVllr{1d?c@}n)}BuR9YLU9Ojw0ia*|ofB{sAH{D~#( ze);_7>2~ed5*F6BP}1gY-w#i{Q9hS)hVr*3>zUTT|A2T3V|0-fRq#1W-Btzn2U9N` M9(=)tZTUI-7g+QLtpET3 diff --git a/microsip/res/conference.ico b/microsip/res/conference.ico deleted file mode 100644 index 7e12f83cfea9f222944d9346fc990a34538decd9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmchWF-rqM5QQhi&cc9TZRsyaXKyDqc1ExgTYta>f?8XJ1ciuNNVGiBLcLZ)Dj`aU zNH7t(fQ_IiG2^^F$Lt-KXyt~NcQd=+?97D_CFGMzk$g|m@(9rc5lx9CC7B>EX4d#9 z5%eF6Pgbj3Ovg+1hV@|B)0HaMOB^fg4XI)7RkpFq+&*UZy}%J;ubAdRJ%o6$uQ$xy zcHoHXB{LUzr?Od?ahGyYp}x5X_kzWO`(B8hy>#;P_uCvN)R@lKLPBrax7=yCh2{>g z`7RfpFN`BbJ+K+K!_GAu;aPI~7N3)IM_{ksZ@JZbG>%yL^&0cx1M|5bxXq&u=9YWU zz+%DChw@-sZ}RFs1CR1r1HIZpU7VfUYm~Pt9aB4Va957wksCB8_H60wwqyUdIqmb& zXYhZSGsiIbTo>AZ7&u<)eR&y->fL?;AD+yIrVoLUvm1i%xIOc7L IxUZ(LUr~eA5dZ)H diff --git a/microsip/res/default.ico b/microsip/res/default.ico deleted file mode 100644 index 5ee77128f35977f59b89450c29c57140fc33b42e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmb_cJ!`^H6upJ6Qm3x%*q_lU1Oz4EA`VVM!O10p5F{B~%&3cl`V#~f2M0F?w+v1} z{1uX+aC%R=)b>6~p)Z^qI3Ky;-8FGn!;kvXU^)kS}pANdqh!$BuPxB&z#lobUHX3 z4(RoIPS9u0>UX@#PvzZh0nX~%C;SksB71Qa|3Hr=g{n2Q&;X8Y|TyQ?0e}FoD<{bTsKKq5v bFI=Fnee?UVuKAnB|G`5c^7Q^Uu*3BMYi!JA diff --git a/microsip/res/delete.bmp b/microsip/res/delete.bmp deleted file mode 100644 index 9893694c199ccd0b64726ffeccb2d2a10809a8fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 824 zcmY+B%TE(g6vn^fW22#(b7~|iCZuiRrqxAbOcxZ{umGE&O9C5B`Nv$kFowh!p9tj* z^0El+P#B6Z1(`mOX{RN4rih6r-#t0!cfNaP=1$j>M;FnIhnnx{y8d?&TATcW&iU%u zY64Ax;Jok{tK_T5i0~(tkHYUo-if>wRt<{`3%?P56%4*?@y!xOfid6Zm;U!=u-kCo2 zqLEB4st1^FYBG_SajG>P3=C$JFn<>Q4t#5GPn)L4UDr(}SM(@g?%C6Ya=EIoRBA+{ zYrqoosK^>fw=72@8N=|Vr>7?agX!+>CC72Ku?lWSJgWxKDsxJBgJ_Mg4y=a5In(q! z`VN(f_c*)Q=^e?EojW^jCVRH)Bspa1NDV}m@QPpd z0ac-|@1Rog%*A3O7CQ`u4otJIt?Sm4L%-BOIMmA#v4O)t(5_a!X`#^Q=qM>sMZ)%m z;X(Z`u~-o(v*;(6wYbw(-ZEXwI(gi6q%Eid@^~a%HjKJ$*B{)k07uLlA`Vd%a9VFV zw{AOHX!}pv`fnWHZBwqW&b;kwIVP$Rxqv4v&gH@XdClir4Fqb!4$E(m60?", IDC_SETTINGS_HELP_SINGLE_MODE, "SysLink", 0x0, 96, IDD_SETTINGS_OFFSET_INITIAL, 7, 8 - CONTROL "?", IDC_SETTINGS_HELP_RINGING_SOUND, "SysLink", 0x0, 265, 2+IDD_SETTINGS_OFFSET_CUSTOM_INI, 7, 8 - CONTROL "?",IDC_SETTINGS_HELP_MIC_AMPLIF,"SysLink",0x0,265,2+IDD_SETTINGS_OFFSET_MIC,7,8 - CONTROL "?",IDC_SETTINGS_HELP_SW_ADJUST,"SysLink",0x0,265,2+IDD_SETTINGS_OFFSET_MIC_AMPLIF,7,8 - CONTROL "?",IDC_SETTINGS_HELP_AUDIO_CODECS,"SysLink",0x0,265,21+IDD_SETTINGS_OFFSET_SW_ADJUST,7,8 - CONTROL "?",IDC_SETTINGS_HELP_VAD,"SysLink",0x0,10,IDD_SETTINGS_OFFSET_01,7,8 - CONTROL "?",IDC_SETTINGS_HELP_EC,"SysLink",0x0,72,IDD_SETTINGS_OFFSET_01,7,8 - CONTROL "?",IDC_SETTINGS_HELP_FORCE_CODEC,"SysLink",0x0,134,IDD_SETTINGS_OFFSET_01,7,8 - #ifdef _GLOBAL_VIDEO - CONTROL "?",IDC_SETTINGS_HELP_VIDEO,"SysLink",0x0,265,18+IDD_SETTINGS_OFFSET_1,7,8 - #endif - CONTROL "?", IDC_SETTINGS_HELP_PORTS, "SysLink", 0x0, 265, 2 + IDD_SETTINGS_OFFSET_2, 7, 8 - CONTROL "?", IDC_SETTINGS_HELP_STUN_SERVER, "SysLink", 0x0, 265, 2 + IDD_SETTINGS_OFFSET_PORTS, 7, 8 - CONTROL "?",IDC_SETTINGS_HELP_DTMF_METHOD,"SysLink",0x0,265,2+IDD_SETTINGS_OFFSET_STUN,7,8 - CONTROL "?",IDC_SETTINGS_HELP_AUTO_ANSWER,"SysLink",0x0,265,2+IDD_SETTINGS_OFFSET_21,7,8 - CONTROL "?",IDC_SETTINGS_HELP_DENY_INCOMING,"SysLink",0x0,265,2+IDD_SETTINGS_OFFSET_3,7,8 - CONTROL "?",IDC_SETTINGS_HELP_DIRECTORY,"SysLink",0x0,265,2+IDD_SETTINGS_OFFSET_DENY_INCOMING,7,8 - CONTROL "?",IDC_SETTINGS_HELP_MEDIA_BUTTONS,"SysLink",0x0,265,2+IDD_SETTINGS_OFFSET_CUSTOM_FIELD,7,8 - - CONTROL "?",IDC_SETTINGS_HELP_LOCAL_DTMF,"SysLink",0x0,10,IDD_SETTINGS_OFFSET_MEDIA_BUTTONS,7,8 - CONTROL "?", IDC_SETTINGS_HELP_BRING_TO_FRONT, "SysLink", 0x0, 10, IDD_SETTINGS_OFFSET_SOUND_EVENTS, 7, 8 - CONTROL "?",IDC_SETTINGS_HELP_ANSWER_BOX_RANDOM,"SysLink",0x0,10,IDD_SETTINGS_OFFSET_6,7,8 - CONTROL "?",IDC_SETTINGS_HELP_ENABLE_LOG,"SysLink",0x0,145,IDD_SETTINGS_OFFSET_MEDIA_BUTTONS,7,8 - CONTROL "?",IDC_SETTINGS_HELP_DISABLE_LOCAL,"SysLink",0x0,145,IDD_SETTINGS_OFFSET_LOG_FILE,7,8 - - DEFPUSHBUTTON "Save",IDOK,128,IDD_SETTINGS_OFFSET_FINAL,70,14 - PUSHBUTTON "Cancel",IDCANCEL,203,IDD_SETTINGS_OFFSET_FINAL,70,14 -END -//--------------------------------SHORTCUTS--------------------------------------- -#ifndef IDD_SHORTCUTS_OFFSET_INITIAL -#define IDD_SHORTCUTS_OFFSET_INITIAL 4 -#endif - -#define IDD_SHORTCUTS_OFFSET_LABELS IDD_SHORTCUTS_OFFSET_INITIAL+12 - -#define IDD_SHORTCUTS_OFFSET_MATRIX IDD_SHORTCUTS_OFFSET_LABELS+127 - -#ifndef IDD_SHORTCUTS_OFFSET_FINAL -#define IDD_SHORTCUTS_OFFSET_FINAL IDD_SHORTCUTS_OFFSET_MATRIX+16 -#endif - - -IDD_SHORTCUTS DIALOGEX 0, 0, 260, IDD_SHORTCUTS_OFFSET_FINAL+20 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | WS_POPUP | WS_VISIBLE -CAPTION "Shortcuts" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - - LTEXT "Label",IDC_STATIC,20,IDD_SHORTCUTS_OFFSET_INITIAL,70,8 - LTEXT "Number",IDC_STATIC,100,IDD_SHORTCUTS_OFFSET_INITIAL,70,8 - LTEXT "Type",IDC_STATIC,180,IDD_SHORTCUTS_OFFSET_INITIAL,70,8 - - RTEXT "1.",IDC_STATIC,8,IDD_SHORTCUTS_OFFSET_LABELS+3+0,10,8 - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT1_LABEL,20,IDD_SHORTCUTS_OFFSET_LABELS+0,78,14,ES_AUTOHSCROLL - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT1_NUMBER,100,IDD_SHORTCUTS_OFFSET_LABELS+0,78,14,ES_AUTOHSCROLL - COMBOBOX IDC_SHORTCUTS_COMBO_SHORTCUT1_TYPE,180,IDD_SHORTCUTS_OFFSET_LABELS+0,70,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - RTEXT "2.",IDC_STATIC,8,IDD_SHORTCUTS_OFFSET_LABELS+3+15,10,8 - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT2_LABEL,20,IDD_SHORTCUTS_OFFSET_LABELS+15,78,14,ES_AUTOHSCROLL - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT2_NUMBER,100,IDD_SHORTCUTS_OFFSET_LABELS+15,78,14,ES_AUTOHSCROLL - COMBOBOX IDC_SHORTCUTS_COMBO_SHORTCUT2_TYPE,180,IDD_SHORTCUTS_OFFSET_LABELS+15,70,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - RTEXT "3.",IDC_STATIC,8,IDD_SHORTCUTS_OFFSET_LABELS+3+30,10,8 - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT3_LABEL,20,IDD_SHORTCUTS_OFFSET_LABELS+30,78,14,ES_AUTOHSCROLL - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT3_NUMBER,100,IDD_SHORTCUTS_OFFSET_LABELS+30,78,14,ES_AUTOHSCROLL - COMBOBOX IDC_SHORTCUTS_COMBO_SHORTCUT3_TYPE,180,IDD_SHORTCUTS_OFFSET_LABELS+30,70,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - RTEXT "4.",IDC_STATIC,8,IDD_SHORTCUTS_OFFSET_LABELS+3+45,10,8 - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT4_LABEL,20,IDD_SHORTCUTS_OFFSET_LABELS+45,78,14,ES_AUTOHSCROLL - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT4_NUMBER,100,IDD_SHORTCUTS_OFFSET_LABELS+45,78,14,ES_AUTOHSCROLL - COMBOBOX IDC_SHORTCUTS_COMBO_SHORTCUT4_TYPE,180,IDD_SHORTCUTS_OFFSET_LABELS+45,70,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - RTEXT "5.",IDC_STATIC,8,IDD_SHORTCUTS_OFFSET_LABELS+3+60,10,8 - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT5_LABEL,20,IDD_SHORTCUTS_OFFSET_LABELS+60,78,14,ES_AUTOHSCROLL - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT5_NUMBER,100,IDD_SHORTCUTS_OFFSET_LABELS+60,78,14,ES_AUTOHSCROLL - COMBOBOX IDC_SHORTCUTS_COMBO_SHORTCUT5_TYPE,180,IDD_SHORTCUTS_OFFSET_LABELS+60,70,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - RTEXT "6.",IDC_STATIC,8,IDD_SHORTCUTS_OFFSET_LABELS+3+75,10,8 - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT6_LABEL,20,IDD_SHORTCUTS_OFFSET_LABELS+75,78,14,ES_AUTOHSCROLL - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT6_NUMBER,100,IDD_SHORTCUTS_OFFSET_LABELS+75,78,14,ES_AUTOHSCROLL - COMBOBOX IDC_SHORTCUTS_COMBO_SHORTCUT6_TYPE,180,IDD_SHORTCUTS_OFFSET_LABELS+75,70,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - RTEXT "7.",IDC_STATIC,8,IDD_SHORTCUTS_OFFSET_LABELS+3+90,10,8 - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT7_LABEL,20,IDD_SHORTCUTS_OFFSET_LABELS+90,78,14,ES_AUTOHSCROLL - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT7_NUMBER,100,IDD_SHORTCUTS_OFFSET_LABELS+90,78,14,ES_AUTOHSCROLL - COMBOBOX IDC_SHORTCUTS_COMBO_SHORTCUT7_TYPE,180,IDD_SHORTCUTS_OFFSET_LABELS+90,70,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - RTEXT "8.",IDC_STATIC,8,IDD_SHORTCUTS_OFFSET_LABELS+3+105,10,8 - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT8_LABEL,20,IDD_SHORTCUTS_OFFSET_LABELS+105,78,14,ES_AUTOHSCROLL - EDITTEXT IDC_SHORTCUTS_EDIT_SHORTCUT8_NUMBER,100,IDD_SHORTCUTS_OFFSET_LABELS+105,78,14,ES_AUTOHSCROLL - COMBOBOX IDC_SHORTCUTS_COMBO_SHORTCUT8_TYPE,180,IDD_SHORTCUTS_OFFSET_LABELS+105,70,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - - AUTOCHECKBOX "Enable",IDC_SHORTCUTS_ENABLE,20,IDD_SHORTCUTS_OFFSET_MATRIX,100,10 - AUTOCHECKBOX "Bottom Position",IDC_SHORTCUTS_BOTTOM,130,IDD_SHORTCUTS_OFFSET_MATRIX,120,10 - - DEFPUSHBUTTON "Save",IDOK,107,IDD_SHORTCUTS_OFFSET_FINAL,70,14 - PUSHBUTTON "Cancel",IDCANCEL,182,IDD_SHORTCUTS_OFFSET_FINAL,70,14 -END -//----------------------------------------------------------------------- -//-----------------------------ACCOUNT------------------------------------------ - -#define IDD_ACCOUNT_OFF_LABEL 19 - -#ifndef IDD_ACCOUNT_OFF_FINAL -#define IDD_ACCOUNT_OFF_FINAL IDD_ACCOUNT_OFF_LABEL -#endif - -IDD_ACCOUNT DIALOGEX 0, 0, 236, 311 + IDD_ACCOUNT_OFF_FINAL -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | WS_POPUP | WS_VISIBLE -CAPTION "Account" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - RTEXT "Account Name",IDC_STATIC,7,10,70,8 - EDITTEXT IDC_ACCOUNT_LABEL,86,7,127,14,ES_AUTOHSCROLL - RTEXT "SIP Server",IDC_STATIC,7,10+IDD_ACCOUNT_OFF_LABEL,70,8 - EDITTEXT IDC_EDIT_SERVER,86,7+IDD_ACCOUNT_OFF_LABEL,127,14,ES_AUTOHSCROLL - RTEXT "SIP Proxy",IDC_STATIC,7,29+IDD_ACCOUNT_OFF_LABEL,70,8 - EDITTEXT IDC_EDIT_PROXY,86,26+IDD_ACCOUNT_OFF_LABEL,127,14,ES_AUTOHSCROLL - RTEXT "Username",IDC_STATIC,7,55+IDD_ACCOUNT_OFF_LABEL,70,8 - LTEXT "*",IDC_STATIC,78,55+IDD_ACCOUNT_OFF_LABEL,8,5 - EDITTEXT IDC_EDIT_USERNAME,86,52+IDD_ACCOUNT_OFF_LABEL,127,14,ES_AUTOHSCROLL - RTEXT "Domain",IDC_STATIC,7,74+IDD_ACCOUNT_OFF_LABEL,70,8 - LTEXT "*",IDC_STATIC,78,74+IDD_ACCOUNT_OFF_LABEL,8,5 - EDITTEXT IDC_EDIT_DOMAIN,86,71+IDD_ACCOUNT_OFF_LABEL,127,14,ES_AUTOHSCROLL - RTEXT "Login",IDC_STATIC,7,93+IDD_ACCOUNT_OFF_LABEL,70,8 - EDITTEXT IDC_EDIT_AUTHID,86,90+IDD_ACCOUNT_OFF_LABEL,127,14,ES_AUTOHSCROLL - RTEXT "Password",IDC_STATIC,7,112+IDD_ACCOUNT_OFF_LABEL,70,8 - EDITTEXT IDC_EDIT_PASSWORD,86,109+IDD_ACCOUNT_OFF_LABEL,127,14,ES_AUTOHSCROLL | ES_PASSWORD - CONTROL "",IDC_SYSLINK_DISPLAY_PASSWORD,"SysLink",WS_TABSTOP,86,125+IDD_ACCOUNT_OFF_LABEL,120,8 - RTEXT "Display Name",IDC_STATIC,7,143+IDD_ACCOUNT_OFF_LABEL,70,8 - EDITTEXT IDC_EDIT_DISPLAYNAME,86,140+IDD_ACCOUNT_OFF_LABEL,127,14,ES_AUTOHSCROLL - RTEXT "Voicemail Number",IDC_STATIC,7,162+IDD_ACCOUNT_OFF_LABEL,70,8 - EDITTEXT IDC_EDIT_VOICEMAIL,86,159+IDD_ACCOUNT_OFF_LABEL,127,14,ES_AUTOHSCROLL - RTEXT "Media Encryption",IDC_STATIC,7,180+IDD_ACCOUNT_OFF_LABEL,70,8 - COMBOBOX IDC_SRTP,86,177+IDD_ACCOUNT_OFF_LABEL,127,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - RTEXT "Transport",IDC_STATIC,7,198+IDD_ACCOUNT_OFF_LABEL,70,8 - COMBOBOX IDC_TRANSPORT,86,195+IDD_ACCOUNT_OFF_LABEL,127,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - RTEXT "Public Address",IDC_STATIC,7,217+IDD_ACCOUNT_OFF_LABEL,70,8 - COMBOBOX IDC_PUBLIC_ADDR,86,214+IDD_ACCOUNT_OFF_LABEL,127,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - CONTROL "Publish Presence",IDC_PUBLISH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,234+IDD_ACCOUNT_OFF_LABEL,127,10 - CONTROL "ICE",IDC_ICE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,247+IDD_ACCOUNT_OFF_LABEL,127,10 - CONTROL "Allow IP Rewrite",IDC_REWRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,260+IDD_ACCOUNT_OFF_LABEL,127,10 - CONTROL "Disable Session Timers",IDC_SESSION_TIMER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,273+IDD_ACCOUNT_OFF_LABEL,127,10 - PUSHBUTTON "x", IDC_ACCOUNT_REMOVE, 5, 294 + IDD_ACCOUNT_OFF_LABEL, 15, 12, NOT WS_VISIBLE - DEFPUSHBUTTON "Save",IDOK,83,292+IDD_ACCOUNT_OFF_LABEL,70,14 - PUSHBUTTON "Cancel",IDCANCEL,158,292+IDD_ACCOUNT_OFF_LABEL,70,14 - CONTROL "?",IDC_SYSLINK_SIP_SERVER,"SysLink",0x0,222,9+IDD_ACCOUNT_OFF_LABEL,7,8 - CONTROL "?",IDC_SYSLINK_SIP_PROXY,"SysLink",0x0,222,28+IDD_ACCOUNT_OFF_LABEL,7,8 - CONTROL "?",IDC_SYSLINK_USERNAME,"SysLink",0x0,222,55+IDD_ACCOUNT_OFF_LABEL,7,8 - CONTROL "?",IDC_SYSLINK_DOMAIN,"SysLink",0x0,222,73+IDD_ACCOUNT_OFF_LABEL,7,8 - CONTROL "?",IDC_SYSLINK_AUTHID,"SysLink",0x0,222,92+IDD_ACCOUNT_OFF_LABEL,7,8 - CONTROL "?",IDC_SYSLINK_PASSWORD,"SysLink",0x0,222,112+IDD_ACCOUNT_OFF_LABEL,7,8 - CONTROL "?",IDC_SYSLINK_NAME,"SysLink",0x0,222,142+IDD_ACCOUNT_OFF_LABEL,7,8 - CONTROL "?",IDC_SYSLINK_VOICEMAIL,"SysLink",0x0,222,161+IDD_ACCOUNT_OFF_LABEL,7,8 - CONTROL "?",IDC_SYSLINK_ENCRYPTION,"SysLink",0x0,222,179+IDD_ACCOUNT_OFF_LABEL,7,8 - CONTROL "?",IDC_SYSLINK_TRANSPORT,"SysLink",0x0,222,197+IDD_ACCOUNT_OFF_LABEL,7,8 - CONTROL "?",IDC_SYSLINK_PUBLIC_ADDRESS,"SysLink",0x0,222,216+IDD_ACCOUNT_OFF_LABEL,7,8 - CONTROL "?",IDC_SYSLINK_PUBLISH_PRESENCE,"SysLink",0x0,222,234+IDD_ACCOUNT_OFF_LABEL,7,8 - CONTROL "?",IDC_SYSLINK_ICE,"SysLink",0x0,222,247+IDD_ACCOUNT_OFF_LABEL,7,8 - CONTROL "?",IDC_SYSLINK_REWRITE,"SysLink",0x0,222,260+IDD_ACCOUNT_OFF_LABEL,7,8 - CONTROL "?",IDC_SYSLINK_SESSION_TIMER,"SysLink",0x0,222,273+IDD_ACCOUNT_OFF_LABEL,7,8 -END -//----------------------------------------------------------------------- -//----------------------------------------------------------------------- diff --git a/microsip/res/downarrow.bmp b/microsip/res/downarrow.bmp deleted file mode 100644 index 634cb1a2737ee5fd6b2b0bc6035ad02bf2608869..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 230 zcmZ{ay%m5k2!!!HYoB8{hrPR4NxINU=SrEz8PeeamU`jt<0tEOQ|bT~czQk17>7MF zV+PzQAwrQz0*MwDYOUd5QDo*FjOQzaroLEl!v3s1sYzCgx#;CQ!R}<{;{QXxd;kSK BOjG~> diff --git a/microsip/res/dropdown.ico b/microsip/res/dropdown.ico deleted file mode 100644 index 0b4fae9511bcab645bc7c93092b7158e76d86d41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x$gfiO1%0|<`-x`aR)&=wFT2Ur3% z{e)r=n-m}oRQw!>|3fi|4H6>;umKev17et77!48w$q@o`fC^xG&}op|C>TT`@E;gM e==fhf1H&JC28JK<3=ALmA^89Q3!<2qfdK%%E;XY7 diff --git a/microsip/res/exit.ico b/microsip/res/exit.ico deleted file mode 100644 index 63b78507270b5c5e3436b55787825e18c3cda069..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmc(eze`(D6vt1si*#{nwwle-O$FT~V*Ht*=p@*oqJlqg@JH1_&`=?07X=-3)PQF5 zA8-+}1c$UksFLT;mzTtpyoMyEH74Jlb6?e_2zKjzeBZmA^ZmSc&wb|-J>#pglK5_? zq31*|iRd+pLmaW<{2&MC9vLq<_J-wRy<@$9LgEpxFv8l1-hL#S3ln)kRv7RxK&)Rdv-@pxXXL4t;HgVt6J zQtKZ)_m2-fJ!k0ezrfN`9MNbVb8}I}UtQ%fJ8MAKZ!j}spt(7Wnwq0Ko>}QZF9rwC zF)_6L7nu7$1+IukQ?PZJ(L<1T2=yi9YlYee(bN`4O)$!v4Pj GuHqM!==Sme diff --git a/microsip/res/hold.ico b/microsip/res/hold.ico deleted file mode 100644 index 33b83cce5eb7992380160864ffdad41128669b81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmeHEF$%yS5KEz37eVOc(6LYJZ+xpSxJKpZ66scGX(R^2MY$80xIzH;4aW?u0CtiV zo$gZ_;sR8D7{=b5-lm_c-a*wWZ*-5URo5)HoSu$-tN? LmfUHUVkd9{Ug=pL diff --git a/microsip/res/inactive.ico b/microsip/res/inactive.ico deleted file mode 100644 index 747199c4a08d96a727da02f8072f871094aff48b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9622 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 diff --git a/microsip/res/main.rc2 b/microsip/res/main.rc2 deleted file mode 100644 index 080034e1..00000000 --- a/microsip/res/main.rc2 +++ /dev/null @@ -1,118 +0,0 @@ -// -// resources Microsoft Visual C++ does not edit directly -// - -#ifdef APSTUDIO_INVOKED -#error this file is not editable by Microsoft Visual C++ -#endif //APSTUDIO_INVOKED - - -#include "define.h" - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDR_MAINFRAME ICON _GLOBAL_ICON -IDI_EXIT ICON "res\\exit.ico" -IDI_DEFAULT ICON "res\\default.ico" -IDI_UNKNOWN ICON "res\\unknown.ico" -IDI_OFFLINE ICON "res\\offline.ico" -IDI_BUSY ICON "res\\busy.ico" -IDI_AWAY ICON "res\\away.ico" -IDI_ON_THE_PHONE ICON "res\\on-the-phone.ico" -IDI_ONLINE ICON "res\\online.ico" -IDI_SECURE ICON "res\\secure.ico" -IDI_ACTIVE_SECURE ICON "res\\active-secure.ico" -IDI_CONFERENCE_SECURE ICON "res\\conference-secure.ico" -IDI_ACTIVE ICON "res\\active.ico" -IDI_BLANK ICON "res\\blank.ico" -IDI_CALL_OUT ICON "res\\callout.ico" -IDI_CALL_IN ICON "res\\callin.ico" -IDI_CALL_MISS ICON "res\\callmiss.ico" -IDI_MUTE_OUTPUT ICON "res\\muteout.ico" -IDI_MUTED_OUTPUT ICON "res\\mutedout.ico" -IDI_MUTE_INPUT ICON "res\\mutein.ico" -IDI_MUTED_INPUT ICON "res\\mutedin.ico" -IDI_SEARCH ICON "res\\search.ico" -IDI_HOLD ICON "res\\hold.ico" -IDI_CONFERENCE ICON "res\\conference.ico" -IDI_DROPDOWN ICON "res\\dropdown.ico" -IDI_TRANSFER ICON "res\\transfer.ico" -IDI_MESSAGE_IN ICON "res\\message-in.ico" -IDI_ON_HOLD ICON "res\\on-hold.ico" -IDI_ON_REMOTE_HOLD ICON "res\\on-remote-hold.ico" -IDI_ON_REMOTE_HOLD_CONFERENCE ICON "res\\on-remote-hold-conference.ico" -#ifdef _GLOBAL_VIDEO -IDI_VIDEO ICON "res\\video.ico" -#endif -IDI_MESSAGE ICON "res\\message.ico" - -IDI_CLOSE ICON "res\\close.ico" -IDI_CLOSE_2 ICON "res\\close2.ico" - IDI_INACTIVE ICON "res\\inactive.ico" - -IDI_MISSED ICON "res\\missed.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Text -// - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// - -IDB_DOWNARROW BITMAP "res\\downarrow.bmp" -IDB_UPARROW BITMAP "res\\uparrow.bmp" -IDB_VMAIL BITMAP "res\\voicemail.bmp" -IDB_VMAIL_FOCUS BITMAP "res\\voicemail-focus.bmp" -IDB_VMAIL_DOWN BITMAP "res\\voicemail-down.bmp" -IDB_VMAIL_GREY BITMAP "res\\voicemail-grey.bmp" -IDB_VMAIL_GREY_FOCUS BITMAP "res\\voicemail-grey-focus.bmp" -IDB_VMAIL_GREY_DOWN BITMAP "res\\voicemail-grey-down.bmp" -IDB_DELETE BITMAP "res\\delete.bmp" - -///////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION _GLOBAL_VERSION_COMMA - PRODUCTVERSION _GLOBAL_VERSION_COMMA - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904e4" - BEGIN - VALUE "CompanyName", _GLOBAL_COMPANY - VALUE "FileDescription", _GLOBAL_NAME - VALUE "FileVersion", _GLOBAL_VERSION - VALUE "LegalCopyright", _GLOBAL_COMPANY - VALUE "ProductDescription", _GLOBAL_NAME - VALUE "ProductName", _GLOBAL_NAME - VALUE "ProductVersion", _GLOBAL_VERSION - VALUE "OriginalFilename", _GLOBAL_NAME ".exe" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1252 - END -END diff --git a/microsip/res/menu.rc2 b/microsip/res/menu.rc2 deleted file mode 100644 index 84d90c2b..00000000 --- a/microsip/res/menu.rc2 +++ /dev/null @@ -1,61 +0,0 @@ -// -// resources Microsoft Visual C++ does not edit directly -// - -#ifdef APSTUDIO_INVOKED -#error this file is not editable by Microsoft Visual C++ -#endif //APSTUDIO_INVOKED - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDR_MENU_CONTACT MENU -BEGIN - POPUP "" - BEGIN - MENUITEM "Call", ID_CALL -#ifdef _GLOBAL_VIDEO - MENUITEM "Video Call", ID_VIDEOCALL -#endif - MENUITEM "Message", ID_CHAT - MENUITEM SEPARATOR - MENUITEM "Add", ID_ADD - MENUITEM "Edit", ID_EDIT - MENUITEM "Copy", ID_COPY - MENUITEM "Delete", ID_DELETE - END -END - -IDR_MENU_TABS MENU -BEGIN - POPUP "" - BEGIN - MENUITEM "Last Call", ID_GOTOLASTTAB - MENUITEM "Close All", ID_CLOSEALLTABS - END -END - -IDR_MENU_MESSAGES MENU -BEGIN - POPUP "" - BEGIN - MENUITEM "Copy", ID_COPY - MENUITEM "Select All", ID_SELECT_ALL - END -END - -IDR_MENU_CALL_ACTIONS MENU -BEGIN - POPUP "" - BEGIN - MENUITEM "Call Transfer", ID_TRANSFER - MENUITEM "Attended Transfer", ID_ATTENDED_TRANSFER - MENUITEM SEPARATOR - MENUITEM "Invite to Conference", ID_CONFERENCE - MENUITEM "Merge", ID_MERGE - MENUITEM "Separate", ID_SEPARATE - MENUITEM "Disconnect", ID_DISCONNECT - END -END diff --git a/microsip/res/message-in.ico b/microsip/res/message-in.ico deleted file mode 100644 index ef51884ceb91bee22176c7584bdca91a3b58783c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmds!yGjE=6oyYw1W_;;uoMvkK7nB61NZ_yfQ5yPwFJ_Mg{6gsAcBQd+VSeh9HaWLEIIgwpC-(O?&FJPe)4|1{BQid-A>*9F_zIGn04T3FT0oiYI zTyM4Kvf~M3ZLHaYx!uU&Hfyb%i0O6do>el$`YC6g6DND(j)GptfpI^uBrE%LF~O=3 zW0kvRmAPb<4zo&y*h-xl$ML359Fqin_^3l5E!qjMy|9StnihYKvI8u0*JDewOJMuA;KiXK7`V&rl z>G5p7pRzv9o_4o}@7L3mcmCf8T;gxX0oH!~zed+zj+u!ZY8YEnM0$WI*acif{%^b< Pzsu_h3SC|gvq1C(X)}m* diff --git a/microsip/res/message.ico b/microsip/res/message.ico deleted file mode 100644 index 1d54b70fdf087fe2a1139b655b94819242fa5fd2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1406 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%0D?&)7Qrt4ltow0R+n>ez6MM^QMiQ~0r{JuHuJ5qd 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 diff --git a/microsip/res/mutedin.ico b/microsip/res/mutedin.ico deleted file mode 100644 index 4461c766e587d79aac1ec7df0dc7bd227c2c6da0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmcIjPfIFs6umJ|G!Yt#65`1-0?X7ELV{1w5yZ&IPzHlSVpOn&Fe%YOeL5=@H||`y z5c~pyU*Pd}euKB{Be*OG>RiLHva&^YIP<&r+;e_2cm5D9;1ET^*-95bh}MW`8vq67 ziN`_`dfyqvV$q5HwJ8*lGoHCzF1L$%X0+RF!Dh3q#$vGpyWOrBjm8Ru6>v%<5;?S3 zENit|O_*tZMP{?v6@$T01+Ar0snu8QH|1zFT9}Zks_r`+4p~tYQznx!xm>Qe-|s)1 z^k=Q*a(T~eHeY!>o|8hM5MWI(7~FBY-44zZiNtB6(eQ9SE7Iw-2yFsAEgp|Yyk74a z=ZtVTd_EWqmYq(gjQYbUl}aX26jg|{Y1HfW4fw+!nx~qWVIA{aPWBiMhZb%Ng7EyD zrsOZuWHM=$Wm#epv;4-QNs`2~%@v_g=qH34uCG?B)um>$smHs#W-g!4+dkU_&ui>w zJtGhZ?6U{^9&zpS`3|^#FL2K<{LpFret$fFG#cH){kY%rGT-fX^*WvI5BnI%E4^NC z5&7KF>2$0RkN=-mtF{7P<(fwxLByV+R!!#KH15L0lXp z5KyBT#7zeUgQB3|AWq^Y=wBci-0k`7yTO_idgSvvzu!6c`eaN&ADxcTw~?Kw7}GPx z4hZBT&mTV#6DhVS%jHr@*n(fyRmA@b)GFum`Q7Pss+D`7c6$xiPhIozIC2$}$>bi@ zMzYzgbG-+2NU2m3TCLVD<>GmKHuQk5M9%5y={}KEEEb=`Ccgq4jYeM+Np83M1MFMs z(c=zc!{JavB-Ls)8*Hc3c?25>hr@4)Z>wLO!E83uWilCu-|yd7tJNWz`OxKZeMK!0 z3&*w%cvN>-A!8DV0h&ssFR{^K%>3Z^=Eb z_ir|vJIDhZ4#(#}Ah2UF7>>~cbHrk?S3aNboylZ6rX1|?*ZDOX4FhU9>~=fv@gtE) zh*wuvDp3?anayS&<=m*hyu94ywVbV1>le(S)oKI1Ue8>w*Pm1>mA%dR$yP2F3r(R= zI5;~yJILj7g2&_eh&~pJvYhz#zuJz@P!dKp~(AL>x#lH~{5n39PNHEr8~i0dXA=*8p)j z6oc3xv2tT$V=Ewy6~x8Gu{t<72)ekqI4CG6B(Sis)G#wM*UHPwCptPhIsvgzVqzjI zR?TRFSy@>^JUl#w?Ck8NnVFfQXwrDOp`oGHMn*>d!NI|bfq{VvW@cu-{{H@Ucr`&K zr%aim2K0ybs#U9)t*op}fqKoCE?vr!l9J-l)6=6($P8OsTYsQlKA_$NpxOoy2D&A6 z-MV$$mX?-*Kt4_Y3^QgK8JU3Y?ru;LXh6nYU0tF;`9NS;;tW4gQBg*1ZEfB?d-g~m z>jkm*?%gW^bO*19hzKK)j~ARieOer-paB`5I&}(UCQ;zXks}!T4;?y0wEmMPPh#jl ze*8Gm`d6%2fuVodvSmc;U%7H6o1mazDbTYGAk53lTLIM1NtEZIiY82$pa@LAx!l~` r`R(oPs-);8MeYCp3=9w0A^49y1H%t_28Iv(5DXIsiJ@bVT994+Ttw(4q+TJ5tU`(i*#&ePa)u<^ z3^ zp3`5RYh1aN>pI|C=$=?(R6sp*QLE3OOrJ^Ze!uS@kH>4xql`H7UD9`S&1^QaVSf*Y z!*}&5SM-MZm4hI7fgKRtZueFF$|b#-rs-7_Mb=`mu#zNsa$Wb6I)&pnZ)F{A)zezD@*L+{v%?d0|)HFTl_0PBm6Hi Oz^0EeuHjm70gPV+RMSfU diff --git a/microsip/res/offline.ico b/microsip/res/offline.ico deleted file mode 100644 index 8d5a924758d4df25d8a304158e844256b34ce485..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmb_cJ8QyF82t)erA}R2FvwLw2Nx&F<|HmIf`em5XE!JDN9gL}PzfCz>eLb_E~RRl zVk=Vm7)oFEk)h@5Jt-Y(zfcOj;pBw#xL*iKh*tCw4wF7_lC?^-PDDyWOIrEVHIb>k z<;BeOUx-F`LWZ&3R?6{Wv3*aey(M-$_{d2!wQi@=N8D&!v1QGmn zj~_6uC58`A>Sr>?-0wfIVc3CykDS!cW?dc(9`*Ba0s$X6sh`W8u;V;&GC2tZeB`8l zK0oE*@Y&zrG+m!D>kH7}BPaEX#Zw-QUbs-01_C~EQomF>D9TC7VHM|fQIdm{gB%=OaFPphkgUr{oRIdg+1hPM z4&vlHNLMXfyF8+Plf{mRL~OmE)nH}6f&G$JMXbR5ywdKnIg1VyAlOCwFb zxi;z0_x}5_(j9Q!NU5Tj`M$-N?K`aZlq>Al0qH6*v*)w410*X7%(ma`uT&p`s^ zU}n!}$)Le(`}k0`dP%k6X{!dz?9sD3O$M{=cSmd0eIf#HwHeIp(eGlN2D9xC$3yBS zF^JP>7|iU^z3pCu+4gF>QN12d;(DVG%q?D^~}YB1aWVJ+-xsUP|O UUomFe|1}3h^2*MN{8stR7r%k?e*gdg diff --git a/microsip/res/on-remote-hold-conference.ico b/microsip/res/on-remote-hold-conference.ico deleted file mode 100644 index fa43cca2f045f9b74b6b95a795f90399dc8746be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcma))T}YE*6vv;iyDn6M?t;1tp{t;~po;{diweSS(hHO9<0fi%LuSP6%D_NsYt<^T z1_ikg6)i{RSH^4Qw%k;jA7pb&tgTWje?8|NFOB77XZ&~G=l`DHInTrUD78iZN=lUe z-=)rMRceP)YLAw-w3G35GGqHTr9_1WU>k35V(?}y1I@=tOc@vt?et$ejQE@Nq3aS% z_!)NB(cid_5$8_kj2?!rALWg+RQsp%@+RAT4$`w2o+_g5GM0U%#D@HYJcn5I7h||9 z^YiZg5cNW8hG6SiLau{My2@A>>m+oyl9+cd@4Ynz@zYOiOx{01*i}I?*iEFZmbWeC zd}upw@{ZAFDmrTZ6S41E!3f!L#y%s#at?2!=%l^<_!C}sy( z>T~cdaFLY}JLzZ-%K&z9vKYn{R~st4<+_D!2Lxx8@I9SI!cn388} zPIgbr+lX%rWA63EVkYOS&1GdRwS}B>Bi7=rbAC>(NbF)j!sXd$=&!3Bd0f!0P4 z5Uh!owk)z}3lwM(%GxShQUL`+H7J;XrGDNsqy+HA#5*~2Gv7VGIp5qfGmP!vhqpK5 zXFqn(A~#FcfOPr}&e#TdoE4geV=>LPTPC86uS7z>kTm}{lzycZ18={}DJ zOC9Bws+E$#GG(AD#OH>wK$+crZ6&tp^h*0|=bBNTg3f|NFy;GT#@vdY2Vv;T7r`h` z7WigcYfrdF0&#sbq8j57Q6D2jWJ4VK=KEn*#A96Uk42>jwjK>Eio;md?1fn_5%}5< zFTB$9nGkEELCoeb&h=unIu#aK048Mqm>XzIL5p=NeMqUJ!b^xgWyb@@FN6SQ@26a%HGSj9^t5_+AQp$E*R|*Os0T z8^wciiCL!^lZ_}mFY40~!u3AWWjx4uDjKA!KK?|I(myze>h$JinMl$A05 zKFLgn89UAxlXGy2Ge3DgiE-=*V}!pM074HVk8n5Oz`)WVx_wr3%yz-PbO&ph1eaku zxKCxJS5{FmH6oYK=c=k+gdh}3EoI&doBhF8^!{WP)jol=Q{OBaugw?u+MB*!kmq($SYC~`{gzK+w;Phk*|2Bwubmd-w zzpgF>munl<)dA4jVu_18viPo`#nUQsp7pdr72=l9|F?@;em2YW|rh2kCN=XX$B z8!8FXDX!Q{-zrrM3k$oTI+~iIVy5*k5Jx)2N%^(fRRn`ypjO99f^>?L^6T~Qk;!}) z`%?}nkWO(@exot&rhhLQ&0=NcPY_Q!#g*{O42JkfZ||pEDUixo&5tGjVQ#13WtIsNT{LVf-sJRmT(AhNN^IG z5+R46C1@#H-EIip-shwtdyfeE9nU?-^YME*?gN<9BOZsIm#{hyEC5(msHDnNSHg;V zvr9zqU%)1!*no>2c&ID3XP7#D%~>;5??w(IQoXH8@v115Zsi+Or_Y?(--0wpO~0pe zOr{Ubnf*G%xp$=2s|nU%GJU-_yT3P`-?(c?>AEBq`|~wt%?}@hrS;Gf>_T{LF@1Vg zKXw$8_G4SHjzG|7&gv(Q6ViF=h(5nS&}Yu-r%qGSf9^|YKNJZ1%vt@kla|5Dz~4W4 zlJuFgzCevWb5=ilo|WP2P%>wkK+tE->gO(UGVvz<{+wZfK66&Ta9QZ`ogKfAW%M@s n0qXRb3+PAlZr&~5l)WI(*S`7vSbP4a@qZBWfW?o$fgP?-&ozHO diff --git a/microsip/res/search.ico b/microsip/res/search.ico deleted file mode 100644 index 569b71ad38229b47d511aab0931db7f72878787a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmb_aO-n*i5S=h+>neg4wyRAL2!Rk3ZG*tA5Cm;%8w8S;=F?2m%oM-KFG9(}k`M$} zw(4Jmf)KcC7qqyYDX-j2vZD7mZ|0seXWsoH8o{gA6TVZlIZ8B6L^A*=FdsYuEkXN_ z$F*yl|7#z3V}JmXzwN=Eu9y7`)1V&UCjcWbD|O^OZz>WMiSSuWYBHk60<;0ypJNNC zy>m9Z$R<;wkjoA77P#g-7H^aY>Bg_PMlA z>*qS0&AMmb!E+e6|KN96N8MI`UpdYsl3Bk?;~soh_#W}P)`0r4=H_!Bdf%@LMGNlM zQ~We6aGruA#x3w>`JbP}>TPARTB$5>99A!0iNrI|Bzn0gYGQX9V??14k>TMhm~R+R Jw}^T{^ajpc^OXPq diff --git a/microsip/res/secure.ico b/microsip/res/secure.ico deleted file mode 100644 index 95324cd499b9c3355df79194189f71171c761b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmbV~ZAepL6vt02qa`vUY^@KzL_u>(j1nV1_@ysK9|}JN8CW0~sfh_11|>$)%6y?M zn8t8qMy;W?=?0SR#gRJh(8AV>q6Nkft}x0NwfOfuSBgzHsLtho&$<6|e$Vs3eTX)( zCq13mJDbjLCfZ3v`~L1+FC=2}Ge4ej;yV0r~cMX#7#^oA{1{ zFTaX$`(InzUpKBp>ElxHTO)v=S*i(3?yzu&ba10L{Vp(42 zbmd@leiX76*#@2HK8cY@CuZLTQE#b-&1&7Uo>v>xa4)*S&!M`bk}|Jq9AWp2t)EQ1&*u{H#l6KgerIPwGY~!t8^nFy=W|K; gv?5cHseGV3l1#kM__Rd)|9XlDQC9Td#2FsH0Px4O8UO$Q diff --git a/microsip/res/transfer.ico b/microsip/res/transfer.ico deleted file mode 100644 index b8d9bb7b379c6614693b7f9a3bcd35b9451d5d2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmd6lKQDwq5QpcSMCmH!MaM@_5`{=43ZkHqTtVa#$;I7Q(9nunLZbGkphBTlQD_hi z3KG{4ah~73JGsr9?CHe3d3I)hGqdmRX3YwGrIIlY+H$YifSC;g5=y4yY?RzTwIcgk zfK6EXWse2&v#1s1Y?_4k%HP0g(5~V~_1Q<2W}=oj!BgOrx(xqY=_HMHq%ilH`V|(`QcW+qR87&#Ru9qcVNww7$7# zWLbvwdW}}Ar80fyw0^(eujX$y8$?kAjX9q=tv?(NvE6Rb>-E5Ejp@_V`jg27yWI}$ zcDokznbZ2y=@k3@9_BgKfJQ3?Fx#yhUyYHTR9%DNCSuBkH z->?q`#%zqSwkmj^1pwY6p2-QAVj?Kadg7z}WKe~(tHh4FZ-y7Bn<2(Q=M<&4VnIU0@H zVzJoW)zwv>Y=@f)72WmVhda)n6aot+(|QYqweIb<>! z5QFvgbx>?TdWxN+7!rvDip3&+oS!3|P9q$Ykk99FeSM8!Fo@OF)t~Bq+L`>{0)fD! zUauo}dJ6lz4YOu5Ori+$>@2EO-%6!|?d|P0?ej^?a+`cZzVE}s1Kuq;VGslef&qHH zpxAz&7qToXXQJGamS0<2TcGoGc)feQ9+n(-=yf_!jv_&?2j{!puJR64+uvHA>ilYR zbFd$?bmzN{D!|&6qx+dNh3Wd7?7>!2Q?GEfq z67S0rczD?1qIHAV&lJ;5gIR&GkK|Rw*L9JxEEm~IoaYD` PYgUz*vDQiQYsUTnb4ky? diff --git a/microsip/res/voicemail-down.bmp b/microsip/res/voicemail-down.bmp deleted file mode 100644 index ed442b50a2010416f6db19a774310b0a1736f55d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1272 zcmbtUEo|FB6!xTnRwL_1IyAb4t)Nl{N2`&IweTKz*5m`eN=E`+wz3o!)+}QSYrwz^ z%N7>Hnzd|U-uInz`KhXI>hg4s@80+G-n%FtKF*&e;j@qD8?4t@FR`8^&+$x>AIQIW z)~#@WN2BGVqtPTOwRm)t_wYp@icPP(d=VoLu|*9KD~)wNbKB|A_T78ezc+Y(W_u|; zI*oO{k*jRxTK~70xg8r7R(vA|DVdk@g$}SEg$|;>kzU&2CEQNf zV;1C>%3e;F{Plh03tT2Z?Xk+x^LO-o=;$Z9i_AO^zYXNB(AflYqSKNOpJOm)?w!5X zM)}_Q+fbvC5g4r>+pVdYa`pxI)GqY1?NnR8>$VoN*yIx@x}A=)(~RBGI|gsG(XZJk>!oyx=du5|Cyuen YW>%oM$Sqax`bU+2|EB-{{{JM&AA|o&U;qFB diff --git a/microsip/res/voicemail-focus.bmp b/microsip/res/voicemail-focus.bmp deleted file mode 100644 index 3095f39d988f645c30d56825899faa801f5fa10b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1272 zcmbtUy-or_5MC2In?oC{Y;B=1;YxcO=#&2u2e|7f;SsnF zI-GBg`%4Tlz+@M8zMt8hz2o_1e{J;hB=e(;2N`!Vu8b$MF+YOe-ef})G9|-^&W&Vf zOh}WnBP3&@v(*#XcU>QlrQoDr9k1&xZE5Gmd@7nF&)K3vRd4Cdt@-eem=_ME-crj! zyX1TB@J3yH-aACL-muTj(L#~l(V^5&Xe`J(C(;2+o&#?uEW})#*WA)oOs|5>c&dHM z^?{rmHNnAc;w%UL;!s#qnhCNhkW`u80DUg?4dE}84}Cx>p=K;j5iLdEIO+om346;< zQ0lz__|ft9EWvN7>qzI!m@-ftt5@}K zh^eDEJa!Jf&-D0S70*_mw*^wx2Q!dJhdtMII9;yJk%Zc==h7i~$RX-_WYD4dJCbw% OLZH9&{lE18$CzIi5p4GW diff --git a/microsip/res/voicemail-grey-down.bmp b/microsip/res/voicemail-grey-down.bmp deleted file mode 100644 index 9a9d6649c2f2d954c19c19a514921ae26e92a848..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1688 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 ZY`QXkciAQO*3o;&)<*UY(s9{8@DJJwF&_W` diff --git a/microsip/res/voicemail.bmp b/microsip/res/voicemail.bmp deleted file mode 100644 index 9d5450df0c376f25b787e83a35b3cb0ffd017c95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1272 zcmbtUyHWx{5L~OwOb$)F$kg-scl=e2Nq_jT;-bB*&7`vUt6`^aTDoqL1-^dxS3fur!*!K?7jtz>cV zT8VR+Kb)T-{x&~I*ptgHVwWG}%I8|@_|H{pS9?Ci*yabB`byX3-lZR-Rw40&Ja{rI zz0rX#O=qY%;^nZ{v~>t;Zl0$mhs3XC49~L`@C503;&SD4xc?YY_rW}wFX4I7+WOS; zSvg}6!)XM0MK&|#Y-@Re=d;O~+C;`KBz_hXTepcL!e=Cf0nG;l=b zn_d!G%a_Haue2He=EpZzeuBkY5bgF1Qus%BdWf8S+wmjPZp;sE(xA7s_)Y$QfB*me H|8edcmP?1C diff --git a/microsip/settings.cpp b/microsip/settings.cpp deleted file mode 100644 index 1ef3e891..00000000 --- a/microsip/settings.cpp +++ /dev/null @@ -1,964 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 "settings.h" -#include "Crypto.h" - -#include -#include - -#include -#pragma comment(lib, "Msi.lib") - -using namespace MFC; - -AccountSettings accountSettings; -bool firstRun; -bool pj_ready; -CTime startTime; -CArray shortcuts; - -void AccountSettings::Init() -{ - CString str; - LPTSTR ptr; - accountId = 0; - startTime = CTime::GetCurrentTime(); - //-- - ptr = exeFile.GetBuffer(MAX_PATH); - GetModuleFileName(NULL, ptr, MAX_PATH); - exeFile.ReleaseBuffer(); - //-- - pathExe = exeFile.Mid(0, exeFile.ReverseFind('\\')); - //-- - CString fileName = PathFindFileName(exeFile); - fileName = fileName.Mid(0, fileName.ReverseFind('.')); - logFile.Format(_T("%s_log.txt"), fileName); - iniFile.Format(_T("%s.ini"), fileName); - pathRoaming = _T(""); - pathLocal = _T(""); - if (pathRoaming.IsEmpty()) { - CString contactsFile = _T("Contacts.xml"); - CFileStatus rStatus; - CRegKey regKey; - CString pathInstaller; - CString rab; - ULONG pnChars; - rab.Format(_T("Software\\%s"), _T(_GLOBAL_NAME)); - if (regKey.Open(HKEY_CURRENT_USER, rab, KEY_READ) == ERROR_SUCCESS) { - ptr = pathInstaller.GetBuffer(255); - pnChars = 256; - regKey.QueryStringValue(NULL, ptr, &pnChars); - pathInstaller.ReleaseBuffer(); - regKey.Close(); - } - if (pathInstaller.IsEmpty() && regKey.Open(HKEY_LOCAL_MACHINE, rab, KEY_READ) == ERROR_SUCCESS) { - ptr = pathInstaller.GetBuffer(255); - pnChars = 256; - regKey.QueryStringValue(NULL, ptr, &pnChars); - pathInstaller.ReleaseBuffer(); - regKey.Close(); - } - if (pathInstaller.IsEmpty()) { - ptr = pathInstaller.GetBuffer(255); - DWORD bChars = 256; - UINT e = MsiGetProductInfo(_T("{F6560769-8A2F-4874-9E76-D86B016CBDFF}"), INSTALLPROPERTY_PRODUCTNAME, ptr, &bChars); - if (e == ERROR_SUCCESS) { - pathInstaller = pathExe; - } - else { - pathInstaller.ReleaseBuffer(); - pathInstaller.Empty(); - } - } - CString appDataRoaming; - ptr = appDataRoaming.GetBuffer(MAX_PATH); - SHGetSpecialFolderPath( - 0, - ptr, - CSIDL_APPDATA, - FALSE); - appDataRoaming.ReleaseBuffer(); - appDataRoaming.AppendFormat(_T("\\%s\\"), _T(_GLOBAL_NAME)); - - if (!pathInstaller.IsEmpty() && pathInstaller.CompareNoCase(pathExe) == 0) { - // installer - CreateDirectory(appDataRoaming, NULL); - pathRoaming = appDataRoaming; - CString appDataLocal; - ptr = appDataLocal.GetBuffer(MAX_PATH); - SHGetSpecialFolderPath( - 0, - ptr, - CSIDL_LOCAL_APPDATA, - FALSE); - appDataLocal.ReleaseBuffer(); - appDataLocal.AppendFormat(_T("\\%s\\"), _T(_GLOBAL_NAME)); - CreateDirectory(appDataLocal, NULL); - pathLocal = appDataLocal; - logFile = pathLocal + logFile; - } - else { - // portable - pathRoaming = pathExe + _T("\\"); - pathLocal = pathRoaming; - // for version <= 3.14.5 move ini file from currdir to exedir - CString pathCurrent; - ptr = pathCurrent.GetBuffer(MAX_PATH); - ::GetCurrentDirectory(MAX_PATH, ptr); - pathCurrent.ReleaseBuffer(); - if (pathCurrent.CompareNoCase(pathExe) != 0) { - pathCurrent.Append(_T("\\")); - if (CopyFile(pathCurrent + iniFile, pathRoaming + iniFile, TRUE)) { - DeleteFile(pathCurrent + iniFile); - } - if (CopyFile(pathCurrent + contactsFile, pathRoaming + contactsFile, TRUE)) { - DeleteFile(pathCurrent + contactsFile); - } - DeleteFile(pathCurrent + logFile); - } - // copy ini from installer path - CopyFile(appDataRoaming + iniFile, pathRoaming + iniFile, TRUE); - CopyFile(appDataRoaming + contactsFile, pathRoaming + contactsFile, TRUE); - logFile = pathLocal + logFile; - } - - iniFile = pathRoaming + iniFile; - - firstRun = true; - if (CFile::GetStatus(iniFile, rStatus)) { - firstRun = false; - } - } - //-- - - CString section; - section = _T("Settings"); - - ptr = updatesInterval.GetBuffer(255); - GetPrivateProfileString(section, _T("updatesInterval"), NULL, ptr, 256, iniFile); - updatesInterval.ReleaseBuffer(); - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("checkUpdatesTime"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - checkUpdatesTime = _wtoi(str); - - ptr = portKnockerHost.GetBuffer(255); - GetPrivateProfileString(section, _T("portKnockerHost"), NULL, ptr, 256, iniFile); - portKnockerHost.ReleaseBuffer(); - - ptr = portKnockerPorts.GetBuffer(255); - GetPrivateProfileString(section, _T("portKnockerPorts"), NULL, ptr, 256, iniFile); - portKnockerPorts.ReleaseBuffer(); - - ptr = lastCallNumber.GetBuffer(255); - GetPrivateProfileString(section, _T("lastCallNumber"), NULL, ptr, 256, iniFile); - lastCallNumber.ReleaseBuffer(); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("lastCallHasVideo"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - lastCallHasVideo = (str == _T("1")); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("enableLocalAccount"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - enableLocalAccount = str == _T("1") ? 1 : 0; - - crashReport = 0; - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("DTMFMethod"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - DTMFMethod = _wtoi(str); - //-- - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("AA"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - AA = _wtoi(str); - //-- - ptr = autoAnswer.GetBuffer(255); - GetPrivateProfileString(section, _T("autoAnswer"), _T(_GLOBAL_AUTO_ANSWER_DEFAULT), ptr, 256, iniFile); - autoAnswer.ReleaseBuffer(); - //-- - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("DND"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - DND = _wtoi(str); - //-- - ptr = denyIncoming.GetBuffer(255); - GetPrivateProfileString(section, _T("denyIncoming"), _T(_GLOBAL_DENY_INCOMING_DEFAULT), ptr, 256, iniFile); - denyIncoming.ReleaseBuffer(); - //-- - ptr = userAgent.GetBuffer(255); - GetPrivateProfileString(section, _T("userAgent"), NULL, ptr, 256, iniFile); - userAgent.ReleaseBuffer(); - - ptr = usersDirectory.GetBuffer(255); - GetPrivateProfileString(section, _T("usersDirectory"), NULL, ptr, 256, iniFile); - usersDirectory.ReleaseBuffer(); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("dnsSrv"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - dnsSrv = _wtoi(str); - - ptr = stun.GetBuffer(255); - GetPrivateProfileString(section, _T("STUN"), NULL, ptr, 256, iniFile); - stun.ReleaseBuffer(); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("enableSTUN"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - enableSTUN = str == "1" ? 1 : 0; - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("enableMediaButtons"), _T("0"), ptr, 256, iniFile); - str.ReleaseBuffer(); - enableMediaButtons = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("localDTMF"), _T("1"), ptr, 256, iniFile); - str.ReleaseBuffer(); - localDTMF = _wtoi(str); - - ptr = ringingSound.GetBuffer(255); - GetPrivateProfileString(section, _T("ringingSound"), NULL, ptr, 256, iniFile); - - ringingSound.ReleaseBuffer(); - ptr = audioRingDevice.GetBuffer(255); - GetPrivateProfileString(section, _T("audioRingDevice"), NULL, ptr, 256, iniFile); - audioRingDevice.ReleaseBuffer(); - ptr = audioOutputDevice.GetBuffer(255); - GetPrivateProfileString(section, _T("audioOutputDevice"), NULL, ptr, 256, iniFile); - audioOutputDevice.ReleaseBuffer(); - ptr = audioInputDevice.GetBuffer(255); - GetPrivateProfileString(section, _T("audioInputDevice"), NULL, ptr, 256, iniFile); - audioInputDevice.ReleaseBuffer(); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("micAmplification"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - micAmplification = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("swLevelAdjustment"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - swLevelAdjustment = _wtoi(str); - - ptr = audioCodecs.GetBuffer(255); - GetPrivateProfileString(section, _T("audioCodecs"), NULL, ptr, 256, iniFile); - audioCodecs.ReleaseBuffer(); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("rport"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - rport = str == "0" ? 0 : 1; - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("sourcePort"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - sourcePort = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("rtpPortMin"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - rtpPortMin = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("rtpPortMax"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - rtpPortMax = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("VAD"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - vad = str == "1" ? 1 : 0; - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("EC"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - ec = str == _T("0") ? 0 : 1; - - //-- - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("forceCodec"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - forceCodec = _wtoi(str); - //-- - -#ifdef _GLOBAL_VIDEO - ptr = videoCaptureDevice.GetBuffer(255); - GetPrivateProfileString(section, _T("videoCaptureDevice"), NULL, ptr, 256, iniFile); - videoCaptureDevice.ReleaseBuffer(); - - ptr = videoCodec.GetBuffer(255); - GetPrivateProfileString(section, _T("videoCodec"), NULL, ptr, 256, iniFile); - videoCodec.ReleaseBuffer(); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("videoH264"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - videoH264 = str == "0" ? 0 : 1; - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("videoH263"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - videoH263 = str == "0" ? 0 : 1; - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("videoVP8"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - videoVP8 = str == "0" ? 0 : 1; - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("videoBitrate"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - videoBitrate = _wtoi(str); -#endif - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("mainX"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - mainX = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("mainY"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - mainY = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("mainW"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - mainW = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("mainH"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - mainH = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("noResize"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - noResize = str == _T("1") ? 1 : 0; - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("messagesX"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - messagesX = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("messagesY"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - messagesY = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("messagesW"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - messagesW = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("messagesH"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - messagesH = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("ringinX"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - ringinX = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("ringinY"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - ringinY = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("callsWidth0"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - callsWidth0 = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("callsWidth1"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - callsWidth1 = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("callsWidth2"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - callsWidth2 = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("callsWidth3"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - callsWidth3 = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("callsWidth4"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - callsWidth4 = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("contactsWidth0"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - contactsWidth0 = _wtoi(str); - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("contactsWidth1"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - contactsWidth1 = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("volumeOutput"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - volumeOutput = str.IsEmpty() ? 100 : _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("volumeInput"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - volumeInput = str.IsEmpty() ? 100 : _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("activeTab"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - activeTab = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("alwaysOnTop"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - alwaysOnTop = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("autoHangUpTime"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - autoHangUpTime = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("maxConcurrentCalls"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - maxConcurrentCalls = _wtoi(str); - - ptr = cmdCallStart.GetBuffer(255); - GetPrivateProfileString(section, _T("cmdCallStart"), NULL, ptr, 256, iniFile); - cmdCallStart.ReleaseBuffer(); - - ptr = cmdCallEnd.GetBuffer(255); - GetPrivateProfileString(section, _T("cmdCallEnd"), NULL, ptr, 256, iniFile); - cmdCallEnd.ReleaseBuffer(); - - ptr = cmdIncomingCall.GetBuffer(255); - GetPrivateProfileString(section, _T("cmdIncomingCall"), NULL, ptr, 256, iniFile); - cmdIncomingCall.ReleaseBuffer(); - - ptr = cmdCallAnswer.GetBuffer(255); - GetPrivateProfileString(section, _T("cmdCallAnswer"), NULL, ptr, 256, iniFile); - cmdCallAnswer.ReleaseBuffer(); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("enableLog"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - enableLog = _wtoi(str); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("bringToFrontOnIncoming"), _T("1"), ptr, 256, iniFile); - str.ReleaseBuffer(); - bringToFrontOnIncoming = _wtoi(str); - //-- - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("randomAnswerBox"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - randomAnswerBox = _wtoi(str); - - //-- - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("singleMode"), _T("1"), ptr, 256, iniFile); - str.ReleaseBuffer(); - singleMode = _wtoi(str); - - hidden = 0; - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("silent"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - silent = str == "1" ? 1 : 0; - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("enableShortcuts"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - enableShortcuts = _wtoi(str); - GetPrivateProfileString(section, _T("shortcutsBottom"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - shortcutsBottom = _wtoi(str); - - //-- - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("accountId"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - if (str.IsEmpty()) { - if (AccountLoad(-1, &account)) { - accountId = 1; - WritePrivateProfileString(section, _T("accountId"), _T("1"), iniFile); - } - } - else { - accountId = _wtoi(str); - if (!accountId && !enableLocalAccount) { - accountId = 1; - } - if (accountId > 0) { - if (!AccountLoad(accountId, &account)) { - accountId = 0; - } - } - } -} - -AccountSettings::AccountSettings() -{ - Init(); -} - -void AccountSettings::AccountDelete(int id) -{ - CString section; - section.Format(_T("Account%d"), id); - WritePrivateProfileStruct(section, NULL, NULL, 0, iniFile); -} - -bool AccountSettings::AccountLoad(int id, Account *account) -{ - CString str; - CString rab; - LPTSTR ptr; - - CString section; - if (id == -1) { - section = _T("Settings"); - } - else { - section.Format(_T("Account%d"), id); - } - - ptr = account->label.GetBuffer(255); - GetPrivateProfileString(section, _T("label"), NULL, ptr, 256, iniFile); - account->label.ReleaseBuffer(); - - ptr = account->server.GetBuffer(255); - GetPrivateProfileString(section, _T("server"), NULL, ptr, 256, iniFile); - account->server.ReleaseBuffer(); - - ptr = account->proxy.GetBuffer(255); - GetPrivateProfileString(section, _T("proxy"), NULL, ptr, 256, iniFile); - account->proxy.ReleaseBuffer(); - - ptr = account->domain.GetBuffer(255); - GetPrivateProfileString(section, _T("domain"), NULL, ptr, 256, iniFile); - account->domain.ReleaseBuffer(); - - - ptr = account->username.GetBuffer(255); - GetPrivateProfileString(section, _T("username"), NULL, ptr, 256, iniFile); - account->username.ReleaseBuffer(); - ptr = account->password.GetBuffer(1040); - GetPrivateProfileString(section, _T("password"), NULL, ptr, 1041, iniFile); - account->password.ReleaseBuffer(); - if (!account->password.IsEmpty()) { - CByteArray arPassword; - String2Bin(account->password, &arPassword); - CCrypto crypto; - if (crypto.DeriveKey((LPCTSTR)_GLOBAL_KEY)) { - try { - if (!crypto.Decrypt(arPassword, account->password)) { - //--decode from old format - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("passwordSize"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - if (!str.IsEmpty()) { - int size = _wtoi(str); - arPassword.SetSize(size > 0 ? size : 16); - GetPrivateProfileStruct(section, _T("password"), arPassword.GetData(), arPassword.GetSize(), iniFile); - crypto.Decrypt(arPassword, account->password); - } - //--end decode from old format - if (crypto.Encrypt(account->password, arPassword)) { - WritePrivateProfileString(section, _T("password"), Bin2String(&arPassword), iniFile); - //--delete old format addl.data - WritePrivateProfileString(section, _T("passwordSize"), NULL, iniFile); - } - } - } - catch (CArchiveException *e) { - } - } - } - - account->rememberPassword = account->password.GetLength() ? 1 : 0; - - - ptr = account->authID.GetBuffer(255); - GetPrivateProfileString(section, _T("authID"), NULL, ptr, 256, iniFile); - account->authID.ReleaseBuffer(); - - ptr = account->displayName.GetBuffer(255); - GetPrivateProfileString(section, _T("displayName"), NULL, ptr, 256, iniFile); - account->displayName.ReleaseBuffer(); - - ptr = account->voicemailNumber.GetBuffer(255); - GetPrivateProfileString(section, _T("voicemailNumber"), NULL, ptr, 256, iniFile); - account->voicemailNumber.ReleaseBuffer(); - - ptr = account->srtp.GetBuffer(255); - GetPrivateProfileString(section, _T("SRTP"), NULL, ptr, 256, iniFile); - account->srtp.ReleaseBuffer(); - - ptr = account->transport.GetBuffer(255); - GetPrivateProfileString(section, _T("transport"), NULL, ptr, 256, iniFile); - account->transport.ReleaseBuffer(); - - ptr = account->publicAddr.GetBuffer(255); - GetPrivateProfileString(section, _T("publicAddr"), NULL, ptr, 256, iniFile); - account->publicAddr.ReleaseBuffer(); - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("publish"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - account->publish = str == _T("1") ? 1 : 0; - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("ICE"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - account->ice = str == _T("1") ? 1 : 0; - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("allowRewrite"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - account->allowRewrite = str == _T("1") ? 1 : 0; - - - ptr = str.GetBuffer(255); - GetPrivateProfileString(section, _T("disableSessionTimer"), NULL, ptr, 256, iniFile); - str.ReleaseBuffer(); - account->disableSessionTimer = str == _T("1") ? 1 : 0; - - bool sectionExists = IniSectionExists(section, iniFile); - - if (id == -1) { - // delete old - WritePrivateProfileString(section, _T("server"), NULL, iniFile); - WritePrivateProfileString(section, _T("proxy"), NULL, iniFile); - WritePrivateProfileString(section, _T("SRTP"), NULL, iniFile); - WritePrivateProfileString(section, _T("transport"), NULL, iniFile); - WritePrivateProfileString(section, _T("publicAddr"), NULL, iniFile); - WritePrivateProfileString(section, _T("publish"), NULL, iniFile); - WritePrivateProfileString(section, _T("STUN"), NULL, iniFile); - WritePrivateProfileString(section, _T("ICE"), NULL, iniFile); - WritePrivateProfileString(section, _T("allowRewrite"), NULL, iniFile); - WritePrivateProfileString(section, _T("domain"), NULL, iniFile); - WritePrivateProfileString(section, _T("authID"), NULL, iniFile); - WritePrivateProfileString(section, _T("username"), NULL, iniFile); - WritePrivateProfileString(section, _T("passwordSize"), NULL, iniFile); - WritePrivateProfileString(section, _T("password"), NULL, iniFile); - WritePrivateProfileString(section, _T("id"), NULL, iniFile); - WritePrivateProfileString(section, _T("displayName"), NULL, iniFile); - // save new - //if (!account->domain.IsEmpty() && !account->username.IsEmpty()) { - if (sectionExists && !account->domain.IsEmpty()) { - AccountSave(1, account); - } - } - //return !account->domain.IsEmpty() && !account->username.IsEmpty(); - return sectionExists && !account->domain.IsEmpty(); - } - -void AccountSettings::AccountSave(int id, Account *account) -{ - CString str; - CString section; - section.Format(_T("Account%d"), id); - - WritePrivateProfileString(section, _T("label"), account->label, iniFile); - - WritePrivateProfileString(section, _T("server"), account->server, iniFile); - - WritePrivateProfileString(section, _T("proxy"), account->proxy, iniFile); - - WritePrivateProfileString(section, _T("domain"), account->domain, iniFile); - - if (!account->rememberPassword) { - WritePrivateProfileString(section, _T("username"), _T(""), iniFile); - WritePrivateProfileString(section, _T("password"), _T(""), iniFile); - } - else { - WritePrivateProfileString(section, _T("username"), account->username, iniFile); - CCrypto crypto; - CByteArray arPassword; - if (!account->password.IsEmpty() && crypto.DeriveKey((LPCTSTR)_GLOBAL_KEY) - && crypto.Encrypt(account->password, arPassword) - ) { - str = Bin2String(&arPassword); - } - else { - str = account->password; - } - WritePrivateProfileString(section, _T("password"), str, iniFile); - } - - WritePrivateProfileString(section, _T("authID"), account->authID, iniFile); - - WritePrivateProfileString(section, _T("displayName"), account->displayName, iniFile); - - WritePrivateProfileString(section, _T("voicemailNumber"), account->voicemailNumber, iniFile); - - WritePrivateProfileString(section, _T("transport"), account->transport, iniFile); - - WritePrivateProfileString(section, _T("publicAddr"), account->publicAddr, iniFile); - - WritePrivateProfileString(section, _T("SRTP"), account->srtp, iniFile); - - WritePrivateProfileString(section, _T("publish"), account->publish ? _T("1") : _T("0"), iniFile); - WritePrivateProfileString(section, _T("ICE"), account->ice ? _T("1") : _T("0"), iniFile); - WritePrivateProfileString(section, _T("allowRewrite"), account->allowRewrite ? _T("1") : _T("0"), iniFile); - WritePrivateProfileString(section, _T("disableSessionTimer"), account->disableSessionTimer ? _T("1") : _T("0"), iniFile); - } - -void AccountSettings::SettingsSave() -{ - CString str; - LPTSTR ptr; - - CString section; - section = _T("Settings"); - - str.Format(_T("%d"), accountId); - WritePrivateProfileString(section, _T("accountId"), str, iniFile); - - WritePrivateProfileString(section, _T("enableLocalAccount"), enableLocalAccount ? _T("1") : _T("0"), iniFile); - - WritePrivateProfileString(section, _T("enableLog"), enableLog ? _T("1") : _T("0"), iniFile); - - WritePrivateProfileString(section, _T("bringToFrontOnIncoming"), bringToFrontOnIncoming ? _T("1") : _T("0"), iniFile); - - WritePrivateProfileString(section, _T("randomAnswerBox"), randomAnswerBox ? _T("1") : _T("0"), iniFile); - - WritePrivateProfileString(section, _T("portKnockerHost"), portKnockerHost, iniFile); - - WritePrivateProfileString(section, _T("portKnockerPorts"), portKnockerPorts, iniFile); - - WritePrivateProfileString(section, _T("lastCallNumber"), lastCallNumber, iniFile); - WritePrivateProfileString(section, _T("lastCallHasVideo"), lastCallHasVideo ? _T("1") : _T("0"), iniFile); - - WritePrivateProfileString(section, _T("updatesInterval"), updatesInterval, iniFile); - str.Format(_T("%d"), checkUpdatesTime); - WritePrivateProfileString(section, _T("checkUpdatesTime"), str, iniFile); - - WritePrivateProfileString(section, _T("DTMFMethod"), DTMFMethod == 1 ? _T("1") : (DTMFMethod == 2 ? _T("2") : (DTMFMethod == 3 ? _T("3") : _T("0"))), iniFile); - - WritePrivateProfileString(section, _T("AA"), AA ? _T("1") : _T("0"), iniFile); - WritePrivateProfileString(section, _T("autoAnswer"), autoAnswer, iniFile); - - WritePrivateProfileString(section, _T("DND"), DND ? _T("1") : _T("0"), iniFile); - WritePrivateProfileString(section, _T("denyIncoming"), denyIncoming, iniFile); - - WritePrivateProfileString(section, _T("usersDirectory"), usersDirectory, iniFile); - - WritePrivateProfileString(section, _T("dnsSrv"), dnsSrv ? _T("1") : _T("0"), iniFile); - - WritePrivateProfileString(section, _T("STUN"), stun, iniFile); - - WritePrivateProfileString(section, _T("enableSTUN"), enableSTUN ? _T("1") : _T("0"), iniFile); - - WritePrivateProfileString(section, _T("singleMode"), singleMode ? _T("1") : _T("0"), iniFile); - - WritePrivateProfileString(section, _T("rport"), rport ? _T("1") : _T("0"), iniFile); - str.Format(_T("%d"), sourcePort); - WritePrivateProfileString(section, _T("sourcePort"), str, iniFile); - str.Format(_T("%d"), rtpPortMin); - WritePrivateProfileString(section, _T("rtpPortMin"), str, iniFile); - str.Format(_T("%d"), rtpPortMax); - WritePrivateProfileString(section, _T("rtpPortMax"), str, iniFile); - - WritePrivateProfileString(section, _T("silent"), silent ? _T("1") : _T("0"), iniFile); - - WritePrivateProfileString(section, _T("enableShortcuts"), enableShortcuts ? _T("1") : _T("0"), iniFile); - WritePrivateProfileString(section, _T("shortcutsBottom"), shortcutsBottom ? _T("1") : _T("0"), iniFile); - - WritePrivateProfileString(section, _T("enableMediaButtons"), enableMediaButtons ? _T("1") : _T("0"), iniFile); - WritePrivateProfileString(section, _T("localDTMF"), localDTMF ? _T("1") : _T("0"), iniFile); - WritePrivateProfileString(section, _T("ringingSound"), ringingSound, iniFile); - WritePrivateProfileString(section, _T("audioRingDevice"), _T("\"") + audioRingDevice + _T("\""), iniFile); - WritePrivateProfileString(section, _T("audioOutputDevice"), _T("\"") + audioOutputDevice + _T("\""), iniFile); - WritePrivateProfileString(section, _T("audioInputDevice"), _T("\"") + audioInputDevice + _T("\""), iniFile); - WritePrivateProfileString(section, _T("micAmplification"), micAmplification ? _T("1") : _T("0"), iniFile); - WritePrivateProfileString(section, _T("swLevelAdjustment"), swLevelAdjustment ? _T("1") : _T("0"), iniFile); - WritePrivateProfileString(section, _T("audioCodecs"), audioCodecs, iniFile); - WritePrivateProfileString(section, _T("VAD"), vad ? _T("1") : _T("0"), iniFile); - WritePrivateProfileString(section, _T("EC"), ec ? _T("1") : _T("0"), iniFile); - WritePrivateProfileString(section, _T("forceCodec"), forceCodec ? _T("1") : _T("0"), iniFile); -#ifdef _GLOBAL_VIDEO - WritePrivateProfileString(section, _T("videoCaptureDevice"), _T("\"") + videoCaptureDevice + _T("\""), iniFile); - WritePrivateProfileString(section, _T("videoCodec"), videoCodec, iniFile); - WritePrivateProfileString(section, _T("videoH264"), videoH264 ? _T("1") : _T("0"), iniFile); - WritePrivateProfileString(section, _T("videoH263"), videoH263 ? _T("1") : _T("0"), iniFile); - WritePrivateProfileString(section, _T("videoVP8"), videoVP8 ? _T("1") : _T("0"), iniFile); - str.Format(_T("%d"), videoBitrate); - WritePrivateProfileString(section, _T("videoBitrate"), str, iniFile); -#endif - - str.Format(_T("%d"), mainX); - WritePrivateProfileString(section, _T("mainX"), str, iniFile); - - str.Format(_T("%d"), mainY); - WritePrivateProfileString(section, _T("mainY"), str, iniFile); - - str.Format(_T("%d"), mainW); - WritePrivateProfileString(section, _T("mainW"), str, iniFile); - - str.Format(_T("%d"), mainH); - WritePrivateProfileString(section, _T("mainH"), str, iniFile); - - str.Format(_T("%d"), noResize); - WritePrivateProfileString(section, _T("noResize"), str, iniFile); - - str.Format(_T("%d"), messagesX); - WritePrivateProfileString(section, _T("messagesX"), str, iniFile); - - str.Format(_T("%d"), messagesY); - WritePrivateProfileString(section, _T("messagesY"), str, iniFile); - - str.Format(_T("%d"), messagesW); - WritePrivateProfileString(section, _T("messagesW"), str, iniFile); - - str.Format(_T("%d"), messagesH); - WritePrivateProfileString(section, _T("messagesH"), str, iniFile); - - str.Format(_T("%d"), ringinX); - WritePrivateProfileString(section, _T("ringinX"), str, iniFile); - - str.Format(_T("%d"), ringinY); - WritePrivateProfileString(section, _T("ringinY"), str, iniFile); - - str.Format(_T("%d"), callsWidth0); - WritePrivateProfileString(section, _T("callsWidth0"), str, iniFile); - - str.Format(_T("%d"), callsWidth1); - WritePrivateProfileString(section, _T("callsWidth1"), str, iniFile); - - str.Format(_T("%d"), callsWidth2); - WritePrivateProfileString(section, _T("callsWidth2"), str, iniFile); - - str.Format(_T("%d"), callsWidth3); - WritePrivateProfileString(section, _T("callsWidth3"), str, iniFile); - - str.Format(_T("%d"), callsWidth4); - WritePrivateProfileString(section, _T("callsWidth4"), str, iniFile); - - str.Format(_T("%d"), contactsWidth0); - WritePrivateProfileString(section, _T("contactsWidth0"), str, iniFile); - str.Format(_T("%d"), contactsWidth1); - WritePrivateProfileString(section, _T("contactsWidth1"), str, iniFile); - - str.Format(_T("%d"), volumeOutput); - WritePrivateProfileString(section, _T("volumeOutput"), str, iniFile); - - str.Format(_T("%d"), volumeInput); - WritePrivateProfileString(section, _T("volumeInput"), str, iniFile); - - str.Format(_T("%d"), activeTab); - WritePrivateProfileString(section, _T("activeTab"), str, iniFile); - - str.Format(_T("%d"), alwaysOnTop); - WritePrivateProfileString(section, _T("alwaysOnTop"), str, iniFile); - - str.Format(_T("%d"), autoHangUpTime); - WritePrivateProfileString(section, _T("autoHangUpTime"), str, iniFile); - - str.Format(_T("%d"), maxConcurrentCalls); - WritePrivateProfileString(section, _T("maxConcurrentCalls"), str, iniFile); - - WritePrivateProfileString(section, _T("cmdCallStart"), cmdCallStart, iniFile); - WritePrivateProfileString(section, _T("cmdCallEnd"), cmdCallEnd, iniFile); - WritePrivateProfileString(section, _T("cmdIncomingCall"), cmdIncomingCall, iniFile); - WritePrivateProfileString(section, _T("cmdCallAnswer"), cmdCallAnswer, iniFile); -} - -CString ShortcutEncode(Shortcut *pShortcut) -{ - CString data; - data.Format(_T("%s;%s;%d"), pShortcut->label, pShortcut->number, pShortcut->type); - return data; -} - -void ShortcutDecode(CString str, Shortcut *pShortcut) -{ - pShortcut->label.Empty(); - pShortcut->number.Empty(); - pShortcut->type = MSIP_SHORTCUT_DTMF; - - CString rab; - int begin; - int end; - begin = 0; - end = str.Find(';', begin); - if (end != -1) { - pShortcut->label = str.Mid(begin, end - begin); - begin = end + 1; - end = str.Find(';', begin); - if (end != -1) { - pShortcut->number = str.Mid(begin, end - begin); - begin = end + 1; - end = str.Find(';', begin); - if (end != -1) { - pShortcut->type = (msip_shortcut_type)_wtoi(str.Mid(begin, end - begin)); - } - else { - pShortcut->type = (msip_shortcut_type)_wtoi(str.Mid(begin)); - } - } - } -} - -void ShortcutsLoad() -{ - Shortcut shortcut; - CString key; - CString val; - LPTSTR ptr = val.GetBuffer(255); - int i = 0; - while (i < _GLOBAL_SHORTCUTS_QTY) { - key.Format(_T("%d"), i); - if (GetPrivateProfileString(_T("Shortcuts"), key, NULL, ptr, 256, accountSettings.iniFile)) { - ShortcutDecode(ptr, &shortcut); - shortcuts.Add(shortcut); - } - else { - break; - } - i++; - } - if (!shortcuts.GetCount()) { - } -} - -void ShortcutsSave() -{ - WritePrivateProfileSection(_T("Shortcuts"), NULL, accountSettings.iniFile); - for (int i = 0; i < shortcuts.GetCount(); i++) { - Shortcut shortcut = shortcuts.GetAt(i); - CString key; - key.Format(_T("%d"), i); - WritePrivateProfileString(_T("Shortcuts"), key, ShortcutEncode(&shortcut), accountSettings.iniFile); -} -} - diff --git a/microsip/settings.h b/microsip/settings.h deleted file mode 100644 index fa980d82..00000000 --- a/microsip/settings.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2011-2018 MicroSIP (http://www.microsip.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; 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 - */ - -#pragma once - -#include "global.h" - -struct Account { - CString label; - CString server; - CString proxy; - CString username; - CString domain; - int port; - CString authID; - CString password; - bool rememberPassword; - CString displayName; - CString voicemailNumber; - CString srtp; - CString transport; - CString publicAddr; - bool publish; - bool ice; - bool allowRewrite; - bool disableSessionTimer; - bool operator==(const Account& a) const { - if (label == a.label - && server == a.server - && proxy == a.proxy - && username == a.username - && domain == a.domain - && authID == a.authID - && password == a.password - && displayName == a.displayName - && srtp == a.srtp - && transport == a.transport - && publish == a.publish - && ice == a.ice - && allowRewrite == a.allowRewrite - ) - return true; - return false; - }; - bool operator!=(const Account& a) const { - return !(*this == a); - } - void operator=(const Account& a) - { - label = a.label; - server = a.server; - proxy = a.proxy; - username = a.username; - domain = a.domain; - authID = a.authID; - password = a.password; - displayName = a.displayName; - srtp = a.srtp; - transport = a.transport; - publish = a.publish; - ice = a.ice; - allowRewrite = a.allowRewrite; - }; - Account() : port(0) - , rememberPassword(false) - , publish(false) - , ice(false) - , allowRewrite(false) - , disableSessionTimer(false) - {} -}; - -struct AccountSettings { - - int accountId; - Account account; - bool singleMode; - CString ringingSound; - CString audioRingDevice; - CString audioOutputDevice; - CString audioInputDevice; - bool micAmplification; - bool swLevelAdjustment; - CString audioCodecs; - bool vad; - bool ec; - bool forceCodec; - CString videoCaptureDevice; - CString videoCodec; - bool videoH264; - bool videoH263; - bool videoVP8; - int videoBitrate; - bool rport; - int sourcePort; - int rtpPortMin; - int rtpPortMax; - bool dnsSrv; - CString stun; - bool enableSTUN; - int DTMFMethod; - bool AA; - bool DND; - CString autoAnswer; - CString denyIncoming; - CString usersDirectory; - bool enableMediaButtons; - bool localDTMF; - bool enableLocalAccount; - bool crashReport; - bool enableLog; - bool bringToFrontOnIncoming; - bool randomAnswerBox; - CString userAgent; - CString portKnockerHost; - CString portKnockerPorts; - - CString lastCallNumber; - bool lastCallHasVideo; - - CString updatesInterval; - - int activeTab; - bool alwaysOnTop; - - int mainX; - int mainY; - int mainW; - int mainH; - bool noResize; - - int messagesX; - int messagesY; - int messagesW; - int messagesH; - - int ringinX; - int ringinY; - - int callsWidth0; - int callsWidth1; - int callsWidth2; - int callsWidth3; - int callsWidth4; - - int contactsWidth0; - int contactsWidth1; - - int volumeOutput; - int volumeInput; - - CString iniFile; - CString logFile; - CString exeFile; - CString pathRoaming; - CString pathLocal; - CString pathExe; - - int checkUpdatesTime; - - bool hidden; - bool silent; - - int autoHangUpTime; - int maxConcurrentCalls; - - CString cmdCallStart; - CString cmdCallEnd; - CString cmdIncomingCall; - CString cmdCallAnswer; - bool enableShortcuts; - bool shortcutsBottom; - AccountSettings(); - void Init(); - bool AccountLoad(int id, Account *account); - void AccountSave(int id, Account *account); - void AccountDelete(int id); - void SettingsSave(); -}; - -extern AccountSettings accountSettings; -extern bool firstRun; -extern bool pj_ready; -extern CTime startTime; - -CString ShortcutEncode(Shortcut *pShortcut); -void ShortcutDecode(CString str, Shortcut *pShortcut); -void ShortcutsLoad(); -void ShortcutsSave(); -extern CArray shortcuts; diff --git a/microsip/stdafx.cpp b/microsip/stdafx.cpp deleted file mode 100644 index 0931d26a..00000000 --- a/microsip/stdafx.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// microsip.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - - diff --git a/microsip/stdafx.h b/microsip/stdafx.h deleted file mode 100644 index 6c3033d6..00000000 --- a/microsip/stdafx.h +++ /dev/null @@ -1,60 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, -// but are changed infrequently - -#pragma once - -#ifndef _SECURE_ATL -#define _SECURE_ATL 1 -#endif - -#ifndef VC_EXTRALEAN -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers -#endif - -#include "targetver.h" - -#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit - -// turns off MFC's hiding of some common and often safely ignored warning messages -#define _AFX_ALL_WARNINGS - -#include // MFC core and standard components -#include // MFC extensions - - -#include // MFC Automation classes - - - -#ifndef _AFX_NO_OLE_SUPPORT -#include // MFC support for Internet Explorer 4 Common Controls -#endif -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT -#include - -#define SECURITY_WIN32 -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _UNICODE -#if defined _M_IX86 -#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") -#elif defined _M_IA64 -#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"") -#elif defined _M_X64 -#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") -#else -#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") -#endif -#endif - - diff --git a/microsip/targetver.h b/microsip/targetver.h deleted file mode 100644 index 56a907e4..00000000 --- a/microsip/targetver.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -// The following macros define the minimum required platform. The minimum required platform -// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run -// your application. The macros work by enabling all features available on platform versions up to and -// including the version specified. - -// Modify the following defines if you have to target a platform prior to the ones specified below. -// Refer to MSDN for the latest info on corresponding values for different platforms. -#ifndef WINVER -#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows. -#endif - -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. -#endif - -#ifndef _WIN32_WINDOWS -#define _WIN32_WINDOWS 0x0501 // Change this to the appropriate value to target other versions of Windows. -#endif - -#ifndef NTDDI_VERSION -#define NTDDI_VERSION 0x05010000 // Change this to the appropriate value to target other versions of Windows. -#endif - -#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0. -#define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE. -#endif diff --git a/microsip/utf.cpp b/microsip/utf.cpp deleted file mode 100644 index 1ee660bc..00000000 --- a/microsip/utf.cpp +++ /dev/null @@ -1,420 +0,0 @@ -#include "StdAfx.h" -#include "utf.h" - -/* number of following bytes in sequence based on first byte value (for bytes above 0x7f) */ -static const char utf8_length[128] = -{ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x80-0x8f */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x90-0x9f */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xa0-0xaf */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xb0-0xbf */ - 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0xc0-0xcf */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0xd0-0xdf */ - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* 0xe0-0xef */ - 3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0 /* 0xf0-0xff */ -}; - -/* first byte mask depending on UTF-8 sequence length */ -static const unsigned char utf8_mask[4] = { 0x7f, 0x1f, 0x0f, 0x07 }; - -/* minimum Unicode value depending on UTF-8 sequence length */ -static const unsigned int utf8_minval[4] = { 0x0, 0x80, 0x800, 0x10000 }; - - -/* get the next char value taking surrogates into account */ -static unsigned int getSurrogateValue(const wchar_t *src, unsigned int srclen) -{ - if (src[0] >= 0xd800 && src[0] <= 0xdfff) /* surrogate pair */ - { - if (src[0] > 0xdbff || /* invalid high surrogate */ - srclen <= 1 || /* missing low surrogate */ - src[1] < 0xdc00 || src[1] > 0xdfff) /* invalid low surrogate */ - return 0; - return 0x10000 + ((src[0] & 0x3ff) << 10) + (src[1] & 0x3ff); - } - return src[0]; -} - -/* query necessary dst length for src string */ -static int Ucs2toUtf8Len(const wchar_t *src, unsigned int srclen) -{ - int len; - unsigned int val; - - for (len = 0; srclen; srclen--, src++) - { - if (*src < 0x80) /* 0x00-0x7f: 1 byte */ - { - len++; - continue; - } - if (*src < 0x800) /* 0x80-0x7ff: 2 bytes */ - { - len += 2; - continue; - } - if (!(val = getSurrogateValue(src, srclen))) - { - return -2; - } - if (val < 0x10000) /* 0x800-0xffff: 3 bytes */ - len += 3; - else /* 0x10000-0x10ffff: 4 bytes */ - { - len += 4; - src++; - srclen--; - } - } - return len; -} - -int Ucs2toUtf8Len(const wchar_t *src) -{ - if ( src == 0 ) - return 0; - - return Ucs2toUtf8Len( src, (int)wcslen( src )); -} - -/* wide char to UTF-8 string conversion */ -/* return -1 on dst buffer overflow, -2 on invalid input char */ -int Ucs2toUtf8(const wchar_t *src, int srclen, char *dst, int dstlen) -{ - int len; - - for (len = dstlen; srclen; srclen--, src++) - { - WCHAR ch = *src; - unsigned int val; - - if (ch < 0x80) /* 0x00-0x7f: 1 byte */ - { - if (!len--) return -1; /* overflow */ - *dst++ = ch; - continue; - } - - if (ch < 0x800) /* 0x80-0x7ff: 2 bytes */ - { - if ((len -= 2) < 0) return -1; /* overflow */ - dst[1] = 0x80 | (ch & 0x3f); - ch >>= 6; - dst[0] = 0xc0 | ch; - dst += 2; - continue; - } - - if (!(val = getSurrogateValue(src, srclen))) - { - return -2; - } - - if (val < 0x10000) /* 0x800-0xffff: 3 bytes */ - { - if ((len -= 3) < 0) return -1; /* overflow */ - dst[2] = 0x80 | (val & 0x3f); - val >>= 6; - dst[1] = 0x80 | (val & 0x3f); - val >>= 6; - dst[0] = 0xe0 | val; - dst += 3; - } - else /* 0x10000-0x10ffff: 4 bytes */ - { - if ((len -= 4) < 0) return -1; /* overflow */ - dst[3] = 0x80 | (val & 0x3f); - val >>= 6; - dst[2] = 0x80 | (val & 0x3f); - val >>= 6; - dst[1] = 0x80 | (val & 0x3f); - val >>= 6; - dst[0] = 0xf0 | val; - dst += 4; - src++; - srclen--; - } - } - return dstlen - len; -} - -/* helper for the various utf8 mbstowcs functions */ -static unsigned int decodeUtf8Char(unsigned char ch, const char **str, const char *strend) -{ - unsigned int len = utf8_length[ch-0x80]; - unsigned int res = ch & utf8_mask[len]; - const char *end = *str + len; - - if (end > strend) return ~0; - switch(len) - { - case 3: - if ((ch = end[-3] ^ 0x80) >= 0x40) break; - res = (res << 6) | ch; - (*str)++; - case 2: - if ((ch = end[-2] ^ 0x80) >= 0x40) break; - res = (res << 6) | ch; - (*str)++; - case 1: - if ((ch = end[-1] ^ 0x80) >= 0x40) break; - res = (res << 6) | ch; - (*str)++; - if (res < utf8_minval[len]) break; - return res; - } - return ~0; -} - -/* query necessary dst length for src string */ -static inline int Utf8toUcs2Len(const char *src, int srclen) -{ - int ret = 0; - unsigned int res; - const char *srcend = src + srclen; - - while (src < srcend) - { - unsigned char ch = *src++; - if (ch < 0x80) /* special fast case for 7-bit ASCII */ - { - ret++; - continue; - } - if ((res = decodeUtf8Char(ch, &src, srcend)) <= 0x10ffff) - { - if (res > 0xffff) ret++; - ret++; - } - else return -2; /* bad char */ - /* otherwise ignore it */ - } - return ret; -} - -/* UTF-8 to wide char string conversion */ -/* return -1 on dst buffer overflow, -2 on invalid input char */ -int Utf8toUcs2(const char *src, int srclen, wchar_t *dst, int dstlen) -{ - unsigned int res; - const char *srcend = src + srclen; - wchar_t *dstend = dst + dstlen; - - while ((dst < dstend) && (src < srcend)) - { - unsigned char ch = *src++; - if (ch < 0x80) /* special fast case for 7-bit ASCII */ - { - *dst++ = ch; - continue; - } - if ((res = decodeUtf8Char(ch, &src, srcend)) <= 0xffff) - { - *dst++ = res; - } - else if (res <= 0x10ffff) /* we need surrogates */ - { - if (dst == dstend - 1) return -1; /* overflow */ - res -= 0x10000; - *dst++ = 0xd800 | (res >> 10); - *dst++ = 0xdc00 | (res & 0x3ff); - } - else return -2; /* bad char */ - /* otherwise ignore it */ - } - if (src < srcend) return -1; /* overflow */ - return dstlen - (dstend - dst); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Utf8Decode - converts UTF8-encoded string to the UCS2/MBCS format - -char* Utf8DecodeCP(char* str, int codepage, wchar_t** ucs2) -{ - int len; - bool needs_free = false; - wchar_t* tempBuf = NULL; - if ( ucs2 ) - *ucs2 = NULL; - - if (str == NULL) - return NULL; - - len = (int)strlen(str); - - if (len < 2) { - if (ucs2 != NULL) { - *ucs2 = tempBuf = (wchar_t*)malloc((len + 1) * sizeof(wchar_t)); - MultiByteToWideChar(codepage, 0, str, len, tempBuf, len); - tempBuf[len] = 0; - } - return str; - } - - int destlen = Utf8toUcs2Len(str, len); - if (destlen < 0) - return NULL; - - if (ucs2 == NULL) { - __try - { - tempBuf = (wchar_t*)alloca((destlen + 1) * sizeof(wchar_t)); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - tempBuf = NULL; - needs_free = true; - } - } - - if ( tempBuf == NULL ) { - tempBuf = (wchar_t*)malloc((destlen + 1) * sizeof(wchar_t)); - if ( tempBuf == NULL ) - return NULL; - } - - Utf8toUcs2(str, len, tempBuf, destlen); - tempBuf[destlen] = 0; - WideCharToMultiByte(codepage, 0, tempBuf, -1, str, len + 1, "?", NULL); - - if (ucs2) - *ucs2 = tempBuf; - else if (needs_free) - free(tempBuf); - - return str; -} - -wchar_t* Utf8DecodeUcs2(const char* str) -{ - if (str == NULL) - return NULL; - - int len = (int)strlen(str); - - int destlen = Utf8toUcs2Len(str, len); - if (destlen < 0) return NULL; - - wchar_t* ucs2 = (wchar_t*)malloc((destlen + 1) * sizeof(wchar_t)); - if (ucs2 == NULL) return NULL; - - if (Utf8toUcs2(str, len, ucs2, destlen) >= 0) - { - ucs2[destlen] = 0; - return ucs2; - } - - free(ucs2); - - return NULL; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Utf8Encode - converts MBCS string to the UTF8-encoded format - -char* Utf8EncodeCP(const char* src, int codepage) -{ - int len; - bool needs_free = false; - char* result = NULL; - wchar_t* tempBuf; - - if (src == NULL) - return NULL; - - len = (int)strlen(src); - - __try - { - tempBuf = (wchar_t*)alloca((len + 1) * sizeof(wchar_t)); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - tempBuf = (wchar_t*)malloc((len + 1) * sizeof(wchar_t)); - if (tempBuf == NULL) return NULL; - needs_free = true; - } - - len = MultiByteToWideChar(codepage, 0, src, -1, tempBuf, len + 1); - - int destlen = Ucs2toUtf8Len(tempBuf, len); - if (destlen >= 0) - { - result = (char*)malloc(destlen + 1); - if (result) - { - Ucs2toUtf8(tempBuf, len, result, destlen); - result[destlen] = 0; - } - } - - if (needs_free) - free(tempBuf); - - return result; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Utf8Encode - converts UCS2 string to the UTF8-encoded format - -char* Utf8EncodeUcs2(const wchar_t* src) -{ - if (src == NULL) - return NULL; - - int len = (int)wcslen(src); - - int destlen = Ucs2toUtf8Len(src, len); - if (destlen < 0) return NULL; - - char* result = (char*)malloc(destlen + 1); - if (result == NULL) - return NULL; - - Ucs2toUtf8(src, len, result, destlen); - result[destlen] = 0; - - return result; -} - -bool is_utf8_string(const char* str) -{ - int expect_bytes = 0, utf_found = 0; - - if (!str) return 0; - - while (*str) { - if ((*str & 0x80) == 0) { - /* Looks like an ASCII character */ - if (expect_bytes) - /* byte of UTF-8 character expected */ - return 0; - } - else { - /* Looks like byte of an UTF-8 character */ - if (expect_bytes) { - /* expect_bytes already set: first byte of UTF-8 char already seen */ - if ((*str & 0xC0) != 0x80) { - /* again first byte ?!?! */ - return 0; - } - } - else { - /* First byte of the UTF-8 character */ - /* count initial one bits and set expect_bytes to 1 less */ - char ch = *str; - while (ch & 0x80) { - expect_bytes++; - ch = (ch & 0x7f) << 1; - } - } - /* OK, next byte of UTF-8 character */ - /* Decrement number of expected bytes */ - if ( --expect_bytes == 0 ) - utf_found = 1; - } - str++; - } - - return (utf_found && expect_bytes == 0); -} diff --git a/microsip/utf.h b/microsip/utf.h deleted file mode 100644 index 2c25c657..00000000 --- a/microsip/utf.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -char* Utf8DecodeCP(char* str, int codepage, wchar_t** ucs2); -char* Utf8EncodeCP(const char* src, int codepage); -char* Utf8EncodeUcs2(const wchar_t* src); diff --git a/microsip/zip.cpp b/microsip/zip.cpp deleted file mode 100644 index eeb6b8f9..00000000 --- a/microsip/zip.cpp +++ /dev/null @@ -1,2830 +0,0 @@ -#include -#include -#include -#include "zip.h" - - -// THIS FILE is almost entirely based upon code by info-zip. -// It has been modified by Lucian Wischik. The modifications -// were a complete rewrite of the bit of code that generates the -// layout of the zipfile, and support for zipping to/from memory -// or handles or pipes or pagefile or diskfiles, encryption, unicode. -// The original code may be found at http://www.info-zip.org -// The original copyright text follows. -// -// -// -// This is version 1999-Oct-05 of the Info-ZIP copyright and license. -// The definitive version of this document should be available at -// ftp://ftp.cdrom.com/pub/infozip/license.html indefinitely. -// -// Copyright (c) 1990-1999 Info-ZIP. All rights reserved. -// -// For the purposes of this copyright and license, "Info-ZIP" is defined as -// the following set of individuals: -// -// Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois, -// Jean-loup Gailly, Hunter Goatley, Ian Gorman, Chris Herborth, Dirk Haase, -// Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz, David Kirschbaum, -// Johnny Lee, Onno van der Linden, Igor Mandrichenko, Steve P. Miller, -// Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs, Kai Uwe Rommel, -// Steve Salisbury, Dave Smith, Christian Spieler, Antoine Verheijen, -// Paul von Behren, Rich Wales, Mike White -// -// This software is provided "as is," without warranty of any kind, express -// or implied. In no event shall Info-ZIP or its contributors be held liable -// for any direct, indirect, incidental, special or consequential damages -// arising out of the use of or inability to use this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. Redistributions of source code must retain the above copyright notice, -// definition, disclaimer, and this list of conditions. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, definition, disclaimer, and this list of conditions in -// documentation and/or other materials provided with the distribution. -// -// 3. Altered versions--including, but not limited to, ports to new operating -// systems, existing ports with new graphical interfaces, and dynamic, -// shared, or static library versions--must be plainly marked as such -// and must not be misrepresented as being the original source. Such -// altered versions also must not be misrepresented as being Info-ZIP -// releases--including, but not limited to, labeling of the altered -// versions with the names "Info-ZIP" (or any variation thereof, including, -// but not limited to, different capitalizations), "Pocket UnZip," "WiZ" -// or "MacZip" without the explicit permission of Info-ZIP. Such altered -// versions are further prohibited from misrepresentative use of the -// Zip-Bugs or Info-ZIP e-mail addresses or of the Info-ZIP URL(s). -// -// 4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip," -// "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its own source and -// binary releases. -// - - -typedef unsigned char uch; // unsigned 8-bit value -typedef unsigned short ush; // unsigned 16-bit value -typedef unsigned long ulg; // unsigned 32-bit value -typedef size_t extent; // file size -typedef unsigned Pos; // must be at least 32 bits -typedef unsigned IPos; // A Pos is an index in the character window. Pos is used only for parameter passing - -#ifndef EOF -#define EOF (-1) -#endif - - -// Error return values. The values 0..4 and 12..18 follow the conventions -// of PKZIP. The values 4..10 are all assigned to "insufficient memory" -// by PKZIP, so the codes 5..10 are used here for other purposes. -#define ZE_MISS -1 // used by procname(), zipbare() -#define ZE_OK 0 // success -#define ZE_EOF 2 // unexpected end of zip file -#define ZE_FORM 3 // zip file structure error -#define ZE_MEM 4 // out of memory -#define ZE_LOGIC 5 // internal logic error -#define ZE_BIG 6 // entry too large to split -#define ZE_NOTE 7 // invalid comment format -#define ZE_TEST 8 // zip test (-T) failed or out of memory -#define ZE_ABORT 9 // user interrupt or termination -#define ZE_TEMP 10 // error using a temp file -#define ZE_READ 11 // read or seek error -#define ZE_NONE 12 // nothing to do -#define ZE_NAME 13 // missing or empty zip file -#define ZE_WRITE 14 // error writing to a file -#define ZE_CREAT 15 // couldn't open to write -#define ZE_PARMS 16 // bad command line -#define ZE_OPEN 18 // could not open a specified file to read -#define ZE_MAXERR 18 // the highest error number - - -// internal file attribute -#define UNKNOWN (-1) -#define BINARY 0 -#define ASCII 1 - -#define BEST -1 // Use best method (deflation or store) -#define STORE 0 // Store method -#define DEFLATE 8 // Deflation method - -#define CRCVAL_INITIAL 0L - -// MSDOS file or directory attributes -#define MSDOS_HIDDEN_ATTR 0x02 -#define MSDOS_DIR_ATTR 0x10 - -// Lengths of headers after signatures in bytes -#define LOCHEAD 26 -#define CENHEAD 42 -#define ENDHEAD 18 - -// Definitions for extra field handling: -#define EB_HEADSIZE 4 /* length of a extra field block header */ -#define EB_LEN 2 /* offset of data length field in header */ -#define EB_UT_MINLEN 1 /* minimal UT field contains Flags byte */ -#define EB_UT_FLAGS 0 /* byte offset of Flags field */ -#define EB_UT_TIME1 1 /* byte offset of 1st time value */ -#define EB_UT_FL_MTIME (1 << 0) /* mtime present */ -#define EB_UT_FL_ATIME (1 << 1) /* atime present */ -#define EB_UT_FL_CTIME (1 << 2) /* ctime present */ -#define EB_UT_LEN(n) (EB_UT_MINLEN + 4 * (n)) -#define EB_L_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(3)) -#define EB_C_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(1)) - - -// Macros for writing machine integers to little-endian format -#define PUTSH(a,f) {char _putsh_c=(char)((a)&0xff); wfunc(param,&_putsh_c,1); _putsh_c=(char)((a)>>8); wfunc(param,&_putsh_c,1);} -#define PUTLG(a,f) {PUTSH((a) & 0xffff,(f)) PUTSH((a) >> 16,(f))} - - -// -- Structure of a ZIP file -- -// Signatures for zip file information headers -#define LOCSIG 0x04034b50L -#define CENSIG 0x02014b50L -#define ENDSIG 0x06054b50L -#define EXTLOCSIG 0x08074b50L - - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -// The minimum and maximum match lengths - - -#define WSIZE (0x8000) -// Maximum window size = 32K. If you are really short of memory, compile -// with a smaller WSIZE but this reduces the compression ratio for files -// of size > WSIZE. WSIZE must be a power of two in the current implementation. -// - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -// Minimum amount of lookahead, except at the end of the input file. -// See deflate.c for comments about the MIN_MATCH+1. -// - -#define MAX_DIST (WSIZE-MIN_LOOKAHEAD) -// In order to simplify the code, particularly on 16 bit machines, match -// distances are limited to MAX_DIST instead of WSIZE. -// - - -#define ZIP_HANDLE 1 -#define ZIP_FILENAME 2 -#define ZIP_MEMORY 3 -#define ZIP_FOLDER 4 - - - -// =========================================================================== -// Constants -// - -#define MAX_BITS 15 -// All codes must not exceed MAX_BITS bits - -#define MAX_BL_BITS 7 -// Bit length codes must not exceed MAX_BL_BITS bits - -#define LENGTH_CODES 29 -// number of length codes, not counting the special END_BLOCK code - -#define LITERALS 256 -// number of literal bytes 0..255 - -#define END_BLOCK 256 -// end of block literal code - -#define L_CODES (LITERALS+1+LENGTH_CODES) -// number of Literal or Length codes, including the END_BLOCK code - -#define D_CODES 30 -// number of distance codes - -#define BL_CODES 19 -// number of codes used to transfer the bit lengths - - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -// The three kinds of block type - -#define LIT_BUFSIZE 0x8000 -#define DIST_BUFSIZE LIT_BUFSIZE -// Sizes of match buffers for literals/lengths and distances. There are -// 4 reasons for limiting LIT_BUFSIZE to 64K: -// - frequencies can be kept in 16 bit counters -// - if compression is not successful for the first block, all input data is -// still in the window so we can still emit a stored block even when input -// comes from standard input. (This can also be done for all blocks if -// LIT_BUFSIZE is not greater than 32K.) -// - if compression is not successful for a file smaller than 64K, we can -// even emit a stored file instead of a stored block (saving 5 bytes). -// - creating new Huffman trees less frequently may not provide fast -// adaptation to changes in the input data statistics. (Take for -// example a binary file with poorly compressible code followed by -// a highly compressible string table.) Smaller buffer sizes give -// fast adaptation but have of course the overhead of transmitting trees -// more frequently. -// - I can't count above 4 -// The current code is general and allows DIST_BUFSIZE < LIT_BUFSIZE (to save -// memory at the expense of compression). Some optimizations would be possible -// if we rely on DIST_BUFSIZE == LIT_BUFSIZE. -// - -#define REP_3_6 16 -// repeat previous bit length 3-6 times (2 bits of repeat count) - -#define REPZ_3_10 17 -// repeat a zero length 3-10 times (3 bits of repeat count) - -#define REPZ_11_138 18 -// repeat a zero length 11-138 times (7 bits of repeat count) - -#define HEAP_SIZE (2*L_CODES+1) -// maximum heap size - - -// =========================================================================== -// Local data used by the "bit string" routines. -// - -#define Buf_size (8 * 2*sizeof(char)) -// Number of bits used within bi_buf. (bi_buf may be implemented on -// more than 16 bits on some systems.) - -// Output a 16 bit value to the bit stream, lower (oldest) byte first -#define PUTSHORT(state,w) \ -{ if (state.bs.out_offset >= state.bs.out_size-1) \ - state.flush_outbuf(state.param,state.bs.out_buf, &state.bs.out_offset); \ - state.bs.out_buf[state.bs.out_offset++] = (char) ((w) & 0xff); \ - state.bs.out_buf[state.bs.out_offset++] = (char) ((ush)(w) >> 8); \ -} - -#define PUTBYTE(state,b) \ -{ if (state.bs.out_offset >= state.bs.out_size) \ - state.flush_outbuf(state.param,state.bs.out_buf, &state.bs.out_offset); \ - state.bs.out_buf[state.bs.out_offset++] = (char) (b); \ -} - -// DEFLATE.CPP HEADER - -#define HASH_BITS 15 -// For portability to 16 bit machines, do not use values above 15. - -#define HASH_SIZE (unsigned)(1<= HASH_BITS - -#define max_insert_length max_lazy_match -// Insert new strings in the hash table only if the match length -// is not greater than this length. This saves time but degrades compression. -// max_insert_length is used only for compression levels <= 3. - - - -const int extra_lbits[LENGTH_CODES] // extra bits for each length code - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -const int extra_dbits[D_CODES] // extra bits for each distance code - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -const int extra_blbits[BL_CODES]// extra bits for each bit length code - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -const uch bl_order[BL_CODES] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -// The lengths of the bit length codes are sent in order of decreasing -// probability, to avoid transmitting the lengths for unused bit length codes. - - -typedef struct config { - ush good_length; // reduce lazy search above this match length - ush max_lazy; // do not perform lazy search above this match length - ush nice_length; // quit search above this match length - ush max_chain; -} config; - -// Values for max_lazy_match, good_match, nice_match and max_chain_length, -// depending on the desired pack level (0..9). The values given below have -// been tuned to exclude worst case performance for pathological files. -// Better values may be found for specific files. -// - -const config configuration_table[10] = { -// good lazy nice chain - {0, 0, 0, 0}, // 0 store only - {4, 4, 8, 4}, // 1 maximum speed, no lazy matches - {4, 5, 16, 8}, // 2 - {4, 6, 32, 32}, // 3 - {4, 4, 16, 16}, // 4 lazy matches */ - {8, 16, 32, 32}, // 5 - {8, 16, 128, 128}, // 6 - {8, 32, 128, 256}, // 7 - {32, 128, 258, 1024}, // 8 - {32, 258, 258, 4096}};// 9 maximum compression */ - -// Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 -// For deflate_fast() (levels <= 3) good is ignored and lazy has a different meaning. - - - - - - - -// Data structure describing a single value and its code string. -typedef struct ct_data { - union { - ush freq; // frequency count - ush code; // bit string - } fc; - union { - ush dad; // father node in Huffman tree - ush len; // length of bit string - } dl; -} ct_data; - -typedef struct tree_desc { - ct_data *dyn_tree; // the dynamic tree - ct_data *static_tree; // corresponding static tree or NULL - const int *extra_bits; // extra bits for each code or NULL - int extra_base; // base index for extra_bits - int elems; // max number of elements in the tree - int max_length; // max bit length for the codes - int max_code; // largest code with non zero frequency -} tree_desc; - - - - -class TTreeState -{ public: - TTreeState(); - - ct_data dyn_ltree[HEAP_SIZE]; // literal and length tree - ct_data dyn_dtree[2*D_CODES+1]; // distance tree - ct_data static_ltree[L_CODES+2]; // the static literal tree... - // ... Since the bit lengths are imposed, there is no need for the L_CODES - // extra codes used during heap construction. However the codes 286 and 287 - // are needed to build a canonical tree (see ct_init below). - ct_data static_dtree[D_CODES]; // the static distance tree... - // ... (Actually a trivial tree since all codes use 5 bits.) - ct_data bl_tree[2*BL_CODES+1]; // Huffman tree for the bit lengths - - tree_desc l_desc; - tree_desc d_desc; - tree_desc bl_desc; - - ush bl_count[MAX_BITS+1]; // number of codes at each bit length for an optimal tree - - int heap[2*L_CODES+1]; // heap used to build the Huffman trees - int heap_len; // number of elements in the heap - int heap_max; // element of largest frequency - // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - // The same heap array is used to build all trees. - - uch depth[2*L_CODES+1]; - // Depth of each subtree used as tie breaker for trees of equal frequency - - uch length_code[MAX_MATCH-MIN_MATCH+1]; - // length code for each normalized match length (0 == MIN_MATCH) - - uch dist_code[512]; - // distance codes. The first 256 values correspond to the distances - // 3 .. 258, the last 256 values correspond to the top 8 bits of - // the 15 bit distances. - - int base_length[LENGTH_CODES]; - // First normalized length for each code (0 = MIN_MATCH) - - int base_dist[D_CODES]; - // First normalized distance for each code (0 = distance of 1) - - uch far l_buf[LIT_BUFSIZE]; // buffer for literals/lengths - ush far d_buf[DIST_BUFSIZE]; // buffer for distances - - uch flag_buf[(LIT_BUFSIZE/8)]; - // flag_buf is a bit array distinguishing literals from lengths in - // l_buf, and thus indicating the presence or absence of a distance. - - unsigned last_lit; // running index in l_buf - unsigned last_dist; // running index in d_buf - unsigned last_flags; // running index in flag_buf - uch flags; // current flags not yet saved in flag_buf - uch flag_bit; // current bit used in flags - // bits are filled in flags starting at bit 0 (least significant). - // Note: these flags are overkill in the current code since we don't - // take advantage of DIST_BUFSIZE == LIT_BUFSIZE. - - ulg opt_len; // bit length of current block with optimal trees - ulg static_len; // bit length of current block with static trees - - ulg cmpr_bytelen; // total byte length of compressed file - ulg cmpr_len_bits; // number of bits past 'cmpr_bytelen' - - ulg input_len; // total byte length of input file - // input_len is for debugging only since we can get it by other means. - - ush *file_type; // pointer to UNKNOWN, BINARY or ASCII -// int *file_method; // pointer to DEFLATE or STORE -}; - -TTreeState::TTreeState() -{ tree_desc a = {dyn_ltree, static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS, 0}; l_desc = a; - tree_desc b = {dyn_dtree, static_dtree, extra_dbits, 0, D_CODES, MAX_BITS, 0}; d_desc = b; - tree_desc c = {bl_tree, NULL, extra_blbits, 0, BL_CODES, MAX_BL_BITS, 0}; bl_desc = c; - last_lit=0; - last_dist=0; - last_flags=0; -} - - - -class TBitState -{ public: - - int flush_flg; - // - unsigned bi_buf; - // Output buffer. bits are inserted starting at the bottom (least significant - // bits). The width of bi_buf must be at least 16 bits. - int bi_valid; - // Number of valid bits in bi_buf. All bits above the last valid bit - // are always zero. - char *out_buf; - // Current output buffer. - unsigned out_offset; - // Current offset in output buffer. - // On 16 bit machines, the buffer is limited to 64K. - unsigned out_size; - // Size of current output buffer - ulg bits_sent; // bit length of the compressed data only needed for debugging??? -}; - - - - - - - -class TDeflateState -{ public: - TDeflateState() {window_size=0;} - - uch window[2L*WSIZE]; - // Sliding window. Input bytes are read into the second half of the window, - // and move to the first half later to keep a dictionary of at least WSIZE - // bytes. With this organization, matches are limited to a distance of - // WSIZE-MAX_MATCH bytes, but this ensures that IO is always - // performed with a length multiple of the block size. Also, it limits - // the window size to 64K, which is quite useful on MSDOS. - // To do: limit the window size to WSIZE+CBSZ if SMALL_MEM (the code would - // be less efficient since the data would have to be copied WSIZE/CBSZ times) - Pos prev[WSIZE]; - // Link to older string with same hash index. To limit the size of this - // array to 64K, this link is maintained only for the last 32K strings. - // An index in this array is thus a window index modulo 32K. - Pos head[HASH_SIZE]; - // Heads of the hash chains or NIL. If your compiler thinks that - // HASH_SIZE is a dynamic value, recompile with -DDYN_ALLOC. - - ulg window_size; - // window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the - // input file length plus MIN_LOOKAHEAD. - - long block_start; - // window position at the beginning of the current output block. Gets - // negative when the window is moved backwards. - - int sliding; - // Set to false when the input file is already in memory - - unsigned ins_h; // hash index of string to be inserted - - unsigned int prev_length; - // Length of the best match at previous step. Matches not greater than this - // are discarded. This is used in the lazy match evaluation. - - unsigned strstart; // start of string to insert - unsigned match_start; // start of matching string - int eofile; // flag set at end of input file - unsigned lookahead; // number of valid bytes ahead in window - - unsigned max_chain_length; - // To speed up deflation, hash chains are never searched beyond this length. - // A higher limit improves compression ratio but degrades the speed. - - unsigned int max_lazy_match; - // Attempt to find a better match only when the current match is strictly - // smaller than this value. This mechanism is used only for compression - // levels >= 4. - - unsigned good_match; - // Use a faster search when the previous match is longer than this - - int nice_match; // Stop searching when current match exceeds this -}; - -typedef __int64 lutime_t; // define it ourselves since we don't include time.h - -typedef struct iztimes { - lutime_t atime,mtime,ctime; -} iztimes; // access, modify, create times - -typedef struct zlist { - ush vem, ver, flg, how; // See central header in zipfile.c for what vem..off are - ulg tim, crc, siz, len; - extent nam, ext, cext, com; // offset of ext must be >= LOCHEAD - ush dsk, att, lflg; // offset of lflg must be >= LOCHEAD - ulg atx, off; - char name[MAX_PATH]; // File name in zip file - char *extra; // Extra field (set only if ext != 0) - char *cextra; // Extra in central (set only if cext != 0) - char *comment; // Comment (set only if com != 0) - char iname[MAX_PATH]; // Internal file name after cleanup - char zname[MAX_PATH]; // External version of internal name - int mark; // Marker for files to operate on - int trash; // Marker for files to delete - int dosflag; // Set to force MSDOS file attributes - struct zlist far *nxt; // Pointer to next header in list -} TZipFileInfo; - - -struct TState; -typedef unsigned (*READFUNC)(TState &state, char *buf,unsigned size); -typedef unsigned (*FLUSHFUNC)(void *param, const char *buf, unsigned *size); -typedef unsigned (*WRITEFUNC)(void *param, const char *buf, unsigned size); -struct TState -{ void *param; - int level; bool seekable; - READFUNC readfunc; FLUSHFUNC flush_outbuf; - TTreeState ts; TBitState bs; TDeflateState ds; - const char *err; -}; - - - - - - - - - -void Assert(TState &state,bool cond, const char *msg) -{ if (cond) return; - state.err=msg; -} -void __cdecl Trace(const char *x, ...) {va_list paramList; va_start(paramList, x); paramList; va_end(paramList);} -void __cdecl Tracec(bool ,const char *x, ...) {va_list paramList; va_start(paramList, x); paramList; va_end(paramList);} - - - -// =========================================================================== -// Local (static) routines in this file. -// - -void init_block (TState &); -void pqdownheap (TState &,ct_data *tree, int k); -void gen_bitlen (TState &,tree_desc *desc); -void gen_codes (TState &state,ct_data *tree, int max_code); -void build_tree (TState &,tree_desc *desc); -void scan_tree (TState &,ct_data *tree, int max_code); -void send_tree (TState &state,ct_data *tree, int max_code); -int build_bl_tree (TState &); -void send_all_trees (TState &state,int lcodes, int dcodes, int blcodes); -void compress_block (TState &state,ct_data *ltree, ct_data *dtree); -void set_file_type (TState &); -void send_bits (TState &state, int value, int length); -unsigned bi_reverse (unsigned code, int len); -void bi_windup (TState &state); -void copy_block (TState &state,char *buf, unsigned len, int header); - - -#define send_code(state, c, tree) send_bits(state, tree[c].fc.code, tree[c].dl.len) -// Send a code of the given tree. c and tree must not have side effects - -// alternatively... -//#define send_code(state, c, tree) -// { if (state.verbose>1) fprintf(stderr,"\ncd %3d ",(c)); -// send_bits(state, tree[c].fc.code, tree[c].dl.len); } - -#define d_code(dist) ((dist) < 256 ? state.ts.dist_code[dist] : state.ts.dist_code[256+((dist)>>7)]) -// Mapping from a distance to a distance code. dist is the distance - 1 and -// must not have side effects. dist_code[256] and dist_code[257] are never used. - -#define Max(a,b) (a >= b ? a : b) -/* the arguments must not have side effects */ - -/* =========================================================================== - * Allocate the match buffer, initialize the various tables and save the - * location of the internal file attribute (ascii/binary) and method - * (DEFLATE/STORE). - */ -void ct_init(TState &state, ush *attr) -{ - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - - state.ts.file_type = attr; - //state.ts.file_method = method; - state.ts.cmpr_bytelen = state.ts.cmpr_len_bits = 0L; - state.ts.input_len = 0L; - - if (state.ts.static_dtree[0].dl.len != 0) return; /* ct_init already called */ - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - state.ts.base_length[code] = length; - for (n = 0; n < (1< dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - state.ts.base_dist[code] = dist; - for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - state.ts.base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - state.ts.dist_code[256 + dist++] = (uch)code; - } - } - Assert(state,dist == 256, "ct_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) state.ts.bl_count[bits] = 0; - n = 0; - while (n <= 143) state.ts.static_ltree[n++].dl.len = 8, state.ts.bl_count[8]++; - while (n <= 255) state.ts.static_ltree[n++].dl.len = 9, state.ts.bl_count[9]++; - while (n <= 279) state.ts.static_ltree[n++].dl.len = 7, state.ts.bl_count[7]++; - while (n <= 287) state.ts.static_ltree[n++].dl.len = 8, state.ts.bl_count[8]++; - /* fc.codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes(state,(ct_data *)state.ts.static_ltree, L_CODES+1); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - state.ts.static_dtree[n].dl.len = 5; - state.ts.static_dtree[n].fc.code = (ush)bi_reverse(n, 5); - } - - /* Initialize the first block of the first file: */ - init_block(state); -} - -/* =========================================================================== - * Initialize a new block. - */ -void init_block(TState &state) -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) state.ts.dyn_ltree[n].fc.freq = 0; - for (n = 0; n < D_CODES; n++) state.ts.dyn_dtree[n].fc.freq = 0; - for (n = 0; n < BL_CODES; n++) state.ts.bl_tree[n].fc.freq = 0; - - state.ts.dyn_ltree[END_BLOCK].fc.freq = 1; - state.ts.opt_len = state.ts.static_len = 0L; - state.ts.last_lit = state.ts.last_dist = state.ts.last_flags = 0; - state.ts.flags = 0; state.ts.flag_bit = 1; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(tree, top) \ -{\ - top = state.ts.heap[SMALLEST]; \ - state.ts.heap[SMALLEST] = state.ts.heap[state.ts.heap_len--]; \ - pqdownheap(state,tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m) \ - (tree[n].fc.freq < tree[m].fc.freq || \ - (tree[n].fc.freq == tree[m].fc.freq && state.ts.depth[n] <= state.ts.depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -void pqdownheap(TState &state,ct_data *tree, int k) -{ - int v = state.ts.heap[k]; - int j = k << 1; /* left son of k */ - int htemp; /* required because of bug in SASC compiler */ - - while (j <= state.ts.heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < state.ts.heap_len && smaller(tree, state.ts.heap[j+1], state.ts.heap[j])) j++; - - /* Exit if v is smaller than both sons */ - htemp = state.ts.heap[j]; - if (smaller(tree, v, htemp)) break; - - /* Exchange v with the smallest son */ - state.ts.heap[k] = htemp; - k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - state.ts.heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -void gen_bitlen(TState &state,tree_desc *desc) -{ - ct_data *tree = desc->dyn_tree; - const int *extra = desc->extra_bits; - int base = desc->extra_base; - int max_code = desc->max_code; - int max_length = desc->max_length; - ct_data *stree = desc->static_tree; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) state.ts.bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[state.ts.heap[state.ts.heap_max]].dl.len = 0; /* root of the heap */ - - for (h = state.ts.heap_max+1; h < HEAP_SIZE; h++) { - n = state.ts.heap[h]; - bits = tree[tree[n].dl.dad].dl.len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].dl.len = (ush)bits; - /* We overwrite tree[n].dl.dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - state.ts.bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].fc.freq; - state.ts.opt_len += (ulg)f * (bits + xbits); - if (stree) state.ts.static_len += (ulg)f * (stree[n].dl.len + xbits); - } - if (overflow == 0) return; - - Trace("\nbit length overflow\n"); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (state.ts.bl_count[bits] == 0) bits--; - state.ts.bl_count[bits]--; /* move one leaf down the tree */ - state.ts.bl_count[bits+1] += (ush)2; /* move one overflow item as its brother */ - state.ts.bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = state.ts.bl_count[bits]; - while (n != 0) { - m = state.ts.heap[--h]; - if (m > max_code) continue; - if (tree[m].dl.len != (ush)bits) { - Trace("code %d bits %d->%d\n", m, tree[m].dl.len, bits); - state.ts.opt_len += ((long)bits-(long)tree[m].dl.len)*(long)tree[m].fc.freq; - tree[m].dl.len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -void gen_codes (TState &state, ct_data *tree, int max_code) -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (ush)((code + state.ts.bl_count[bits-1]) << 1); - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert(state,code + state.ts.bl_count[MAX_BITS]-1 == (1<< ((ush) MAX_BITS)) - 1, - "inconsistent bit counts"); - Trace("\ngen_codes: max_code %d ", max_code); - - for (n = 0; n <= max_code; n++) { - int len = tree[n].dl.len; - if (len == 0) continue; - /* Now reverse the bits */ - tree[n].fc.code = (ush)bi_reverse(next_code[len]++, len); - - //Tracec(tree != state.ts.static_ltree, "\nn %3d %c l %2d c %4x (%x) ", n, (isgraph(n) ? n : ' '), len, tree[n].fc.code, next_code[len]-1); - } -} - -/* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ -void build_tree(TState &state,tree_desc *desc) -{ - ct_data *tree = desc->dyn_tree; - ct_data *stree = desc->static_tree; - int elems = desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node = elems; /* next internal node of the tree */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - state.ts.heap_len = 0, state.ts.heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].fc.freq != 0) { - state.ts.heap[++state.ts.heap_len] = max_code = n; - state.ts.depth[n] = 0; - } else { - tree[n].dl.len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (state.ts.heap_len < 2) { - int newcp = state.ts.heap[++state.ts.heap_len] = (max_code < 2 ? ++max_code : 0); - tree[newcp].fc.freq = 1; - state.ts.depth[newcp] = 0; - state.ts.opt_len--; if (stree) state.ts.static_len -= stree[newcp].dl.len; - /* new is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = state.ts.heap_len/2; n >= 1; n--) pqdownheap(state,tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - do { - pqremove(tree, n); /* n = node of least frequency */ - m = state.ts.heap[SMALLEST]; /* m = node of next least frequency */ - - state.ts.heap[--state.ts.heap_max] = n; /* keep the nodes sorted by frequency */ - state.ts.heap[--state.ts.heap_max] = m; - - /* Create a new node father of n and m */ - tree[node].fc.freq = (ush)(tree[n].fc.freq + tree[m].fc.freq); - state.ts.depth[node] = (uch) (Max(state.ts.depth[n], state.ts.depth[m]) + 1); - tree[n].dl.dad = tree[m].dl.dad = (ush)node; - /* and insert the new node in the heap */ - state.ts.heap[SMALLEST] = node++; - pqdownheap(state,tree, SMALLEST); - - } while (state.ts.heap_len >= 2); - - state.ts.heap[--state.ts.heap_max] = state.ts.heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(state,(tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes (state,(ct_data *)tree, max_code); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. Updates opt_len to take into account the repeat - * counts. (The contribution of the bit length codes will be added later - * during the construction of bl_tree.) - */ -void scan_tree (TState &state,ct_data *tree, int max_code) -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].dl.len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].dl.len = (ush)-1; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].dl.len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - state.ts.bl_tree[curlen].fc.freq = (ush)(state.ts.bl_tree[curlen].fc.freq + count); - } else if (curlen != 0) { - if (curlen != prevlen) state.ts.bl_tree[curlen].fc.freq++; - state.ts.bl_tree[REP_3_6].fc.freq++; - } else if (count <= 10) { - state.ts.bl_tree[REPZ_3_10].fc.freq++; - } else { - state.ts.bl_tree[REPZ_11_138].fc.freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -void send_tree (TState &state, ct_data *tree, int max_code) -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].dl.len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].dl.len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].dl.len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(state, curlen, state.ts.bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(state, curlen, state.ts.bl_tree); count--; - } - Assert(state,count >= 3 && count <= 6, " 3_6?"); - send_code(state,REP_3_6, state.ts.bl_tree); send_bits(state,count-3, 2); - - } else if (count <= 10) { - send_code(state,REPZ_3_10, state.ts.bl_tree); send_bits(state,count-3, 3); - - } else { - send_code(state,REPZ_11_138, state.ts.bl_tree); send_bits(state,count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -int build_bl_tree(TState &state) -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(state,(ct_data *)state.ts.dyn_ltree, state.ts.l_desc.max_code); - scan_tree(state,(ct_data *)state.ts.dyn_dtree, state.ts.d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(state,(tree_desc *)(&state.ts.bl_desc)); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (state.ts.bl_tree[bl_order[max_blindex]].dl.len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - state.ts.opt_len += 3*(max_blindex+1) + 5+5+4; - Trace("\ndyn trees: dyn %ld, stat %ld", state.ts.opt_len, state.ts.static_len); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -void send_all_trees(TState &state,int lcodes, int dcodes, int blcodes) -{ - int rank; /* index in bl_order */ - - Assert(state,lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert(state,lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Trace("\nbl counts: "); - send_bits(state,lcodes-257, 5); - /* not +255 as stated in appnote.txt 1.93a or -256 in 2.04c */ - send_bits(state,dcodes-1, 5); - send_bits(state,blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Trace("\nbl code %2d ", bl_order[rank]); - send_bits(state,state.ts.bl_tree[bl_order[rank]].dl.len, 3); - } - Trace("\nbl tree: sent %ld", state.bs.bits_sent); - - send_tree(state,(ct_data *)state.ts.dyn_ltree, lcodes-1); /* send the literal tree */ - Trace("\nlit tree: sent %ld", state.bs.bits_sent); - - send_tree(state,(ct_data *)state.ts.dyn_dtree, dcodes-1); /* send the distance tree */ - Trace("\ndist tree: sent %ld", state.bs.bits_sent); -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. This function - * returns the total compressed length (in bytes) for the file so far. - */ -ulg flush_block(TState &state,char *buf, ulg stored_len, int eof) -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex; /* index of last bit length code of non zero freq */ - - state.ts.flag_buf[state.ts.last_flags] = state.ts.flags; /* Save the flags for the last 8 items */ - - /* Check if the file is ascii or binary */ - if (*state.ts.file_type == (ush)UNKNOWN) set_file_type(state); - - /* Construct the literal and distance trees */ - build_tree(state,(tree_desc *)(&state.ts.l_desc)); - Trace("\nlit data: dyn %ld, stat %ld", state.ts.opt_len, state.ts.static_len); - - build_tree(state,(tree_desc *)(&state.ts.d_desc)); - Trace("\ndist data: dyn %ld, stat %ld", state.ts.opt_len, state.ts.static_len); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(state); - - /* Determine the best encoding. Compute first the block length in bytes */ - opt_lenb = (state.ts.opt_len+3+7)>>3; - static_lenb = (state.ts.static_len+3+7)>>3; - state.ts.input_len += stored_len; /* for debugging only */ - - Trace("\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", - opt_lenb, state.ts.opt_len, static_lenb, state.ts.static_len, stored_len, - state.ts.last_lit, state.ts.last_dist); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - // Originally, zip allowed the file to be transformed from a compressed - // into a stored file in the case where compression failed, there - // was only one block, and it was allowed to change. I've removed this - // possibility since the code's cleaner if no changes are allowed. - //if (stored_len <= opt_lenb && eof && state.ts.cmpr_bytelen == 0L - // && state.ts.cmpr_len_bits == 0L && state.seekable) - //{ // && state.ts.file_method != NULL - // // Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: - // Assert(state,buf!=NULL,"block vanished"); - // copy_block(state,buf, (unsigned)stored_len, 0); // without header - // state.ts.cmpr_bytelen = stored_len; - // Assert(state,false,"unimplemented *state.ts.file_method = STORE;"); - // //*state.ts.file_method = STORE; - //} - //else - if (stored_len+4 <= opt_lenb && buf != (char*)NULL) { - /* 4: two words for the lengths */ - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - send_bits(state,(STORED_BLOCK<<1)+eof, 3); /* send block type */ - state.ts.cmpr_bytelen += ((state.ts.cmpr_len_bits + 3 + 7) >> 3) + stored_len + 4; - state.ts.cmpr_len_bits = 0L; - - copy_block(state,buf, (unsigned)stored_len, 1); /* with header */ - } - else if (static_lenb == opt_lenb) { - send_bits(state,(STATIC_TREES<<1)+eof, 3); - compress_block(state,(ct_data *)state.ts.static_ltree, (ct_data *)state.ts.static_dtree); - state.ts.cmpr_len_bits += 3 + state.ts.static_len; - state.ts.cmpr_bytelen += state.ts.cmpr_len_bits >> 3; - state.ts.cmpr_len_bits &= 7L; - } - else { - send_bits(state,(DYN_TREES<<1)+eof, 3); - send_all_trees(state,state.ts.l_desc.max_code+1, state.ts.d_desc.max_code+1, max_blindex+1); - compress_block(state,(ct_data *)state.ts.dyn_ltree, (ct_data *)state.ts.dyn_dtree); - state.ts.cmpr_len_bits += 3 + state.ts.opt_len; - state.ts.cmpr_bytelen += state.ts.cmpr_len_bits >> 3; - state.ts.cmpr_len_bits &= 7L; - } - Assert(state,((state.ts.cmpr_bytelen << 3) + state.ts.cmpr_len_bits) == state.bs.bits_sent, "bad compressed size"); - init_block(state); - - if (eof) { - // Assert(state,input_len == isize, "bad input size"); - bi_windup(state); - state.ts.cmpr_len_bits += 7; /* align on byte boundary */ - } - Trace("\n"); - - return state.ts.cmpr_bytelen + (state.ts.cmpr_len_bits >> 3); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int ct_tally (TState &state,int dist, int lc) -{ - state.ts.l_buf[state.ts.last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - state.ts.dyn_ltree[lc].fc.freq++; - } else { - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert(state,(ush)dist < (ush)MAX_DIST && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "ct_tally: bad match"); - - state.ts.dyn_ltree[state.ts.length_code[lc]+LITERALS+1].fc.freq++; - state.ts.dyn_dtree[d_code(dist)].fc.freq++; - - state.ts.d_buf[state.ts.last_dist++] = (ush)dist; - state.ts.flags |= state.ts.flag_bit; - } - state.ts.flag_bit <<= 1; - - /* Output the flags if they fill a byte: */ - if ((state.ts.last_lit & 7) == 0) { - state.ts.flag_buf[state.ts.last_flags++] = state.ts.flags; - state.ts.flags = 0, state.ts.flag_bit = 1; - } - /* Try to guess if it is profitable to stop the current block here */ - if (state.level > 2 && (state.ts.last_lit & 0xfff) == 0) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)state.ts.last_lit*8L; - ulg in_length = (ulg)state.ds.strstart-state.ds.block_start; - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)state.ts.dyn_dtree[dcode].fc.freq*(5L+extra_dbits[dcode]); - } - out_length >>= 3; - Trace("\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", - state.ts.last_lit, state.ts.last_dist, in_length, out_length, - 100L - out_length*100L/in_length); - if (state.ts.last_dist < state.ts.last_lit/2 && out_length < in_length/2) return 1; - } - return (state.ts.last_lit == LIT_BUFSIZE-1 || state.ts.last_dist == DIST_BUFSIZE); - /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -void compress_block(TState &state,ct_data *ltree, ct_data *dtree) -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned dx = 0; /* running index in d_buf */ - unsigned fx = 0; /* running index in flag_buf */ - uch flag = 0; /* current flags */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (state.ts.last_lit != 0) do { - if ((lx & 7) == 0) flag = state.ts.flag_buf[fx++]; - lc = state.ts.l_buf[lx++]; - if ((flag & 1) == 0) { - send_code(state,lc, ltree); /* send a literal byte */ - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = state.ts.length_code[lc]; - send_code(state,code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= state.ts.base_length[code]; - send_bits(state,lc, extra); /* send the extra length bits */ - } - dist = state.ts.d_buf[dx++]; - /* Here, dist is the match distance - 1 */ - code = d_code(dist); - Assert(state,code < D_CODES, "bad d_code"); - - send_code(state,code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= state.ts.base_dist[code]; - send_bits(state,dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - flag >>= 1; - } while (lx < state.ts.last_lit); - - send_code(state,END_BLOCK, ltree); -} - -/* =========================================================================== - * Set the file type to ASCII or BINARY, using a crude approximation: - * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. - * IN assertion: the fields freq of dyn_ltree are set and the total of all - * frequencies does not exceed 64K (to fit in an int on 16 bit machines). - */ -void set_file_type(TState &state) -{ - int n = 0; - unsigned ascii_freq = 0; - unsigned bin_freq = 0; - while (n < 7) bin_freq += state.ts.dyn_ltree[n++].fc.freq; - while (n < 128) ascii_freq += state.ts.dyn_ltree[n++].fc.freq; - while (n < LITERALS) bin_freq += state.ts.dyn_ltree[n++].fc.freq; - *state.ts.file_type = (ush)(bin_freq > (ascii_freq >> 2) ? BINARY : ASCII); -} - - -/* =========================================================================== - * Initialize the bit string routines. - */ -void bi_init (TState &state,char *tgt_buf, unsigned tgt_size, int flsh_allowed) -{ - state.bs.out_buf = tgt_buf; - state.bs.out_size = tgt_size; - state.bs.out_offset = 0; - state.bs.flush_flg = flsh_allowed; - - state.bs.bi_buf = 0; - state.bs.bi_valid = 0; - state.bs.bits_sent = 0L; -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -void send_bits(TState &state,int value, int length) -{ - Assert(state,length > 0 && length <= 15, "invalid length"); - state.bs.bits_sent += (ulg)length; - /* If not enough room in bi_buf, use (bi_valid) bits from bi_buf and - * (Buf_size - bi_valid) bits from value to flush the filled bi_buf, - * then fill in the rest of (value), leaving (length - (Buf_size-bi_valid)) - * unused bits in bi_buf. - */ - state.bs.bi_buf |= (value << state.bs.bi_valid); - state.bs.bi_valid += length; - if (state.bs.bi_valid > (int)Buf_size) { - PUTSHORT(state,state.bs.bi_buf); - state.bs.bi_valid -= Buf_size; - state.bs.bi_buf = (unsigned)value >> (length - state.bs.bi_valid); - } -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -unsigned bi_reverse(unsigned code, int len) -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Write out any remaining bits in an incomplete byte. - */ -void bi_windup(TState &state) -{ - if (state.bs.bi_valid > 8) { - PUTSHORT(state,state.bs.bi_buf); - } else if (state.bs.bi_valid > 0) { - PUTBYTE(state,state.bs.bi_buf); - } - if (state.bs.flush_flg) { - state.flush_outbuf(state.param,state.bs.out_buf, &state.bs.out_offset); - } - state.bs.bi_buf = 0; - state.bs.bi_valid = 0; - state.bs.bits_sent = (state.bs.bits_sent+7) & ~7; -} - -/* =========================================================================== - * Copy a stored block to the zip file, storing first the length and its - * one's complement if requested. - */ -void copy_block(TState &state, char *block, unsigned len, int header) -{ - bi_windup(state); /* align on byte boundary */ - - if (header) { - PUTSHORT(state,(ush)len); - PUTSHORT(state,(ush)~len); - state.bs.bits_sent += 2*16; - } - if (state.bs.flush_flg) { - state.flush_outbuf(state.param,state.bs.out_buf, &state.bs.out_offset); - state.bs.out_offset = len; - state.flush_outbuf(state.param,block, &state.bs.out_offset); - } else if (state.bs.out_offset + len > state.bs.out_size) { - Assert(state,false,"output buffer too small for in-memory compression"); - } else { - memcpy(state.bs.out_buf + state.bs.out_offset, block, len); - state.bs.out_offset += len; - } - state.bs.bits_sent += (ulg)len<<3; -} - - - - - - - - -/* =========================================================================== - * Prototypes for functions. - */ - -void fill_window (TState &state); -ulg deflate_fast (TState &state); - -int longest_match (TState &state,IPos cur_match); - - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#define UPDATE_HASH(h,c) (h = (((h)< 0 if the input file is already read or - * mmap'ed in the window[] array, 0 otherwise. In the first case, - * window_size is sufficient to contain the whole input file plus - * MIN_LOOKAHEAD bytes (to avoid referencing memory beyond the end - * of window[] when looking for matches towards the end). - */ -void lm_init (TState &state, int pack_level, ush *flags) -{ - register unsigned j; - - Assert(state,pack_level>=1 && pack_level<=8,"bad pack level"); - - /* Do not slide the window if the whole input is already in memory - * (window_size > 0) - */ - state.ds.sliding = 0; - if (state.ds.window_size == 0L) { - state.ds.sliding = 1; - state.ds.window_size = (ulg)2L*WSIZE; - } - - /* Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ - state.ds.head[HASH_SIZE-1] = NIL; - memset((char*)state.ds.head, NIL, (unsigned)(HASH_SIZE-1)*sizeof(*state.ds.head)); - - /* Set the default configuration parameters: - */ - state.ds.max_lazy_match = configuration_table[pack_level].max_lazy; - state.ds.good_match = configuration_table[pack_level].good_length; - state.ds.nice_match = configuration_table[pack_level].nice_length; - state.ds.max_chain_length = configuration_table[pack_level].max_chain; - if (pack_level <= 2) { - *flags |= FAST; - } else if (pack_level >= 8) { - *flags |= SLOW; - } - /* ??? reduce max_chain_length for binary files */ - - state.ds.strstart = 0; - state.ds.block_start = 0L; - - j = WSIZE; - j <<= 1; // Can read 64K in one step - state.ds.lookahead = state.readfunc(state, (char*)state.ds.window, j); - - if (state.ds.lookahead == 0 || state.ds.lookahead == (unsigned)EOF) { - state.ds.eofile = 1, state.ds.lookahead = 0; - return; - } - state.ds.eofile = 0; - /* Make sure that we always have enough lookahead. This is important - * if input comes from a device such as a tty. - */ - if (state.ds.lookahead < MIN_LOOKAHEAD) fill_window(state); - - state.ds.ins_h = 0; - for (j=0; j= 1 - */ -// For 80x86 and 680x0 and ARM, an optimized version is in match.asm or -// match.S. The code is functionally equivalent, so you can use the C version -// if desired. Which I do so desire! -int longest_match(TState &state,IPos cur_match) -{ - unsigned chain_length = state.ds.max_chain_length; /* max hash chain length */ - register uch far *scan = state.ds.window + state.ds.strstart; /* current string */ - register uch far *match; /* matched string */ - register int len; /* length of current match */ - int best_len = state.ds.prev_length; /* best match length so far */ - IPos limit = state.ds.strstart > (IPos)MAX_DIST ? state.ds.strstart - (IPos)MAX_DIST : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - - // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - // It is easy to get rid of this optimization if necessary. - Assert(state,HASH_BITS>=8 && MAX_MATCH==258,"Code too clever"); - - - - register uch far *strend = state.ds.window + state.ds.strstart + MAX_MATCH; - register uch scan_end1 = scan[best_len-1]; - register uch scan_end = scan[best_len]; - - /* Do not waste too much time if we already have a good match: */ - if (state.ds.prev_length >= state.ds.good_match) { - chain_length >>= 2; - } - - Assert(state,state.ds.strstart <= state.ds.window_size-MIN_LOOKAHEAD, "insufficient lookahead"); - - do { - Assert(state,cur_match < state.ds.strstart, "no future"); - match = state.ds.window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2: - */ - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(state,scan <= state.ds.window+(unsigned)(state.ds.window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - - - if (len > best_len) { - state.ds.match_start = cur_match; - best_len = len; - if (len >= state.ds.nice_match) break; - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; - } - } while ((cur_match = state.ds.prev[cur_match & WMASK]) > limit - && --chain_length != 0); - - return best_len; -} - - - -#define check_match(state,start, match, length) -// or alternatively... -//void check_match(TState &state,IPos start, IPos match, int length) -//{ // check that the match is indeed a match -// if (memcmp((char*)state.ds.window + match, -// (char*)state.ds.window + start, length) != EQUAL) { -// fprintf(stderr, -// " start %d, match %d, length %d\n", -// start, match, length); -// error("invalid match"); -// } -// if (state.verbose > 1) { -// fprintf(stderr,"\\[%d,%d]", start-match, length); -// do { fprintf(stdout,"%c",state.ds.window[start++]); } while (--length != 0); -// } -//} - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead, and sets eofile if end of input file. - * - * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or eofile is set; file reads are - * performed for at least two bytes (required for the translate_eol option). - */ -void fill_window(TState &state) -{ - register unsigned n, m; - unsigned more; /* Amount of free space at the end of the window. */ - - do { - more = (unsigned)(state.ds.window_size - (ulg)state.ds.lookahead - (ulg)state.ds.strstart); - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (more == (unsigned)EOF) { - /* Very unlikely, but possible on 16 bit machine if strstart == 0 - * and lookahead == 1 (input done one byte at time) - */ - more--; - - /* For MMAP or BIG_MEM, the whole input file is already in memory so - * we must not perform sliding. We must however call (*read_buf)() in - * order to compute the crc, update lookahead and possibly set eofile. - */ - } else if (state.ds.strstart >= WSIZE+MAX_DIST && state.ds.sliding) { - - /* By the IN assertion, the window is not empty so we can't confuse - * more == 0 with more == 64K on a 16 bit machine. - */ - memcpy((char*)state.ds.window, (char*)state.ds.window+WSIZE, (unsigned)WSIZE); - state.ds.match_start -= WSIZE; - state.ds.strstart -= WSIZE; /* we now have strstart >= MAX_DIST: */ - - state.ds.block_start -= (long) WSIZE; - - for (n = 0; n < HASH_SIZE; n++) { - m = state.ds.head[n]; - state.ds.head[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL); - } - for (n = 0; n < WSIZE; n++) { - m = state.ds.prev[n]; - state.ds.prev[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } - more += WSIZE; - } - if (state.ds.eofile) return; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the MMAP or BIG_MEM case (not yet supported in gzip), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(state,more >= 2, "more < 2"); - - n = state.readfunc(state, (char*)state.ds.window+state.ds.strstart+state.ds.lookahead, more); - - if (n == 0 || n == (unsigned)EOF) { - state.ds.eofile = 1; - } else { - state.ds.lookahead += n; - } - } while (state.ds.lookahead < MIN_LOOKAHEAD && !state.ds.eofile); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK(state,eof) \ - flush_block(state,state.ds.block_start >= 0L ? (char*)&state.ds.window[(unsigned)state.ds.block_start] : \ - (char*)NULL, (long)state.ds.strstart - state.ds.block_start, (eof)) - -/* =========================================================================== - * Processes a new input file and return its compressed length. This - * function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -ulg deflate_fast(TState &state) -{ - IPos hash_head = NIL; /* head of the hash chain */ - int flush; /* set if current block must be flushed */ - unsigned match_length = 0; /* length of best match */ - - state.ds.prev_length = MIN_MATCH-1; - while (state.ds.lookahead != 0) { - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (state.ds.lookahead >= MIN_MATCH) - INSERT_STRING(state.ds.strstart, hash_head); - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && state.ds.strstart - hash_head <= MAX_DIST) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - /* Do not look for matches beyond the end of the input. - * This is necessary to make deflate deterministic. - */ - if ((unsigned)state.ds.nice_match > state.ds.lookahead) state.ds.nice_match = (int)state.ds.lookahead; - match_length = longest_match (state,hash_head); - /* longest_match() sets match_start */ - if (match_length > state.ds.lookahead) match_length = state.ds.lookahead; - } - if (match_length >= MIN_MATCH) { - check_match(state,state.ds.strstart, state.ds.match_start, match_length); - - flush = ct_tally(state,state.ds.strstart-state.ds.match_start, match_length - MIN_MATCH); - - state.ds.lookahead -= match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ - if (match_length <= state.ds.max_insert_length - && state.ds.lookahead >= MIN_MATCH) { - match_length--; /* string at strstart already in hash table */ - do { - state.ds.strstart++; - INSERT_STRING(state.ds.strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--match_length != 0); - state.ds.strstart++; - } else { - state.ds.strstart += match_length; - match_length = 0; - state.ds.ins_h = state.ds.window[state.ds.strstart]; - UPDATE_HASH(state.ds.ins_h, state.ds.window[state.ds.strstart+1]); - Assert(state,MIN_MATCH==3,"Call UPDATE_HASH() MIN_MATCH-3 more times"); - } - } else { - /* No match, output a literal byte */ - flush = ct_tally (state,0, state.ds.window[state.ds.strstart]); - state.ds.lookahead--; - state.ds.strstart++; - } - if (flush) FLUSH_BLOCK(state,0), state.ds.block_start = state.ds.strstart; - - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (state.ds.lookahead < MIN_LOOKAHEAD) fill_window(state); - } - return FLUSH_BLOCK(state,1); /* eof */ -} - -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -ulg deflate(TState &state) -{ - IPos hash_head = NIL; /* head of hash chain */ - IPos prev_match; /* previous match */ - int flush; /* set if current block must be flushed */ - int match_available = 0; /* set if previous match exists */ - register unsigned match_length = MIN_MATCH-1; /* length of best match */ - - if (state.level <= 3) return deflate_fast(state); /* optimized for speed */ - - /* Process the input block. */ - while (state.ds.lookahead != 0) { - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (state.ds.lookahead >= MIN_MATCH) - INSERT_STRING(state.ds.strstart, hash_head); - - /* Find the longest match, discarding those <= prev_length. - */ - state.ds.prev_length = match_length, prev_match = state.ds.match_start; - match_length = MIN_MATCH-1; - - if (hash_head != NIL && state.ds.prev_length < state.ds.max_lazy_match && - state.ds.strstart - hash_head <= MAX_DIST) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - /* Do not look for matches beyond the end of the input. - * This is necessary to make deflate deterministic. - */ - if ((unsigned)state.ds.nice_match > state.ds.lookahead) state.ds.nice_match = (int)state.ds.lookahead; - match_length = longest_match (state,hash_head); - /* longest_match() sets match_start */ - if (match_length > state.ds.lookahead) match_length = state.ds.lookahead; - - /* Ignore a length 3 match if it is too distant: */ - if (match_length == MIN_MATCH && state.ds.strstart-state.ds.match_start > TOO_FAR){ - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (state.ds.prev_length >= MIN_MATCH && match_length <= state.ds.prev_length) { - unsigned max_insert = state.ds.strstart + state.ds.lookahead - MIN_MATCH; - check_match(state,state.ds.strstart-1, prev_match, state.ds.prev_length); - flush = ct_tally(state,state.ds.strstart-1-prev_match, state.ds.prev_length - MIN_MATCH); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. - */ - state.ds.lookahead -= state.ds.prev_length-1; - state.ds.prev_length -= 2; - do { - if (++state.ds.strstart <= max_insert) { - INSERT_STRING(state.ds.strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } - } while (--state.ds.prev_length != 0); - state.ds.strstart++; - match_available = 0; - match_length = MIN_MATCH-1; - - if (flush) FLUSH_BLOCK(state,0), state.ds.block_start = state.ds.strstart; - - } else if (match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - if (ct_tally (state,0, state.ds.window[state.ds.strstart-1])) { - FLUSH_BLOCK(state,0), state.ds.block_start = state.ds.strstart; - } - state.ds.strstart++; - state.ds.lookahead--; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - match_available = 1; - state.ds.strstart++; - state.ds.lookahead--; - } -// Assert(state,strstart <= isize && lookahead <= isize, "a bit too far"); - - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (state.ds.lookahead < MIN_LOOKAHEAD) fill_window(state); - } - if (match_available) ct_tally (state,0, state.ds.window[state.ds.strstart-1]); - - return FLUSH_BLOCK(state,1); /* eof */ -} - - - - - - - - - - - - -int putlocal(struct zlist far *z, WRITEFUNC wfunc,void *param) -{ // Write a local header described by *z to file *f. Return a ZE_ error code. - PUTLG(LOCSIG, f); - PUTSH(z->ver, f); - PUTSH(z->lflg, f); - PUTSH(z->how, f); - PUTLG(z->tim, f); - PUTLG(z->crc, f); - PUTLG(z->siz, f); - PUTLG(z->len, f); - PUTSH(z->nam, f); - PUTSH(z->ext, f); - size_t res = (size_t)wfunc(param, z->iname, (unsigned int)z->nam); - if (res!=z->nam) return ZE_TEMP; - if (z->ext) - { res = (size_t)wfunc(param, z->extra, (unsigned int)z->ext); - if (res!=z->ext) return ZE_TEMP; - } - return ZE_OK; -} - -int putextended(struct zlist far *z, WRITEFUNC wfunc, void *param) -{ // Write an extended local header described by *z to file *f. Returns a ZE_ code - PUTLG(EXTLOCSIG, f); - PUTLG(z->crc, f); - PUTLG(z->siz, f); - PUTLG(z->len, f); - return ZE_OK; -} - -int putcentral(struct zlist far *z, WRITEFUNC wfunc, void *param) -{ // Write a central header entry of *z to file *f. Returns a ZE_ code. - PUTLG(CENSIG, f); - PUTSH(z->vem, f); - PUTSH(z->ver, f); - PUTSH(z->flg, f); - PUTSH(z->how, f); - PUTLG(z->tim, f); - PUTLG(z->crc, f); - PUTLG(z->siz, f); - PUTLG(z->len, f); - PUTSH(z->nam, f); - PUTSH(z->cext, f); - PUTSH(z->com, f); - PUTSH(z->dsk, f); - PUTSH(z->att, f); - PUTLG(z->atx, f); - PUTLG(z->off, f); - if ((size_t)wfunc(param, z->iname, (unsigned int)z->nam) != z->nam || - (z->cext && (size_t)wfunc(param, z->cextra, (unsigned int)z->cext) != z->cext) || - (z->com && (size_t)wfunc(param, z->comment, (unsigned int)z->com) != z->com)) - return ZE_TEMP; - return ZE_OK; -} - - -int putend(int n, ulg s, ulg c, extent m, char *z, WRITEFUNC wfunc, void *param) -{ // write the end of the central-directory-data to file *f. - PUTLG(ENDSIG, f); - PUTSH(0, f); - PUTSH(0, f); - PUTSH(n, f); - PUTSH(n, f); - PUTLG(s, f); - PUTLG(c, f); - PUTSH(m, f); - // Write the comment, if any - if (m && wfunc(param, z, (unsigned int)m) != m) return ZE_TEMP; - return ZE_OK; -} - - - - - - -const ulg crc_table[256] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; - -#define CRC32(c, b) (crc_table[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8)) -#define DO1(buf) crc = CRC32(crc, *buf++) -#define DO2(buf) DO1(buf); DO1(buf) -#define DO4(buf) DO2(buf); DO2(buf) -#define DO8(buf) DO4(buf); DO4(buf) - -ulg crc32(ulg crc, const uch *buf, extent len) -{ if (buf==NULL) return 0L; - crc = crc ^ 0xffffffffL; - while (len >= 8) {DO8(buf); len -= 8;} - if (len) do {DO1(buf);} while (--len); - return crc ^ 0xffffffffL; // (instead of ~c for 64-bit machines) -} - - -void update_keys(unsigned long *keys, char c) -{ keys[0] = CRC32(keys[0],c); - keys[1] += keys[0] & 0xFF; - keys[1] = keys[1]*134775813L +1; - keys[2] = CRC32(keys[2], keys[1] >> 24); -} -char decrypt_byte(unsigned long *keys) -{ unsigned temp = ((unsigned)keys[2] & 0xffff) | 2; - return (char)(((temp * (temp ^ 1)) >> 8) & 0xff); -} -char zencode(unsigned long *keys, char c) -{ int t=decrypt_byte(keys); - update_keys(keys,c); - return (char)(t^c); -} - - - - - - - -bool HasZipSuffix(const TCHAR *fn) -{ const TCHAR *ext = fn+_tcslen(fn); - while (ext>fn && *ext!='.') ext--; - if (ext==fn && *ext!='.') return false; - if (_tcsicmp(ext,_T(".Z"))==0) return true; - if (_tcsicmp(ext,_T(".zip"))==0) return true; - if (_tcsicmp(ext,_T(".zoo"))==0) return true; - if (_tcsicmp(ext,_T(".arc"))==0) return true; - if (_tcsicmp(ext,_T(".lzh"))==0) return true; - if (_tcsicmp(ext,_T(".arj"))==0) return true; - if (_tcsicmp(ext,_T(".gz"))==0) return true; - if (_tcsicmp(ext,_T(".tgz"))==0) return true; - return false; -} - - -lutime_t filetime2timet(const FILETIME ft) -{ __int64 i = *(__int64*)&ft; - return (lutime_t)((i-116444736000000000)/10000000); -} - -void filetime2dosdatetime(const FILETIME ft, WORD *dosdate,WORD *dostime) -{ // date: bits 0-4 are day of month 1-31. Bits 5-8 are month 1..12. Bits 9-15 are year-1980 - // time: bits 0-4 are seconds/2, bits 5-10 are minute 0..59. Bits 11-15 are hour 0..23 - SYSTEMTIME st; FileTimeToSystemTime(&ft,&st); - *dosdate = (WORD)(((st.wYear-1980)&0x7f) << 9); - *dosdate |= (WORD)((st.wMonth&0xf) << 5); - *dosdate |= (WORD)((st.wDay&0x1f)); - *dostime = (WORD)((st.wHour&0x1f) << 11); - *dostime |= (WORD)((st.wMinute&0x3f) << 5); - *dostime |= (WORD)((st.wSecond*2)&0x1f); -} - - -ZRESULT GetFileInfo(HANDLE hf, ulg *attr, long *size, iztimes *times, ulg *timestamp) -{ // The handle must be a handle to a file - // The date and time is returned in a long with the date most significant to allow - // unsigned integer comparison of absolute times. The attributes have two - // high bytes unix attr, and two low bytes a mapping of that to DOS attr. - //struct stat s; int res=stat(fn,&s); if (res!=0) return false; - // translate windows file attributes into zip ones. - BY_HANDLE_FILE_INFORMATION bhi; BOOL res=GetFileInformationByHandle(hf,&bhi); - if (!res) return ZR_NOFILE; - DWORD fa=bhi.dwFileAttributes; ulg a=0; - // Zip uses the lower word for its interpretation of windows stuff - if (fa&FILE_ATTRIBUTE_READONLY) a|=0x01; - if (fa&FILE_ATTRIBUTE_HIDDEN) a|=0x02; - if (fa&FILE_ATTRIBUTE_SYSTEM) a|=0x04; - if (fa&FILE_ATTRIBUTE_DIRECTORY)a|=0x10; - if (fa&FILE_ATTRIBUTE_ARCHIVE) a|=0x20; - // It uses the upper word for standard unix attr, which we manually construct - if (fa&FILE_ATTRIBUTE_DIRECTORY)a|=0x40000000; // directory - else a|=0x80000000; // normal file - a|=0x01000000; // readable - if (fa&FILE_ATTRIBUTE_READONLY) {} else a|=0x00800000; // writeable - // now just a small heuristic to check if it's an executable: - DWORD red, hsize=GetFileSize(hf,NULL); if (hsize>40) - { SetFilePointer(hf,0,NULL,FILE_BEGIN); unsigned short magic; ReadFile(hf,&magic,sizeof(magic),&red,NULL); - SetFilePointer(hf,36,NULL,FILE_BEGIN); unsigned long hpos; ReadFile(hf,&hpos,sizeof(hpos),&red,NULL); - if (magic==0x54AD && hsize>hpos+4+20+28) - { SetFilePointer(hf,hpos,NULL,FILE_BEGIN); unsigned long signature; ReadFile(hf,&signature,sizeof(signature),&red,NULL); - if (signature==IMAGE_DOS_SIGNATURE || signature==IMAGE_OS2_SIGNATURE - || signature==IMAGE_OS2_SIGNATURE_LE || signature==IMAGE_NT_SIGNATURE) - { a |= 0x00400000; // executable - } - } - } - // - if (attr!=NULL) *attr = a; - if (size!=NULL) *size = hsize; - if (times!=NULL) - { // lutime_t is 32bit number of seconds elapsed since 0:0:0GMT, Jan1, 1970. - // but FILETIME is 64bit number of 100-nanosecs since Jan1, 1601 - times->atime = filetime2timet(bhi.ftLastAccessTime); - times->mtime = filetime2timet(bhi.ftLastWriteTime); - times->ctime = filetime2timet(bhi.ftCreationTime); - } - if (timestamp!=NULL) - { WORD dosdate,dostime; - filetime2dosdatetime(bhi.ftLastWriteTime,&dosdate,&dostime); - *timestamp = (WORD)dostime | (((DWORD)dosdate)<<16); - } - return ZR_OK; -} - - - - - - - - -class TZip -{ public: - TZip(const char *pwd) : hfout(0),mustclosehfout(false),hmapout(0),zfis(0),obuf(0),hfin(0),writ(0),oerr(false),hasputcen(false),ooffset(0),encwriting(false),encbuf(0),password(0), state(0) {if (pwd!=0 && *pwd!=0) {password=new char[strlen(pwd)+1]; strcpy(password,pwd);}} - ~TZip() {if (state!=0) delete state; state=0; if (encbuf!=0) delete[] encbuf; encbuf=0; if (password!=0) delete[] password; password=0;} - - // These variables say about the file we're writing into - // We can write to pipe, file-by-handle, file-by-name, memory-to-memmapfile - char *password; // keep a copy of the password - HANDLE hfout; // if valid, we'll write here (for files or pipes) - bool mustclosehfout; // if true, we are responsible for closing hfout - HANDLE hmapout; // otherwise, we'll write here (for memmap) - unsigned ooffset; // for hfout, this is where the pointer was initially - ZRESULT oerr; // did a write operation give rise to an error? - unsigned writ; // how far have we written. This is maintained by Add, not write(), to avoid confusion over seeks - bool ocanseek; // can we seek? - char *obuf; // this is where we've locked mmap to view. - unsigned int opos; // current pos in the mmap - unsigned int mapsize; // the size of the map we created - bool hasputcen; // have we yet placed the central directory? - bool encwriting; // if true, then we'll encrypt stuff using 'keys' before we write it to disk - unsigned long keys[3]; // keys are initialised inside Add() - char *encbuf; // if encrypting, then this is a temporary workspace for encrypting the data - unsigned int encbufsize; // (to be used and resized inside write(), and deleted in the destructor) - // - TZipFileInfo *zfis; // each file gets added onto this list, for writing the table at the end - TState *state; // we use just one state object per zip, because it's big (500k) - - ZRESULT Create(void *z,unsigned int len,DWORD flags); - static unsigned sflush(void *param,const char *buf, unsigned *size); - static unsigned swrite(void *param,const char *buf, unsigned size); - unsigned int write(const char *buf,unsigned int size); - bool oseek(unsigned int pos); - ZRESULT GetMemory(void **pbuf, unsigned long *plen); - ZRESULT Close(); - - // some variables to do with the file currently being read: - // I haven't done it object-orientedly here, just put them all - // together, since OO didn't seem to make the design any clearer. - ulg attr; iztimes times; ulg timestamp; // all open_* methods set these - bool iseekable; long isize,ired; // size is not set until close() on pips - ulg crc; // crc is not set until close(). iwrit is cumulative - HANDLE hfin; bool selfclosehf; // for input files and pipes - const char *bufin; unsigned int lenin,posin; // for memory - // and a variable for what we've done with the input: (i.e. compressed it!) - ulg csize; // compressed size, set by the compression routines - // and this is used by some of the compression routines - char buf[16384]; - - - ZRESULT open_file(const TCHAR *fn); - ZRESULT open_handle(HANDLE hf,unsigned int len); - ZRESULT open_mem(void *src,unsigned int len); - ZRESULT open_dir(); - static unsigned sread(TState &s,char *buf,unsigned size); - unsigned read(char *buf, unsigned size); - ZRESULT iclose(); - - ZRESULT ideflate(TZipFileInfo *zfi); - ZRESULT istore(); - - ZRESULT Add(const TCHAR *odstzn, void *src,unsigned int len, DWORD flags); - ZRESULT AddCentral(); - -}; - - - -ZRESULT TZip::Create(void *z,unsigned int len,DWORD flags) -{ if (hfout!=0 || hmapout!=0 || obuf!=0 || writ!=0 || oerr!=ZR_OK || hasputcen) return ZR_NOTINITED; - // - if (flags==ZIP_HANDLE) - { HANDLE hf = (HANDLE)z; - hfout=hf; mustclosehfout=false; -#ifdef DuplicateHandle - BOOL res = DuplicateHandle(GetCurrentProcess(),hf,GetCurrentProcess(),&hfout,0,FALSE,DUPLICATE_SAME_ACCESS); - if (res) mustclosehandle=true; -#endif - // now we have hfout. Either we duplicated the handle and we close it ourselves - // (while the caller closes h themselves), or we couldn't duplicate it. - DWORD res = SetFilePointer(hfout,0,0,FILE_CURRENT); - ocanseek = (res!=0xFFFFFFFF); - if (ocanseek) ooffset=res; else ooffset=0; - return ZR_OK; - } - else if (flags==ZIP_FILENAME) - { const TCHAR *fn = (const TCHAR*)z; - hfout = CreateFile(fn,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); - if (hfout==INVALID_HANDLE_VALUE) {hfout=0; return ZR_NOFILE;} - ocanseek=true; - ooffset=0; - mustclosehfout=true; - return ZR_OK; - } - else if (flags==ZIP_MEMORY) - { unsigned int size = len; - if (size==0) return ZR_MEMSIZE; - if (z!=0) obuf=(char*)z; - else - { hmapout = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,size,NULL); - if (hmapout==NULL) return ZR_NOALLOC; - obuf = (char*)MapViewOfFile(hmapout,FILE_MAP_ALL_ACCESS,0,0,size); - if (obuf==0) {CloseHandle(hmapout); hmapout=0; return ZR_NOALLOC;} - } - ocanseek=true; - opos=0; mapsize=size; - return ZR_OK; - } - else return ZR_ARGS; -} - -unsigned TZip::sflush(void *param,const char *buf, unsigned *size) -{ // static - if (*size==0) return 0; - TZip *zip = (TZip*)param; - unsigned int writ = zip->write(buf,*size); - if (writ!=0) *size=0; - return writ; -} -unsigned TZip::swrite(void *param,const char *buf, unsigned size) -{ // static - if (size==0) return 0; - TZip *zip=(TZip*)param; return zip->write(buf,size); -} -unsigned int TZip::write(const char *buf,unsigned int size) -{ const char *srcbuf=buf; - if (encwriting) - { if (encbuf!=0 && encbufsize=mapsize) {oerr=ZR_MEMSIZE; return 0;} - memcpy(obuf+opos, srcbuf, size); - opos+=size; - return size; - } - else if (hfout!=0) - { DWORD writ; WriteFile(hfout,srcbuf,size,&writ,NULL); - return writ; - } - oerr=ZR_NOTINITED; return 0; -} - -bool TZip::oseek(unsigned int pos) -{ if (!ocanseek) {oerr=ZR_SEEK; return false;} - if (obuf!=0) - { if (pos>=mapsize) {oerr=ZR_MEMSIZE; return false;} - opos=pos; - return true; - } - else if (hfout!=0) - { SetFilePointer(hfout,pos+ooffset,NULL,FILE_BEGIN); - return true; - } - oerr=ZR_NOTINITED; return 0; -} - -ZRESULT TZip::GetMemory(void **pbuf, unsigned long *plen) -{ // When the user calls GetMemory, they're presumably at the end - // of all their adding. In any case, we have to add the central - // directory now, otherwise the memory we tell them won't be complete. - if (!hasputcen) AddCentral(); hasputcen=true; - if (pbuf!=NULL) *pbuf=(void*)obuf; - if (plen!=NULL) *plen=writ; - if (obuf==NULL) return ZR_NOTMMAP; - return ZR_OK; -} - -ZRESULT TZip::Close() -{ // if the directory hadn't already been added through a call to GetMemory, - // then we do it now - ZRESULT res=ZR_OK; if (!hasputcen) res=AddCentral(); hasputcen=true; - if (obuf!=0 && hmapout!=0) UnmapViewOfFile(obuf); obuf=0; - if (hmapout!=0) CloseHandle(hmapout); hmapout=0; - if (hfout!=0 && mustclosehfout) CloseHandle(hfout); hfout=0; mustclosehfout=false; - return res; -} - - - - -ZRESULT TZip::open_file(const TCHAR *fn) -{ hfin=0; bufin=0; selfclosehf=false; crc=CRCVAL_INITIAL; isize=0; csize=0; ired=0; - if (fn==0) return ZR_ARGS; - HANDLE hf = CreateFile(fn,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL); - if (hf==INVALID_HANDLE_VALUE) return ZR_NOFILE; - ZRESULT res = open_handle(hf,0); - if (res!=ZR_OK) {CloseHandle(hf); return res;} - selfclosehf=true; - return ZR_OK; -} -ZRESULT TZip::open_handle(HANDLE hf,unsigned int len) -{ hfin=0; bufin=0; selfclosehf=false; crc=CRCVAL_INITIAL; isize=0; csize=0; ired=0; - if (hf==0 || hf==INVALID_HANDLE_VALUE) return ZR_ARGS; - DWORD res = SetFilePointer(hfout,0,0,FILE_CURRENT); - if (res!=0xFFFFFFFF) - { ZRESULT res = GetFileInfo(hf,&attr,&isize,×,×tamp); - if (res!=ZR_OK) return res; - SetFilePointer(hf,0,NULL,FILE_BEGIN); // because GetFileInfo will have screwed it up - iseekable=true; hfin=hf; - return ZR_OK; - } - else - { attr= 0x80000000; // just a normal file - isize = -1; // can't know size until at the end - if (len!=0) isize=len; // unless we were told explicitly! - iseekable=false; - SYSTEMTIME st; GetLocalTime(&st); - FILETIME ft; SystemTimeToFileTime(&st,&ft); - WORD dosdate,dostime; filetime2dosdatetime(ft,&dosdate,&dostime); - times.atime = filetime2timet(ft); - times.mtime = times.atime; - times.ctime = times.atime; - timestamp = (WORD)dostime | (((DWORD)dosdate)<<16); - hfin=hf; - return ZR_OK; - } -} -ZRESULT TZip::open_mem(void *src,unsigned int len) -{ hfin=0; bufin=(const char*)src; selfclosehf=false; crc=CRCVAL_INITIAL; ired=0; csize=0; ired=0; - lenin=len; posin=0; - if (src==0 || len==0) return ZR_ARGS; - attr= 0x80000000; // just a normal file - isize = len; - iseekable=true; - SYSTEMTIME st; GetLocalTime(&st); - FILETIME ft; SystemTimeToFileTime(&st,&ft); - WORD dosdate,dostime; filetime2dosdatetime(ft,&dosdate,&dostime); - times.atime = filetime2timet(ft); - times.mtime = times.atime; - times.ctime = times.atime; - timestamp = (WORD)dostime | (((DWORD)dosdate)<<16); - return ZR_OK; -} -ZRESULT TZip::open_dir() -{ hfin=0; bufin=0; selfclosehf=false; crc=CRCVAL_INITIAL; isize=0; csize=0; ired=0; - attr= 0x41C00010; // a readable writable directory, and again directory - isize = 0; - iseekable=false; - SYSTEMTIME st; GetLocalTime(&st); - FILETIME ft; SystemTimeToFileTime(&st,&ft); - WORD dosdate,dostime; filetime2dosdatetime(ft,&dosdate,&dostime); - times.atime = filetime2timet(ft); - times.mtime = times.atime; - times.ctime = times.atime; - timestamp = (WORD)dostime | (((DWORD)dosdate)<<16); - return ZR_OK; -} - -unsigned TZip::sread(TState &s,char *buf,unsigned size) -{ // static - TZip *zip = (TZip*)s.param; - return zip->read(buf,size); -} - -unsigned TZip::read(char *buf, unsigned size) -{ if (bufin!=0) - { if (posin>=lenin) return 0; // end of input - ulg red = lenin-posin; - if (red>size) red=size; - memcpy(buf, bufin+posin, red); - posin += red; - ired += red; - crc = crc32(crc, (uch*)buf, red); - return red; - } - else if (hfin!=0) - { DWORD red; - BOOL ok = ReadFile(hfin,buf,size,&red,NULL); - if (!ok) return 0; - ired += red; - crc = crc32(crc, (uch*)buf, red); - return red; - } - else {oerr=ZR_NOTINITED; return 0;} -} - -ZRESULT TZip::iclose() -{ if (selfclosehf && hfin!=0) CloseHandle(hfin); hfin=0; - bool mismatch = (isize!=-1 && isize!=ired); - isize=ired; // and crc has been being updated anyway - if (mismatch) return ZR_MISSIZE; - else return ZR_OK; -} - - - -ZRESULT TZip::ideflate(TZipFileInfo *zfi) -{ if (state==0) state=new TState(); - // It's a very big object! 500k! We allocate it on the heap, because PocketPC's - // stack breaks if we try to put it all on the stack. It will be deleted lazily - state->err=0; - state->readfunc=sread; state->flush_outbuf=sflush; - state->param=this; state->level=8; state->seekable=iseekable; state->err=NULL; - // the following line will make ct_init realise it has to perform the init - state->ts.static_dtree[0].dl.len = 0; - // Thanks to Alvin77 for this crucial fix: - state->ds.window_size=0; - // I think that covers everything that needs to be initted. - // - bi_init(*state,buf, sizeof(buf), TRUE); // it used to be just 1024-size, not 16384 as here - ct_init(*state,&zfi->att); - lm_init(*state,state->level, &zfi->flg); - ulg sz = deflate(*state); - csize=sz; - ZRESULT r=ZR_OK; if (state->err!=NULL) r=ZR_FLATE; - return r; -} - -ZRESULT TZip::istore() -{ ulg size=0; - for (;;) - { unsigned int cin=read(buf,16384); if (cin<=0 || cin==(unsigned int)EOF) break; - unsigned int cout = write(buf,cin); if (cout!=cin) return ZR_MISSIZE; - size += cin; - } - csize=size; - return ZR_OK; -} - - - - - -bool has_seeded=false; -ZRESULT TZip::Add(const TCHAR *odstzn, void *src,unsigned int len, DWORD flags) -{ if (oerr) return ZR_FAILED; - if (hasputcen) return ZR_ENDED; - - // if we use password encryption, then every isize and csize is 12 bytes bigger - int passex=0; if (password!=0 && flags!=ZIP_FOLDER) passex=12; - - // zip has its own notion of what its names should look like: i.e. dir/file.stuff - TCHAR dstzn[MAX_PATH]; _tcscpy(dstzn,odstzn); - if (*dstzn==0) return ZR_ARGS; - TCHAR *d=dstzn; while (*d!=0) {if (*d=='\\') *d='/'; d++;} - bool isdir = (flags==ZIP_FOLDER); - bool needs_trailing_slash = (isdir && dstzn[_tcslen(dstzn)-1]!='/'); - int method=DEFLATE; if (isdir || HasZipSuffix(dstzn)) method=STORE; - - // now open whatever was our input source: - ZRESULT openres; - if (flags==ZIP_FILENAME) openres=open_file((const TCHAR*)src); - else if (flags==ZIP_HANDLE) openres=open_handle((HANDLE)src,len); - else if (flags==ZIP_MEMORY) openres=open_mem(src,len); - else if (flags==ZIP_FOLDER) openres=open_dir(); - else return ZR_ARGS; - if (openres!=ZR_OK) return openres; - - // A zip "entry" consists of a local header (which includes the file name), - // then the compressed data, and possibly an extended local header. - - // Initialize the local header - TZipFileInfo zfi; zfi.nxt=NULL; - strcpy(zfi.name,""); -#ifdef UNICODE - WideCharToMultiByte(CP_UTF8,0,dstzn,-1,zfi.iname,MAX_PATH,0,0); -#else - strcpy(zfi.iname,dstzn); -#endif - zfi.nam=strlen(zfi.iname); - if (needs_trailing_slash) {strcat(zfi.iname,"/"); zfi.nam++;} - strcpy(zfi.zname,""); - zfi.extra=NULL; zfi.ext=0; // extra header to go after this compressed data, and its length - zfi.cextra=NULL; zfi.cext=0; // extra header to go in the central end-of-zip directory, and its length - zfi.comment=NULL; zfi.com=0; // comment, and its length - zfi.mark = 1; - zfi.dosflag = 0; - zfi.att = (ush)BINARY; - zfi.vem = (ush)0xB17; // 0xB00 is win32 os-code. 0x17 is 23 in decimal: zip 2.3 - zfi.ver = (ush)20; // Needs PKUNZIP 2.0 to unzip it - zfi.tim = timestamp; - // Even though we write the header now, it will have to be rewritten, since we don't know compressed size or crc. - zfi.crc = 0; // to be updated later - zfi.flg = 8; // 8 means 'there is an extra header'. Assume for the moment that we need it. - if (password!=0 && !isdir) zfi.flg=9; // and 1 means 'password-encrypted' - zfi.lflg = zfi.flg; // to be updated later - zfi.how = (ush)method; // to be updated later - zfi.siz = (ulg)(method==STORE && isize>=0 ? isize+passex : 0); // to be updated later - zfi.len = (ulg)(isize); // to be updated later - zfi.dsk = 0; - zfi.atx = attr; - zfi.off = writ+ooffset; // offset within file of the start of this local record - // stuff the 'times' structure into zfi.extra - - // nb. apparently there's a problem with PocketPC CE(zip)->CE(unzip) fails. And removing the following block fixes it up. - char xloc[EB_L_UT_SIZE]; zfi.extra=xloc; zfi.ext=EB_L_UT_SIZE; - char xcen[EB_C_UT_SIZE]; zfi.cextra=xcen; zfi.cext=EB_C_UT_SIZE; - xloc[0] = 'U'; - xloc[1] = 'T'; - xloc[2] = EB_UT_LEN(3); // length of data part of e.f. - xloc[3] = 0; - xloc[4] = EB_UT_FL_MTIME | EB_UT_FL_ATIME | EB_UT_FL_CTIME; - xloc[5] = (char)(times.mtime); - xloc[6] = (char)(times.mtime >> 8); - xloc[7] = (char)(times.mtime >> 16); - xloc[8] = (char)(times.mtime >> 24); - xloc[9] = (char)(times.atime); - xloc[10] = (char)(times.atime >> 8); - xloc[11] = (char)(times.atime >> 16); - xloc[12] = (char)(times.atime >> 24); - xloc[13] = (char)(times.ctime); - xloc[14] = (char)(times.ctime >> 8); - xloc[15] = (char)(times.ctime >> 16); - xloc[16] = (char)(times.ctime >> 24); - memcpy(zfi.cextra,zfi.extra,EB_C_UT_SIZE); - zfi.cextra[EB_LEN] = EB_UT_LEN(1); - - - // (1) Start by writing the local header: - int r = putlocal(&zfi,swrite,this); - if (r!=ZE_OK) {iclose(); return ZR_WRITE;} - writ += 4 + LOCHEAD + (unsigned int)zfi.nam + (unsigned int)zfi.ext; - if (oerr!=ZR_OK) {iclose(); return oerr;} - - // (1.5) if necessary, write the encryption header - keys[0]=305419896L; - keys[1]=591751049L; - keys[2]=878082192L; - for (const char *cp=password; cp!=0 && *cp!=0; cp++) update_keys(keys,*cp); - // generate some random bytes - if (!has_seeded) srand(GetTickCount()^(unsigned long)GetDesktopWindow()); - char encbuf[12]; for (int i=0; i<12; i++) encbuf[i]=(char)((rand()>>7)&0xff); - encbuf[11] = (char)((zfi.tim>>8)&0xff); - for (int ei=0; ei<12; ei++) encbuf[ei]=zencode(keys,encbuf[ei]); - if (password!=0 && !isdir) {swrite(this,encbuf,12); writ+=12;} - - //(2) Write deflated/stored file to zip file - ZRESULT writeres=ZR_OK; - encwriting = (password!=0 && !isdir); // an object member variable to say whether we write to disk encrypted - if (!isdir && method==DEFLATE) writeres=ideflate(&zfi); - else if (!isdir && method==STORE) writeres=istore(); - else if (isdir) csize=0; - encwriting = false; - iclose(); - writ += csize; - if (oerr!=ZR_OK) return oerr; - if (writeres!=ZR_OK) return ZR_WRITE; - - // (3) Either rewrite the local header with correct information... - bool first_header_has_size_right = (zfi.siz==csize+passex); - zfi.crc = crc; - zfi.siz = csize+passex; - zfi.len = isize; - if (ocanseek && (password==0 || isdir)) - { zfi.how = (ush)method; - if ((zfi.flg & 1) == 0) zfi.flg &= ~8; // clear the extended local header flag - zfi.lflg = zfi.flg; - // rewrite the local header: - if (!oseek(zfi.off-ooffset)) return ZR_SEEK; - if ((r = putlocal(&zfi, swrite,this)) != ZE_OK) return ZR_WRITE; - if (!oseek(writ)) return ZR_SEEK; - } - else - { // (4) ... or put an updated header at the end - if (zfi.how != (ush) method) return ZR_NOCHANGE; - if (method==STORE && !first_header_has_size_right) return ZR_NOCHANGE; - if ((r = putextended(&zfi, swrite,this)) != ZE_OK) return ZR_WRITE; - writ += 16L; - zfi.flg = zfi.lflg; // if flg modified by inflate, for the central index - } - if (oerr!=ZR_OK) return oerr; - - // Keep a copy of the zipfileinfo, for our end-of-zip directory - char *cextra = new char[zfi.cext]; memcpy(cextra,zfi.cextra,zfi.cext); zfi.cextra=cextra; - TZipFileInfo *pzfi = new TZipFileInfo; memcpy(pzfi,&zfi,sizeof(zfi)); - if (zfis==NULL) zfis=pzfi; - else {TZipFileInfo *z=zfis; while (z->nxt!=NULL) z=z->nxt; z->nxt=pzfi;} - return ZR_OK; -} - -ZRESULT TZip::AddCentral() -{ // write central directory - int numentries = 0; - ulg pos_at_start_of_central = writ; - //ulg tot_unc_size=0, tot_compressed_size=0; - bool okay=true; - for (TZipFileInfo *zfi=zfis; zfi!=NULL; ) - { if (okay) - { int res = putcentral(zfi, swrite,this); - if (res!=ZE_OK) okay=false; - } - writ += 4 + CENHEAD + (unsigned int)zfi->nam + (unsigned int)zfi->cext + (unsigned int)zfi->com; - //tot_unc_size += zfi->len; - //tot_compressed_size += zfi->siz; - numentries++; - // - TZipFileInfo *zfinext = zfi->nxt; - if (zfi->cextra!=0) delete[] zfi->cextra; - delete zfi; - zfi = zfinext; - } - ulg center_size = writ - pos_at_start_of_central; - if (okay) - { int res = putend(numentries, center_size, pos_at_start_of_central+ooffset, 0, NULL, swrite,this); - if (res!=ZE_OK) okay=false; - writ += 4 + ENDHEAD + 0; - } - if (!okay) return ZR_WRITE; - return ZR_OK; -} - - - - - -ZRESULT lasterrorZ=ZR_OK; - -unsigned int FormatZipMessageZ(ZRESULT code, char *buf,unsigned int len) -{ if (code==ZR_RECENT) code=lasterrorZ; - const char *msg="unknown zip result code"; - switch (code) - { case ZR_OK: msg="Success"; break; - case ZR_NODUPH: msg="Culdn't duplicate handle"; break; - case ZR_NOFILE: msg="Couldn't create/open file"; break; - case ZR_NOALLOC: msg="Failed to allocate memory"; break; - case ZR_WRITE: msg="Error writing to file"; break; - case ZR_NOTFOUND: msg="File not found in the zipfile"; break; - case ZR_MORE: msg="Still more data to unzip"; break; - case ZR_CORRUPT: msg="Zipfile is corrupt or not a zipfile"; break; - case ZR_READ: msg="Error reading file"; break; - case ZR_ARGS: msg="Caller: faulty arguments"; break; - case ZR_PARTIALUNZ: msg="Caller: the file had already been partially unzipped"; break; - case ZR_NOTMMAP: msg="Caller: can only get memory of a memory zipfile"; break; - case ZR_MEMSIZE: msg="Caller: not enough space allocated for memory zipfile"; break; - case ZR_FAILED: msg="Caller: there was a previous error"; break; - case ZR_ENDED: msg="Caller: additions to the zip have already been ended"; break; - case ZR_ZMODE: msg="Caller: mixing creation and opening of zip"; break; - case ZR_NOTINITED: msg="Zip-bug: internal initialisation not completed"; break; - case ZR_SEEK: msg="Zip-bug: trying to seek the unseekable"; break; - case ZR_MISSIZE: msg="Zip-bug: the anticipated size turned out wrong"; break; - case ZR_NOCHANGE: msg="Zip-bug: tried to change mind, but not allowed"; break; - case ZR_FLATE: msg="Zip-bug: an internal error during flation"; break; - } - unsigned int mlen=(unsigned int)strlen(msg); - if (buf==0 || len==0) return mlen; - unsigned int n=mlen; if (n+1>len) n=len-1; - strncpy(buf,msg,n); buf[n]=0; - return mlen; -} - - - -typedef struct -{ DWORD flag; - TZip *zip; -} TZipHandleData; - - -HZIP CreateZipInternal(void *z,unsigned int len,DWORD flags, const char *password) -{ TZip *zip = new TZip(password); - lasterrorZ = zip->Create(z,len,flags); - if (lasterrorZ!=ZR_OK) {delete zip; return 0;} - TZipHandleData *han = new TZipHandleData; - han->flag=2; han->zip=zip; return (HZIP)han; -} -HZIP CreateZipHandle(HANDLE h, const char *password) {return CreateZipInternal(h,0,ZIP_HANDLE,password);} -HZIP CreateZip(const TCHAR *fn, const char *password) {return CreateZipInternal((void*)fn,0,ZIP_FILENAME,password);} -HZIP CreateZip(void *z,unsigned int len, const char *password) {return CreateZipInternal(z,len,ZIP_MEMORY,password);} - - -ZRESULT ZipAddInternal(HZIP hz,const TCHAR *dstzn, void *src,unsigned int len, DWORD flags) -{ if (hz==0) {lasterrorZ=ZR_ARGS;return ZR_ARGS;} - TZipHandleData *han = (TZipHandleData*)hz; - if (han->flag!=2) {lasterrorZ=ZR_ZMODE;return ZR_ZMODE;} - TZip *zip = han->zip; - lasterrorZ = zip->Add(dstzn,src,len,flags); - return lasterrorZ; -} -ZRESULT ZipAdd(HZIP hz,const TCHAR *dstzn, const TCHAR *fn) {return ZipAddInternal(hz,dstzn,(void*)fn,0,ZIP_FILENAME);} -ZRESULT ZipAdd(HZIP hz,const TCHAR *dstzn, void *src,unsigned int len) {return ZipAddInternal(hz,dstzn,src,len,ZIP_MEMORY);} -ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, HANDLE h) {return ZipAddInternal(hz,dstzn,h,0,ZIP_HANDLE);} -ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, HANDLE h, unsigned int len) {return ZipAddInternal(hz,dstzn,h,len,ZIP_HANDLE);} -ZRESULT ZipAddFolder(HZIP hz,const TCHAR *dstzn) {return ZipAddInternal(hz,dstzn,0,0,ZIP_FOLDER);} - - - -ZRESULT ZipGetMemory(HZIP hz, void **buf, unsigned long *len) -{ if (hz==0) {if (buf!=0) *buf=0; if (len!=0) *len=0; lasterrorZ=ZR_ARGS;return ZR_ARGS;} - TZipHandleData *han = (TZipHandleData*)hz; - if (han->flag!=2) {lasterrorZ=ZR_ZMODE;return ZR_ZMODE;} - TZip *zip = han->zip; - lasterrorZ = zip->GetMemory(buf,len); - return lasterrorZ; -} - -ZRESULT CloseZipZ(HZIP hz) -{ if (hz==0) {lasterrorZ=ZR_ARGS;return ZR_ARGS;} - TZipHandleData *han = (TZipHandleData*)hz; - if (han->flag!=2) {lasterrorZ=ZR_ZMODE;return ZR_ZMODE;} - TZip *zip = han->zip; - lasterrorZ = zip->Close(); - delete zip; - delete han; - return lasterrorZ; -} - -bool IsZipHandleZ(HZIP hz) -{ if (hz==0) return false; - TZipHandleData *han = (TZipHandleData*)hz; - return (han->flag==2); -} - diff --git a/microsip/zip.h b/microsip/zip.h deleted file mode 100644 index 083895ec..00000000 --- a/microsip/zip.h +++ /dev/null @@ -1,203 +0,0 @@ -#ifndef _zip_H -#define _zip_H - - -// ZIP functions -- for creating zip files -// This file is a repackaged form of the Info-Zip source code available -// at www.info-zip.org. The original copyright notice may be found in -// zip.cpp. The repackaging was done by Lucian Wischik to simplify and -// extend its use in Windows/C++. Also to add encryption and unicode. - - -#ifndef _unzip_H -DECLARE_HANDLE(HZIP); -#endif -// An HZIP identifies a zip file that is being created - -typedef DWORD ZRESULT; -// return codes from any of the zip functions. Listed later. - - - -HZIP CreateZip(const TCHAR *fn, const char *password); -HZIP CreateZip(void *buf,unsigned int len, const char *password); -HZIP CreateZipHandle(HANDLE h, const char *password); -// CreateZip - call this to start the creation of a zip file. -// As the zip is being created, it will be stored somewhere: -// to a pipe: CreateZipHandle(hpipe_write); -// in a file (by handle): CreateZipHandle(hfile); -// in a file (by name): CreateZip("c:\\test.zip"); -// in memory: CreateZip(buf, len); -// or in pagefile memory: CreateZip(0, len); -// The final case stores it in memory backed by the system paging file, -// where the zip may not exceed len bytes. This is a bit friendlier than -// allocating memory with new[]: it won't lead to fragmentation, and the -// memory won't be touched unless needed. That means you can give very -// large estimates of the maximum-size without too much worry. -// As for the password, it lets you encrypt every file in the archive. -// (This api doesn't support per-file encryption.) -// Note: because pipes don't allow random access, the structure of a zipfile -// created into a pipe is slightly different from that created into a file -// or memory. In particular, the compressed-size of the item cannot be -// stored in the zipfile until after the item itself. (Also, for an item added -// itself via a pipe, the uncompressed-size might not either be known until -// after.) This is not normally a problem. But if you try to unzip via a pipe -// as well, then the unzipper will not know these things about the item until -// after it has been unzipped. Therefore: for unzippers which don't just write -// each item to disk or to a pipe, but instead pre-allocate memory space into -// which to unzip them, then either you have to create the zip not to a pipe, -// or you have to add items not from a pipe, or at least when adding items -// from a pipe you have to specify the length. -// Note: for windows-ce, you cannot close the handle until after CloseZip. -// but for real windows, the zip makes its own copy of your handle, so you -// can close yours anytime. - - -ZRESULT ZipAdd(HZIP hz,const TCHAR *dstzn, const TCHAR *fn); -ZRESULT ZipAdd(HZIP hz,const TCHAR *dstzn, void *src,unsigned int len); -ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, HANDLE h); -ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, HANDLE h, unsigned int len); -ZRESULT ZipAddFolder(HZIP hz,const TCHAR *dstzn); -// ZipAdd - call this for each file to be added to the zip. -// dstzn is the name that the file will be stored as in the zip file. -// The file to be added to the zip can come -// from a pipe: ZipAddHandle(hz,"file.dat", hpipe_read); -// from a file: ZipAddHandle(hz,"file.dat", hfile); -// from a filen: ZipAdd(hz,"file.dat", "c:\\docs\\origfile.dat"); -// from memory: ZipAdd(hz,"subdir\\file.dat", buf,len); -// (folder): ZipAddFolder(hz,"subdir"); -// Note: if adding an item from a pipe, and if also creating the zip file itself -// to a pipe, then you might wish to pass a non-zero length to the ZipAddHandle -// function. This will let the zipfile store the item's size ahead of the -// compressed item itself, which in turn makes it easier when unzipping the -// zipfile from a pipe. - -ZRESULT ZipGetMemory(HZIP hz, void **buf, unsigned long *len); -// ZipGetMemory - If the zip was created in memory, via ZipCreate(0,len), -// then this function will return information about that memory block. -// buf will receive a pointer to its start, and len its length. -// Note: you can't add any more after calling this. - -ZRESULT CloseZip(HZIP hz); -// CloseZip - the zip handle must be closed with this function. - -unsigned int FormatZipMessage(ZRESULT code, TCHAR *buf,unsigned int len); -// FormatZipMessage - given an error code, formats it as a string. -// It returns the length of the error message. If buf/len points -// to a real buffer, then it also writes as much as possible into there. - - - -// These are the result codes: -#define ZR_OK 0x00000000 // nb. the pseudo-code zr-recent is never returned, -#define ZR_RECENT 0x00000001 // but can be passed to FormatZipMessage. -// The following come from general system stuff (e.g. files not openable) -#define ZR_GENMASK 0x0000FF00 -#define ZR_NODUPH 0x00000100 // couldn't duplicate the handle -#define ZR_NOFILE 0x00000200 // couldn't create/open the file -#define ZR_NOALLOC 0x00000300 // failed to allocate some resource -#define ZR_WRITE 0x00000400 // a general error writing to the file -#define ZR_NOTFOUND 0x00000500 // couldn't find that file in the zip -#define ZR_MORE 0x00000600 // there's still more data to be unzipped -#define ZR_CORRUPT 0x00000700 // the zipfile is corrupt or not a zipfile -#define ZR_READ 0x00000800 // a general error reading the file -// The following come from mistakes on the part of the caller -#define ZR_CALLERMASK 0x00FF0000 -#define ZR_ARGS 0x00010000 // general mistake with the arguments -#define ZR_NOTMMAP 0x00020000 // tried to ZipGetMemory, but that only works on mmap zipfiles, which yours wasn't -#define ZR_MEMSIZE 0x00030000 // the memory size is too small -#define ZR_FAILED 0x00040000 // the thing was already failed when you called this function -#define ZR_ENDED 0x00050000 // the zip creation has already been closed -#define ZR_MISSIZE 0x00060000 // the indicated input file size turned out mistaken -#define ZR_PARTIALUNZ 0x00070000 // the file had already been partially unzipped -#define ZR_ZMODE 0x00080000 // tried to mix creating/opening a zip -// The following come from bugs within the zip library itself -#define ZR_BUGMASK 0xFF000000 -#define ZR_NOTINITED 0x01000000 // initialisation didn't work -#define ZR_SEEK 0x02000000 // trying to seek in an unseekable file -#define ZR_NOCHANGE 0x04000000 // changed its mind on storage, but not allowed -#define ZR_FLATE 0x05000000 // an internal error in the de/inflation code - - - - - - -// e.g. -// -// (1) Traditional use, creating a zipfile from existing files -// HZIP hz = CreateZip("c:\\simple1.zip",0); -// ZipAdd(hz,"znsimple.bmp", "c:\\simple.bmp"); -// ZipAdd(hz,"znsimple.txt", "c:\\simple.txt"); -// CloseZip(hz); -// -// (2) Memory use, creating an auto-allocated mem-based zip file from various sources -// HZIP hz = CreateZip(0,100000, 0); -// // adding a conventional file... -// ZipAdd(hz,"src1.txt", "c:\\src1.txt"); -// // adding something from memory... -// char buf[1000]; for (int i=0; i<1000; i++) buf[i]=(char)(i&0x7F); -// ZipAdd(hz,"file.dat", buf,1000); -// // adding something from a pipe... -// HANDLE hread,hwrite; CreatePipe(&hread,&hwrite,NULL,0); -// HANDLE hthread = CreateThread(0,0,ThreadFunc,(void*)hwrite,0,0); -// ZipAdd(hz,"unz3.dat", hread,1000); // the '1000' is optional. -// WaitForSingleObject(hthread,INFINITE); -// CloseHandle(hthread); CloseHandle(hread); -// ... meanwhile DWORD WINAPI ThreadFunc(void *dat) -// { HANDLE hwrite = (HANDLE)dat; -// char buf[1000]={17}; -// DWORD writ; WriteFile(hwrite,buf,1000,&writ,NULL); -// CloseHandle(hwrite); -// return 0; -// } -// // and now that the zip is created, let's do something with it: -// void *zbuf; unsigned long zlen; ZipGetMemory(hz,&zbuf,&zlen); -// HANDLE hfz = CreateFile("test2.zip",GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); -// DWORD writ; WriteFile(hfz,zbuf,zlen,&writ,NULL); -// CloseHandle(hfz); -// CloseZip(hz); -// -// (3) Handle use, for file handles and pipes -// HANDLE hzread,hzwrite; CreatePipe(&hzread,&hzwrite,0,0); -// HANDLE hthread = CreateThread(0,0,ZipReceiverThread,(void*)hzread,0,0); -// HZIP hz = CreateZipHandle(hzwrite,0); -// // ... add to it -// CloseZip(hz); -// CloseHandle(hzwrite); -// WaitForSingleObject(hthread,INFINITE); -// CloseHandle(hthread); -// ... meanwhile DWORD WINAPI ZipReceiverThread(void *dat) -// { HANDLE hread = (HANDLE)dat; -// char buf[1000]; -// while (true) -// { DWORD red; ReadFile(hread,buf,1000,&red,NULL); -// // ... and do something with this zip data we're receiving -// if (red==0) break; -// } -// CloseHandle(hread); -// return 0; -// } - - - -// Now we indulge in a little skullduggery so that the code works whether -// the user has included just zip or both zip and unzip. -// Idea: if header files for both zip and unzip are present, then presumably -// the cpp files for zip and unzip are both present, so we will call -// one or the other of them based on a dynamic choice. If the header file -// for only one is present, then we will bind to that particular one. -ZRESULT CloseZipZ(HZIP hz); -unsigned int FormatZipMessageZ(ZRESULT code, char *buf,unsigned int len); -bool IsZipHandleZ(HZIP hz); -#ifdef _unzip_H -#undef CloseZip -#define CloseZip(hz) (IsZipHandleZ(hz)?CloseZipZ(hz):CloseZipU(hz)) -#else -#define CloseZip CloseZipZ -#define FormatZipMessage FormatZipMessageZ -#endif - - - -#endif From 21b3a419411a0ae6499d21bf0ae59c37d1c3bba8 Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Fri, 22 Apr 2022 20:49:04 +0530 Subject: [PATCH 6/7] Enable CodeQL (#56) --- .github/workflows/codeql-analysis.yml | 99 +++++++++++++++++++++++++++ .github/workflows/main.yml | 4 +- 2 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000..4957171a --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,99 @@ +name: "CodeQL" + +on: + push: + branches: [ master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ master ] + schedule: + - cron: '40 4 * * 1' + +jobs: + analyze: + name: Analyze + permissions: + actions: read + contents: read + security-events: write + + runs-on: macos-10.15 + strategy: + fail-fast: false + matrix: + language: [ 'cpp' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://git.io/codeql-language-support + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Checkout submodules # checkout rest + shell: bash + run: | + git config --global url."https://github.com/".insteadOf "git@github.com:" + auth_header="$(git config --local --get http.https://github.com/.extraheader)" + git submodule sync --recursive + git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 + + - name: Install Dependencies + shell: bash + run : | + export HOMEBREW_NO_INSTALL_CLEANUP=true + brew install autoconf automake libtool tree wget opencore-amr + wget https://gist.githubusercontent.com/kingster/1954ead3c38a40cac88c5c1311bb39c5/raw/343da2c7a2a52ee5a1c03902cc5e44ed83b1dd5d/cryptopp.rb + brew install --build-from-source -f cryptopp.rb + + #boost + pushd tinyphone-osx/vendor/boost + ./boost.sh -macos --boost-version 1.74.0 + popd + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + - name: Compile Libraries + run : | + #xcode needs to be proper at this point + xcode-select --print-path + + #stastd + pushd lib/statsd-cpp + mkdir build-osx + cd build-osx + cmake .. + make + popd + + - name: Build Project + run : | + pushd tinyphone-osx + pod install + xcodebuild -workspace Tinyphone.xcworkspace -scheme Tinyphone -configuration Release CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO + + # # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # # If this step fails, then you should remove it and run the build manually (see below) + # - name: Autobuild + # uses: github/codeql-action/autobuild@v2 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a128c24d..d8b14367 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -126,7 +126,7 @@ jobs: mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles #cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles - - name: Install dependencies + - name: Install Dependencies shell: bash run : | export HOMEBREW_NO_INSTALL_CLEANUP=true @@ -142,7 +142,7 @@ jobs: #boost pushd tinyphone-osx/vendor/boost - ./boost.sh -macos --boost-version 1.68.0 + ./boost.sh -macos --boost-version 1.74.0 popd #stastd From f69b3a9658b408c4231b966bf8046c3349f516d3 Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Tue, 26 Apr 2022 15:29:25 +0530 Subject: [PATCH 7/7] Bump crow fixes secbug cpp/comparison-with-wider-type (#57) --- lib/crow | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/crow b/lib/crow index 588020ee..4f533c4b 160000 --- a/lib/crow +++ b/lib/crow @@ -1 +1 @@ -Subproject commit 588020ee1c6c73ff079e57cafc6edd4d818e566e +Subproject commit 4f533c4bab88f53b542949167dbaf0d9bf1ba215