소스 검색

Merge branch 'master' into docking

# Conflicts:
#	imgui.cpp
#	imgui_internal.h
#	imgui_widgets.cpp
omar 5 년 전
부모
커밋
a704614b3e

+ 30 - 0
.gitattributes

@@ -0,0 +1,30 @@
+* text=auto
+
+*.c text
+*.cpp text
+*.h text
+*.m text
+*.mm text
+*.md text
+*.txt text
+*.html text
+*.bat text
+*.frag text
+*.vert text
+*.mkb text
+*.icf text
+
+*.sln text eol=crlf
+*.vcxproj text eol=crlf
+*.vcxproj.filters text eol=crlf
+*.natvis text eol=crlf
+
+Makefile text eol=lf
+*.sh text eol=lf
+*.pbxproj text eol=lf
+*.storyboard text eol=lf
+*.plist text eol=lf
+
+*.png binary
+*.ttf binary
+*.lib binary

+ 165 - 35
.github/workflows/build.yml

@@ -1,36 +1,142 @@
 name: build
 
-on: [push, pull_request]
+on:
+  push: {}
+  pull_request: {}
+  schedule:
+    - cron:  '0 9 * * *'
 
 jobs:
   Windows:
     runs-on: windows-2019
     env:
       MSBUILD_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\
+      # Until gh-actions allow us to use env variables inside other env variables (because we need %GITHUB_WORKSPACE%) we have to use relative path to imgui/examples/example_name directory.
+      SDL2_DIR: ..\..\SDL2-devel-2.0.10-VC\SDL2-2.0.10\
+      VULKAN_SDK: ..\..\vulkan-sdk-1.1.121.2\
     steps:
       - uses: actions/checkout@v1
         with:
           fetch-depth: 1
 
+      - name: Install Dependencies
+        shell: powershell
+        run: |
+          Invoke-WebRequest -Uri "https://www.libsdl.org/release/SDL2-devel-2.0.10-VC.zip" -OutFile "SDL2-devel-2.0.10-VC.zip"
+          Expand-Archive -Path SDL2-devel-2.0.10-VC.zip
+          Invoke-WebRequest -Uri "https://github.com/ocornut/imgui/files/3789205/vulkan-sdk-1.1.121.2.zip" -OutFile vulkan-sdk-1.1.121.2.zip
+          Expand-Archive -Path vulkan-sdk-1.1.121.2.zip
+
       - name: Fix Projects
         shell: powershell
         run: |
-          # Replace v110 toolset with v142. Only v141 and v142 toolsets are available on CI workers.
-          # Replace 8.1 platform sdk with 10.0.18362.0. Workers do not contain legacy SDKs.
           # WARNING: This will need updating if toolset/sdk change in project files!
           gci -recurse -filter "*.vcxproj" | ForEach-Object {
-            (Get-Content $_.FullName) -Replace "<PlatformToolset>v110</PlatformToolset>","<PlatformToolset>v142</PlatformToolset>" -Replace "<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>","<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>" | Set-Content -Path $_.FullName
+            # Fix SDK and toolset for most samples.
+            (Get-Content $_.FullName) -Replace "<PlatformToolset>v110</PlatformToolset>","<PlatformToolset>v142</PlatformToolset>" | Set-Content -Path $_.FullName
+            (Get-Content $_.FullName) -Replace "<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>","<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>" | Set-Content -Path $_.FullName
+            # Fix SDK and toolset for samples that require newer SDK/toolset. At the moment it is only dx12.
+            (Get-Content $_.FullName) -Replace "<PlatformToolset>v140</PlatformToolset>","<PlatformToolset>v142</PlatformToolset>" | Set-Content -Path $_.FullName
+            (Get-Content $_.FullName) -Replace "<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>","<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>" | Set-Content -Path $_.FullName
           }
 
-      - name: Build x86
+      # Not using matrix here because it would inflate job count too much. Check out and setup is done for every job and that makes build times way too long.
+      - name: Build Win32 example_glfw_opengl2
         shell: cmd
-        run: |
-          "%MSBUILD_PATH%\MSBuild.exe" /p:Platform=Win32 /p:Configuration=Release examples/imgui_examples.sln
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj /p:Platform=Win32 /p:Configuration=Release'
 
-      - name: Build x64
+      - name: Build Win32 example_glfw_opengl3
         shell: cmd
-        run: |
-          "%MSBUILD_PATH%\MSBuild.exe" /p:Platform=x64 /p:Configuration=Release examples/imgui_examples.sln
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj /p:Platform=Win32 /p:Configuration=Release'
+        if: github.event_name == 'schedule'
+
+      - name: Build Win32 example_glfw_vulkan
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj /p:Platform=Win32 /p:Configuration=Release'
+        if: github.event_name == 'schedule'
+
+      - name: Build Win32 example_sdl_vulkan
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl_vulkan/example_sdl_vulkan.vcxproj /p:Platform=Win32 /p:Configuration=Release'
+        if: github.event_name == 'schedule'
+
+      - name: Build Win32 example_sdl_opengl2
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl_opengl2/example_sdl_opengl2.vcxproj /p:Platform=Win32 /p:Configuration=Release'
+        if: github.event_name == 'schedule'
+
+      - name: Build Win32 example_sdl_opengl3
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl_opengl3/example_sdl_opengl3.vcxproj /p:Platform=Win32 /p:Configuration=Release'
+
+      - name: Build Win32 example_sdl_directx11
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl_directx11/example_sdl_directx11.vcxproj /p:Platform=Win32 /p:Configuration=Release'
+        if: github.event_name == 'schedule'
+
+      - name: Build Win32 example_win32_directx9
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx9/example_win32_directx9.vcxproj /p:Platform=Win32 /p:Configuration=Release'
+
+      - name: Build Win32 example_win32_directx10
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx10/example_win32_directx10.vcxproj /p:Platform=Win32 /p:Configuration=Release'
+
+      - name: Build Win32 example_win32_directx11
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx11/example_win32_directx11.vcxproj /p:Platform=Win32 /p:Configuration=Release'
+        if: github.event_name == 'schedule'
+
+      - name: Build x64 example_glfw_opengl2
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj /p:Platform=x64 /p:Configuration=Release'
+        if: github.event_name == 'schedule'
+
+      - name: Build x64 example_glfw_opengl3
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release'
+
+      - name: Build x64 example_glfw_vulkan
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release'
+
+      - name: Build x64 example_sdl_vulkan
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl_vulkan/example_sdl_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release'
+        if: github.event_name == 'schedule'
+
+      - name: Build x64 example_sdl_opengl2
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl_opengl2/example_sdl_opengl2.vcxproj /p:Platform=x64 /p:Configuration=Release'
+        if: github.event_name == 'schedule'
+
+      - name: Build x64 example_sdl_opengl3
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl_opengl3/example_sdl_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release'
+        if: github.event_name == 'schedule'
+
+      - name: Build x64 example_sdl_directx11
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl_directx11/example_sdl_directx11.vcxproj /p:Platform=x64 /p:Configuration=Release'
+
+      - name: Build x64 example_win32_directx9
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx9/example_win32_directx9.vcxproj /p:Platform=x64 /p:Configuration=Release'
+        if: github.event_name == 'schedule'
+
+      - name: Build x64 example_win32_directx10
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx10/example_win32_directx10.vcxproj /p:Platform=x64 /p:Configuration=Release'
+        if: github.event_name == 'schedule'
+
+      - name: Build x64 example_win32_directx11
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx11/example_win32_directx11.vcxproj /p:Platform=x64 /p:Configuration=Release'
+        if: github.event_name == 'schedule'
+
+      - name: Build x64 example_win32_directx12
+        shell: cmd
+        run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx12/example_win32_directx12.vcxproj /p:Platform=x64 /p:Configuration=Release'
 
   Linux:
     runs-on: ubuntu-18.04
@@ -44,13 +150,22 @@ jobs:
         sudo apt-get update
         sudo apt-get install -y libglfw3-dev libsdl2-dev
 
-    - name: Build
-      run: |
-        make -C examples/example_null
-        make -C examples/example_glfw_opengl2
-        make -C examples/example_glfw_opengl3
-        make -C examples/example_sdl_opengl2
-        make -C examples/example_sdl_opengl3
+    - name: Build example_null
+      run: make -C examples/example_null
+
+    - name: Build example_glfw_opengl2
+      run: make -C examples/example_glfw_opengl2
+
+    - name: Build example_glfw_opengl3
+      run: make -C examples/example_glfw_opengl3
+      if: github.event_name == 'schedule'
+
+    - name: Build example_sdl_opengl2
+      run: make -C examples/example_sdl_opengl2
+      if: github.event_name == 'schedule'
+
+    - name: Build example_sdl_opengl3
+      run: make -C examples/example_sdl_opengl3
 
   MacOS:
     runs-on: macOS-10.14
@@ -64,16 +179,31 @@ jobs:
         brew install glfw3
         brew install sdl2
 
-    - name: Build
-      run: |
-        make -C examples/example_null
-        make -C examples/example_glfw_opengl2
-        make -C examples/example_glfw_opengl3
-        make -C examples/example_glfw_metal
-        make -C examples/example_sdl_opengl2
-        make -C examples/example_sdl_opengl3
-        xcodebuild -project examples/example_apple_metal/example_apple_metal.xcodeproj -target example_apple_metal_macos
-        xcodebuild -project examples/example_apple_opengl2/example_apple_opengl2.xcodeproj -target example_osx_opengl2
+    - name: Build example_null
+      run: make -C examples/example_null
+
+    - name: Build example_glfw_opengl2
+      run: make -C examples/example_glfw_opengl2
+
+    - name: Build example_glfw_opengl3
+      run: make -C examples/example_glfw_opengl3
+      if: github.event_name == 'schedule'
+
+    - name: Build example_glfw_metal
+      run: make -C examples/example_glfw_metal
+
+    - name: Build example_sdl_opengl2
+      run: make -C examples/example_sdl_opengl2
+      if: github.event_name == 'schedule'
+
+    - name: Build example_sdl_opengl3
+      run: make -C examples/example_sdl_opengl3
+
+    - name: Build example_apple_metal
+      run: xcodebuild -project examples/example_apple_metal/example_apple_metal.xcodeproj -target example_apple_metal_macos
+
+    - name: Build example_apple_opengl2
+      run: xcodebuild -project examples/example_apple_opengl2/example_apple_opengl2.xcodeproj -target example_osx_opengl2
 
   iOS:
     runs-on: macOS-10.14
@@ -82,7 +212,7 @@ jobs:
       with:
         fetch-depth: 1
 
-    - name: Build
+    - name: Build example_apple_metal
       run: |
         # Code signing is required, but we disable it because it is irrelevant for CI builds.
         xcodebuild -project examples/example_apple_metal/example_apple_metal.xcodeproj -target example_apple_metal_ios CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
@@ -96,13 +226,13 @@ jobs:
 
     - name: Install Dependencies
       run: |
-        wget -q https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz
-        tar -xvf emsdk-portable.tar.gz
-        emsdk-portable/emsdk update
-        emsdk-portable/emsdk install latest
-        emsdk-portable/emsdk activate latest
+        wget -q https://github.com/emscripten-core/emsdk/archive/master.tar.gz
+        tar -xvf master.tar.gz
+        emsdk-master/emsdk update
+        emsdk-master/emsdk install latest-fastcomp
+        emsdk-master/emsdk activate latest-fastcomp
 
-    - name: Build
+    - name: Build example_emscripten
       run: |
-        source emsdk-portable/emsdk_env.sh
+        source emsdk-master/emsdk_env.sh
         make -C examples/example_emscripten

+ 2 - 0
docs/CHANGELOG.txt

@@ -137,9 +137,11 @@ Other Changes:
   incorrectly locating the arrow hit position to the left of the frame. (#2451, #2438, #1897)
 - DragScalar, SliderScalar, InputScalar: Added p_ prefix to parameter that are pointers to the data
   to clarify how they are used, and more comments redirecting to the demo code. (#2844)
+- Misc: Windows: Do not use _wfopen() if IMGUI_DISABLE_WIN32_FUNCTIONS is defined. (#2815)
 - Docs: Improved and moved FAQ to docs/FAQ.md so it can be readable on the web. [@ButternCream, @ocornut]
 - Docs: Added permanent redirect from https://www.dearimgui.org/faq to FAQ page.
 - Demo: Added simple item reordering demo in Widgets -> Drag and Drop section. (#2823, #143) [@rokups]
+- Metrics: Expose basic details of each window key/value state storage.
 - Examples: DX12: Using IDXGIDebug1::ReportLiveObjects() when DX12_ENABLE_DEBUG_LAYER is enabled.
 - Examples: Emscripten: Removed NO_FILESYSTEM from Makefile, seems to fail on some setup. (#2734) [@Funto]
 - Backends: OpenGL3: Fix building with pre-3.2 GL loaders which do not expose glDrawElementsBaseVertex(),

+ 180 - 180
examples/example_sdl_directx11/example_sdl_directx11.vcxproj

@@ -1,181 +1,181 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{9E1987E3-1F19-45CA-B9C9-D31E791836D8}</ProjectGuid>
-    <RootNamespace>example_sdl_directx11</RootNamespace>
-    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
-    <ProjectName>example_sdl_directx11</ProjectName>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>MultiByte</CharacterSet>
-    <PlatformToolset>v110</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>MultiByte</CharacterSet>
-    <PlatformToolset>v110</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>MultiByte</CharacterSet>
-    <PlatformToolset>v110</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>MultiByte</CharacterSet>
-    <PlatformToolset>v110</PlatformToolset>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
-    <IntDir>$(ProjectDir)$(Configuration)\</IntDir>
-    <IncludePath>$(IncludePath)</IncludePath>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
-    <IntDir>$(ProjectDir)$(Configuration)\</IntDir>
-    <IncludePath>$(IncludePath)</IncludePath>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
-    <IntDir>$(ProjectDir)$(Configuration)\</IntDir>
-    <IncludePath>$(IncludePath)</IncludePath>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
-    <IntDir>$(ProjectDir)$(Configuration)\</IntDir>
-    <IncludePath>$(IncludePath)</IncludePath>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <WarningLevel>Level4</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>%SDL2_DIR%\lib\x86;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>SDL2.lib;SDL2main.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <SubSystem>Console</SubSystem>
-      <IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <WarningLevel>Level4</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>%SDL2_DIR%\lib\x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>SDL2.lib;SDL2main.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <SubSystem>Console</SubSystem>
-      <IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level4</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>%SDL2_DIR%\lib\x86;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>SDL2.lib;SDL2main.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <SubSystem>Console</SubSystem>
-      <IgnoreSpecificDefaultLibraries>
-      </IgnoreSpecificDefaultLibraries>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level4</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>%SDL2_DIR%\lib\x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>SDL2.lib;SDL2main.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <SubSystem>Console</SubSystem>
-      <IgnoreSpecificDefaultLibraries>
-      </IgnoreSpecificDefaultLibraries>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\imgui.cpp" />
-    <ClCompile Include="..\..\imgui_demo.cpp" />
-    <ClCompile Include="..\..\imgui_draw.cpp" />
-    <ClCompile Include="..\..\imgui_widgets.cpp" />
-    <ClCompile Include="..\imgui_impl_dx11.cpp" />
-    <ClCompile Include="..\imgui_impl_sdl.cpp" />
-    <ClCompile Include="main.cpp" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\imconfig.h" />
-    <ClInclude Include="..\..\imgui.h" />
-    <ClInclude Include="..\..\imgui_internal.h" />
-    <ClInclude Include="..\imgui_impl_dx11.h" />
-    <ClInclude Include="..\imgui_impl_sdl.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="..\..\misc\natvis\imgui.natvis" />
-    <None Include="..\README.txt" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{9E1987E3-1F19-45CA-B9C9-D31E791836D8}</ProjectGuid>
+    <RootNamespace>example_sdl_directx11</RootNamespace>
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+    <ProjectName>example_sdl_directx11</ProjectName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+    <IntDir>$(ProjectDir)$(Configuration)\</IntDir>
+    <IncludePath>$(IncludePath)</IncludePath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+    <IntDir>$(ProjectDir)$(Configuration)\</IntDir>
+    <IncludePath>$(IncludePath)</IncludePath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+    <IntDir>$(ProjectDir)$(Configuration)\</IntDir>
+    <IncludePath>$(IncludePath)</IncludePath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+    <IntDir>$(ProjectDir)$(Configuration)\</IntDir>
+    <IncludePath>$(IncludePath)</IncludePath>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>%SDL2_DIR%\lib\x86;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>SDL2.lib;SDL2main.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <SubSystem>Console</SubSystem>
+      <IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>%SDL2_DIR%\lib\x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>SDL2.lib;SDL2main.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <SubSystem>Console</SubSystem>
+      <IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalLibraryDirectories>%SDL2_DIR%\lib\x86;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>SDL2.lib;SDL2main.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <SubSystem>Console</SubSystem>
+      <IgnoreSpecificDefaultLibraries>
+      </IgnoreSpecificDefaultLibraries>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>..\..;..;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalLibraryDirectories>%SDL2_DIR%\lib\x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>SDL2.lib;SDL2main.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <SubSystem>Console</SubSystem>
+      <IgnoreSpecificDefaultLibraries>
+      </IgnoreSpecificDefaultLibraries>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\imgui.cpp" />
+    <ClCompile Include="..\..\imgui_demo.cpp" />
+    <ClCompile Include="..\..\imgui_draw.cpp" />
+    <ClCompile Include="..\..\imgui_widgets.cpp" />
+    <ClCompile Include="..\imgui_impl_dx11.cpp" />
+    <ClCompile Include="..\imgui_impl_sdl.cpp" />
+    <ClCompile Include="main.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\imconfig.h" />
+    <ClInclude Include="..\..\imgui.h" />
+    <ClInclude Include="..\..\imgui_internal.h" />
+    <ClInclude Include="..\imgui_impl_dx11.h" />
+    <ClInclude Include="..\imgui_impl_sdl.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\misc\natvis\imgui.natvis" />
+    <None Include="..\README.txt" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
 </Project>

+ 56 - 56
examples/example_sdl_directx11/example_sdl_directx11.vcxproj.filters

@@ -1,57 +1,57 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="imgui">
-      <UniqueIdentifier>{0587d7a3-f2ce-4d56-b84f-a0005d3bfce6}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="sources">
-      <UniqueIdentifier>{08e36723-ce4f-4cff-9662-c40801cf1acf}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\imconfig.h">
-      <Filter>imgui</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\imgui.h">
-      <Filter>imgui</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\imgui_internal.h">
-      <Filter>imgui</Filter>
-    </ClInclude>
-    <ClInclude Include="..\imgui_impl_dx11.h">
-      <Filter>sources</Filter>
-    </ClInclude>
-    <ClInclude Include="..\imgui_impl_sdl.h">
-      <Filter>sources</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\imgui.cpp">
-      <Filter>imgui</Filter>
-    </ClCompile>
-    <ClCompile Include="main.cpp">
-      <Filter>sources</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\imgui_demo.cpp">
-      <Filter>imgui</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\imgui_draw.cpp">
-      <Filter>imgui</Filter>
-    </ClCompile>
-    <ClCompile Include="..\imgui_impl_dx11.cpp">
-      <Filter>sources</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\imgui_widgets.cpp">
-      <Filter>imgui</Filter>
-    </ClCompile>
-    <ClCompile Include="..\imgui_impl_sdl.cpp">
-      <Filter>sources</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="..\README.txt" />
-    <None Include="..\..\misc\natvis\imgui.natvis">
-      <Filter>sources</Filter>
-    </None>
-  </ItemGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="imgui">
+      <UniqueIdentifier>{0587d7a3-f2ce-4d56-b84f-a0005d3bfce6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="sources">
+      <UniqueIdentifier>{08e36723-ce4f-4cff-9662-c40801cf1acf}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\imconfig.h">
+      <Filter>imgui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\imgui.h">
+      <Filter>imgui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\imgui_internal.h">
+      <Filter>imgui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\imgui_impl_dx11.h">
+      <Filter>sources</Filter>
+    </ClInclude>
+    <ClInclude Include="..\imgui_impl_sdl.h">
+      <Filter>sources</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\imgui.cpp">
+      <Filter>imgui</Filter>
+    </ClCompile>
+    <ClCompile Include="main.cpp">
+      <Filter>sources</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\imgui_demo.cpp">
+      <Filter>imgui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\imgui_draw.cpp">
+      <Filter>imgui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\imgui_impl_dx11.cpp">
+      <Filter>sources</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\imgui_widgets.cpp">
+      <Filter>imgui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\imgui_impl_sdl.cpp">
+      <Filter>sources</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\README.txt" />
+    <None Include="..\..\misc\natvis\imgui.natvis">
+      <Filter>sources</Filter>
+    </None>
+  </ItemGroup>
 </Project>

+ 1 - 1
examples/imgui_impl_dx11.cpp

@@ -576,7 +576,7 @@ static void ImGui_ImplDX11_CreateWindow(ImGuiViewport* viewport)
 
     // PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
     // Some back-end will leave PlatformHandleRaw NULL, in which case we assume PlatformHandle will contain the HWND.
-    HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
+    HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
     IM_ASSERT(hwnd != 0);
 
     // Create swap chain

+ 636 - 636
examples/libs/usynergy/uSynergy.c

@@ -1,636 +1,636 @@
-/*
-uSynergy client -- Implementation for the embedded Synergy client library
-  version 1.0.0, July 7th, 2012
-
-Copyright (c) 2012 Alex Evans
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of 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. The origin of this software must not be misrepresented; you must not
-   claim that you wrote the original software. If you use this software
-   in a product, an acknowledgment in the product documentation would be
-   appreciated but is not required.
-
-   2. Altered source versions must be plainly marked as such, and must not be
-   misrepresented as being the original software.
-
-   3. This notice may not be removed or altered from any source
-   distribution.
-*/
-#include "uSynergy.h"
-#include <stdio.h>
-#include <string.h>
-
-
-
-//---------------------------------------------------------------------------------------------------------------------
-//	Internal helpers
-//---------------------------------------------------------------------------------------------------------------------
-
-
-
-/**
-@brief Read 16 bit integer in network byte order and convert to native byte order
-**/
-static int16_t sNetToNative16(const unsigned char *value)
-{
-#ifdef USYNERGY_LITTLE_ENDIAN
-	return value[1] | (value[0] << 8);
-#else
-	return value[0] | (value[1] << 8);
-#endif
-}
-
-
-
-/**
-@brief Read 32 bit integer in network byte order and convert to native byte order
-**/
-static int32_t sNetToNative32(const unsigned char *value)
-{
-#ifdef USYNERGY_LITTLE_ENDIAN
-	return value[3] | (value[2] << 8) | (value[1] << 16) | (value[0] << 24);
-#else
-	return value[0] | (value[1] << 8) | (value[2] << 16) | (value[3] << 24);
-#endif
-}
-
-
-
-/**
-@brief Trace text to client
-**/
-static void sTrace(uSynergyContext *context, const char* text)
-{
-	// Don't trace if we don't have a trace function
-	if (context->m_traceFunc != 0L)
-		context->m_traceFunc(context->m_cookie, text);
-}
-
-
-
-/**
-@brief Add string to reply packet
-**/
-static void sAddString(uSynergyContext *context, const char *string)
-{
-	size_t len = strlen(string);
-	memcpy(context->m_replyCur, string, len);
-	context->m_replyCur += len;
-}
-
-
-
-/**
-@brief Add uint8 to reply packet
-**/
-static void sAddUInt8(uSynergyContext *context, uint8_t value)
-{
-	*context->m_replyCur++ = value;
-}
-
-
-
-/**
-@brief Add uint16 to reply packet
-**/
-static void sAddUInt16(uSynergyContext *context, uint16_t value)
-{
-	uint8_t *reply = context->m_replyCur;
-	*reply++ = (uint8_t)(value >> 8);
-	*reply++ = (uint8_t)value;
-	context->m_replyCur = reply;
-}
-
-
-
-/**
-@brief Add uint32 to reply packet
-**/
-static void sAddUInt32(uSynergyContext *context, uint32_t value)
-{
-	uint8_t *reply = context->m_replyCur;
-	*reply++ = (uint8_t)(value >> 24);
-	*reply++ = (uint8_t)(value >> 16);
-	*reply++ = (uint8_t)(value >> 8);
-	*reply++ = (uint8_t)value;
-	context->m_replyCur = reply;
-}
-
-
-
-/**
-@brief Send reply packet
-**/
-static uSynergyBool sSendReply(uSynergyContext *context)
-{
-	// Set header size
-	uint8_t		*reply_buf	= context->m_replyBuffer;
-	uint32_t	reply_len	= (uint32_t)(context->m_replyCur - reply_buf);				/* Total size of reply */
-	uint32_t	body_len	= reply_len - 4;											/* Size of body */
-	uSynergyBool ret;
-	reply_buf[0] = (uint8_t)(body_len >> 24);
-	reply_buf[1] = (uint8_t)(body_len >> 16);
-	reply_buf[2] = (uint8_t)(body_len >> 8);
-	reply_buf[3] = (uint8_t)body_len;
-
-	// Send reply
-	ret = context->m_sendFunc(context->m_cookie, context->m_replyBuffer, reply_len);
-
-	// Reset reply buffer write pointer
-	context->m_replyCur = context->m_replyBuffer+4;
-	return ret;
-}
-
-
-
-/**
-@brief Call mouse callback after a mouse event
-**/
-static void sSendMouseCallback(uSynergyContext *context)
-{
-	// Skip if no callback is installed
-	if (context->m_mouseCallback == 0L)
-		return;
-
-	// Send callback
-	context->m_mouseCallback(context->m_cookie, context->m_mouseX, context->m_mouseY, context->m_mouseWheelX,
-		context->m_mouseWheelY, context->m_mouseButtonLeft, context->m_mouseButtonRight, context->m_mouseButtonMiddle);
-}
-
-
-
-/**
-@brief Send keyboard callback when a key has been pressed or released
-**/
-static void sSendKeyboardCallback(uSynergyContext *context, uint16_t key, uint16_t modifiers, uSynergyBool down, uSynergyBool repeat)
-{
-	// Skip if no callback is installed
-	if (context->m_keyboardCallback == 0L)
-		return;
-
-	// Send callback
-	context->m_keyboardCallback(context->m_cookie, key, modifiers, down, repeat);
-}
-
-
-
-/**
-@brief Send joystick callback
-**/
-static void sSendJoystickCallback(uSynergyContext *context, uint8_t joyNum)
-{
-	int8_t *sticks;
-
-	// Skip if no callback is installed
-	if (context->m_joystickCallback == 0L)
-		return;
-
-	// Send callback
-	sticks = context->m_joystickSticks[joyNum];
-	context->m_joystickCallback(context->m_cookie, joyNum, context->m_joystickButtons[joyNum], sticks[0], sticks[1], sticks[2], sticks[3]);
-}
-
-
-
-/**
-@brief Parse a single client message, update state, send callbacks and send replies
-**/
-#define USYNERGY_IS_PACKET(pkt_id)	memcmp(message+4, pkt_id, 4)==0
-static void sProcessMessage(uSynergyContext *context, const uint8_t *message)
-{
-	// We have a packet!
-	if (memcmp(message+4, "Synergy", 7)==0)
-	{
-		// Welcome message
-		//		kMsgHello			= "Synergy%2i%2i"
-		//		kMsgHelloBack		= "Synergy%2i%2i%s"
-		sAddString(context, "Synergy");
-		sAddUInt16(context, USYNERGY_PROTOCOL_MAJOR);
-		sAddUInt16(context, USYNERGY_PROTOCOL_MINOR);
-		sAddUInt32(context, (uint32_t)strlen(context->m_clientName));
-		sAddString(context, context->m_clientName);
-		if (!sSendReply(context))
-		{
-			// Send reply failed, let's try to reconnect
-			sTrace(context, "SendReply failed, trying to reconnect in a second");
-			context->m_connected = USYNERGY_FALSE;
-			context->m_sleepFunc(context->m_cookie, 1000);
-		}
-		else
-		{
-			// Let's assume we're connected
-			char buffer[256+1];
-			sprintf(buffer, "Connected as client \"%s\"", context->m_clientName);
-			sTrace(context, buffer);
-			context->m_hasReceivedHello = USYNERGY_TRUE;
-		}
-		return;
-	}
-	else if (USYNERGY_IS_PACKET("QINF"))
-	{
-		// Screen info. Reply with DINF
-		//		kMsgQInfo			= "QINF"
-		//		kMsgDInfo			= "DINF%2i%2i%2i%2i%2i%2i%2i"
-		uint16_t x = 0, y = 0, warp = 0;
-		sAddString(context, "DINF");
-		sAddUInt16(context, x);
-		sAddUInt16(context, y);
-		sAddUInt16(context, context->m_clientWidth);
-		sAddUInt16(context, context->m_clientHeight);
-		sAddUInt16(context, warp);
-		sAddUInt16(context, 0);		// mx?
-		sAddUInt16(context, 0);		// my?
-		sSendReply(context);
-		return;
-	}
-	else if (USYNERGY_IS_PACKET("CIAK"))
-	{
-		// Do nothing?
-		//		kMsgCInfoAck		= "CIAK"
-		return;
-	}
-	else if (USYNERGY_IS_PACKET("CROP"))
-	{
-		// Do nothing?
-		//		kMsgCResetOptions	= "CROP"
-		return;
-	}
-	else if (USYNERGY_IS_PACKET("CINN"))
-	{
-		// Screen enter. Reply with CNOP
-		//		kMsgCEnter 			= "CINN%2i%2i%4i%2i"
-
-		// Obtain the Synergy sequence number
-		context->m_sequenceNumber = sNetToNative32(message + 12);
-		context->m_isCaptured = USYNERGY_TRUE;
-
-		// Call callback
-		if (context->m_screenActiveCallback != 0L)
-			context->m_screenActiveCallback(context->m_cookie, USYNERGY_TRUE);
-	}
-	else if (USYNERGY_IS_PACKET("COUT"))
-	{
-		// Screen leave
-		//		kMsgCLeave 			= "COUT"
-		context->m_isCaptured = USYNERGY_FALSE;
-
-		// Call callback
-		if (context->m_screenActiveCallback != 0L)
-			context->m_screenActiveCallback(context->m_cookie, USYNERGY_FALSE);
-	}
-	else if (USYNERGY_IS_PACKET("DMDN"))
-	{
-		// Mouse down
-		//		kMsgDMouseDown		= "DMDN%1i"
-		char btn = message[8]-1;
-		if (btn==2)
-			context->m_mouseButtonRight		= USYNERGY_TRUE;
-		else if (btn==1)
-			context->m_mouseButtonMiddle	= USYNERGY_TRUE;
-		else
-			context->m_mouseButtonLeft		= USYNERGY_TRUE;
-		sSendMouseCallback(context);
-	}
-	else if (USYNERGY_IS_PACKET("DMUP"))
-	{
-		// Mouse up
-		//		kMsgDMouseUp		= "DMUP%1i"
-		char btn = message[8]-1;
-		if (btn==2)
-			context->m_mouseButtonRight		= USYNERGY_FALSE;
-		else if (btn==1)
-			context->m_mouseButtonMiddle	= USYNERGY_FALSE;
-		else
-			context->m_mouseButtonLeft		= USYNERGY_FALSE;
-		sSendMouseCallback(context);
-	}
-	else if (USYNERGY_IS_PACKET("DMMV"))
-	{
-		// Mouse move. Reply with CNOP
-		//		kMsgDMouseMove		= "DMMV%2i%2i"
-		context->m_mouseX = sNetToNative16(message+8);
-		context->m_mouseY = sNetToNative16(message+10);
-		sSendMouseCallback(context);
-	}
-	else if (USYNERGY_IS_PACKET("DMWM"))
-	{
-		// Mouse wheel
-		//		kMsgDMouseWheel		= "DMWM%2i%2i"
-		//		kMsgDMouseWheel1_0	= "DMWM%2i"
-		context->m_mouseWheelX += sNetToNative16(message+8);
-		context->m_mouseWheelY += sNetToNative16(message+10);
-		sSendMouseCallback(context);
-	}
-	else if (USYNERGY_IS_PACKET("DKDN"))
-	{
-		// Key down
-		//		kMsgDKeyDown		= "DKDN%2i%2i%2i"
-		//		kMsgDKeyDown1_0		= "DKDN%2i%2i"
-		//uint16_t id = sNetToNative16(message+8);
-		uint16_t mod = sNetToNative16(message+10);
-		uint16_t key = sNetToNative16(message+12);
-		sSendKeyboardCallback(context, key, mod, USYNERGY_TRUE, USYNERGY_FALSE);
-	}
-	else if (USYNERGY_IS_PACKET("DKRP"))
-	{
-		// Key repeat
-		//		kMsgDKeyRepeat		= "DKRP%2i%2i%2i%2i"
-		//		kMsgDKeyRepeat1_0	= "DKRP%2i%2i%2i"
-		uint16_t mod = sNetToNative16(message+10);
-//		uint16_t count = sNetToNative16(message+12);
-		uint16_t key = sNetToNative16(message+14);
-		sSendKeyboardCallback(context, key, mod, USYNERGY_TRUE, USYNERGY_TRUE);
-	}
-	else if (USYNERGY_IS_PACKET("DKUP"))
-	{
-		// Key up
-		//		kMsgDKeyUp			= "DKUP%2i%2i%2i"
-		//		kMsgDKeyUp1_0		= "DKUP%2i%2i"
-		//uint16 id=Endian::sNetToNative(sbuf[4]);
-		uint16_t mod = sNetToNative16(message+10);
-		uint16_t key = sNetToNative16(message+12);
-		sSendKeyboardCallback(context, key, mod, USYNERGY_FALSE, USYNERGY_FALSE);
-	}
-	else if (USYNERGY_IS_PACKET("DGBT"))
-	{
-		// Joystick buttons
-		//		kMsgDGameButtons	= "DGBT%1i%2i";
-		uint8_t	joy_num = message[8];
-		if (joy_num<USYNERGY_NUM_JOYSTICKS)
-		{
-			// Copy button state, then send callback
-			context->m_joystickButtons[joy_num] = (message[9] << 8) | message[10];
-			sSendJoystickCallback(context, joy_num);
-		}
-	}
-	else if (USYNERGY_IS_PACKET("DGST"))
-	{
-		// Joystick sticks
-		//		kMsgDGameSticks		= "DGST%1i%1i%1i%1i%1i";
-		uint8_t	joy_num = message[8];
-		if (joy_num<USYNERGY_NUM_JOYSTICKS)
-		{
-			// Copy stick state, then send callback
-			memcpy(context->m_joystickSticks[joy_num], message+9, 4);
-			sSendJoystickCallback(context, joy_num);
-		}
-	}
-	else if (USYNERGY_IS_PACKET("DSOP"))
-	{
-		// Set options
-		//		kMsgDSetOptions		= "DSOP%4I"
-	}
-	else if (USYNERGY_IS_PACKET("CALV"))
-	{
-		// Keepalive, reply with CALV and then CNOP
-		//		kMsgCKeepAlive		= "CALV"
-		sAddString(context, "CALV");
-		sSendReply(context);
-		// now reply with CNOP
-	}
-	else if (USYNERGY_IS_PACKET("DCLP"))
-	{
-		// Clipboard message
-		//		kMsgDClipboard		= "DCLP%1i%4i%s"
-		//
-		// The clipboard message contains:
-		//		1 uint32:	The size of the message
-		//		4 chars: 	The identifier ("DCLP")
-		//		1 uint8: 	The clipboard index
-		//		1 uint32:	The sequence number. It's zero, because this message is always coming from the server?
-		//		1 uint32:	The total size of the remaining 'string' (as per the Synergy %s string format (which is 1 uint32 for size followed by a char buffer (not necessarily null terminated)).
-		//		1 uint32:	The number of formats present in the message
-		// And then 'number of formats' times the following:
-		//		1 uint32:	The format of the clipboard data
-		//		1 uint32:	The size n of the clipboard data
-		//		n uint8:	The clipboard data
-		const uint8_t *	parse_msg	= message+17;
-		uint32_t		num_formats = sNetToNative32(parse_msg);
-		parse_msg += 4;
-		for (; num_formats; num_formats--)
-		{
-			// Parse clipboard format header
-			uint32_t format	= sNetToNative32(parse_msg);
-			uint32_t size	= sNetToNative32(parse_msg+4);
-			parse_msg += 8;
-			
-			// Call callback
-			if (context->m_clipboardCallback)
-				context->m_clipboardCallback(context->m_cookie, format, parse_msg, size);
-
-			parse_msg += size;
-		}
-	}
-	else
-	{
-		// Unknown packet, could be any of these
-		//		kMsgCNoop 			= "CNOP"
-		//		kMsgCClose 			= "CBYE"
-		//		kMsgCClipboard 		= "CCLP%1i%4i"
-		//		kMsgCScreenSaver 	= "CSEC%1i"
-		//		kMsgDKeyRepeat		= "DKRP%2i%2i%2i%2i"
-		//		kMsgDKeyRepeat1_0	= "DKRP%2i%2i%2i"
-		//		kMsgDMouseRelMove	= "DMRM%2i%2i"
-		//		kMsgEIncompatible	= "EICV%2i%2i"
-		//		kMsgEBusy 			= "EBSY"
-		//		kMsgEUnknown		= "EUNK"
-		//		kMsgEBad			= "EBAD"
-		char buffer[64];
-		sprintf(buffer, "Unknown packet '%c%c%c%c'", message[4], message[5], message[6], message[7]);
-		sTrace(context, buffer);
-		return;
-	}
-
-	// Reply with CNOP maybe?
-	sAddString(context, "CNOP");
-	sSendReply(context);
-}
-#undef USYNERGY_IS_PACKET
-
-
-
-/**
-@brief Mark context as being disconnected
-**/
-static void sSetDisconnected(uSynergyContext *context)
-{
-	context->m_connected		= USYNERGY_FALSE;
-	context->m_hasReceivedHello = USYNERGY_FALSE;
-	context->m_isCaptured		= USYNERGY_FALSE;
-	context->m_replyCur			= context->m_replyBuffer + 4;
-	context->m_sequenceNumber	= 0;
-}
-
-
-
-/**
-@brief Update a connected context
-**/
-static void sUpdateContext(uSynergyContext *context)
-{
-	/* Receive data (blocking) */
-	int receive_size = USYNERGY_RECEIVE_BUFFER_SIZE - context->m_receiveOfs;
-	int num_received = 0;
-	int packlen = 0;
-	if (context->m_receiveFunc(context->m_cookie, context->m_receiveBuffer + context->m_receiveOfs, receive_size, &num_received) == USYNERGY_FALSE)
-	{
-		/* Receive failed, let's try to reconnect */
-		char buffer[128];
-		sprintf(buffer, "Receive failed (%d bytes asked, %d bytes received), trying to reconnect in a second", receive_size, num_received);
-		sTrace(context, buffer);
-		sSetDisconnected(context);
-		context->m_sleepFunc(context->m_cookie, 1000);
-		return;
-	}
-	context->m_receiveOfs += num_received;
-
-	/*	If we didn't receive any data then we're probably still polling to get connected and
-		therefore not getting any data back. To avoid overloading the system with a Synergy
-		thread that would hammer on polling, we let it rest for a bit if there's no data. */
-	if (num_received == 0)
-		context->m_sleepFunc(context->m_cookie, 500);
-
-	/* Check for timeouts */
-	if (context->m_hasReceivedHello)
-	{
-		uint32_t cur_time = context->m_getTimeFunc();
-		if (num_received == 0)
-		{
-			/* Timeout after 2 secs of inactivity (we received no CALV) */
-			if ((cur_time - context->m_lastMessageTime) > USYNERGY_IDLE_TIMEOUT)
-				sSetDisconnected(context);
-		}
-		else
-			context->m_lastMessageTime = cur_time;
-	}
-
-	/* Eat packets */
-	for (;;)
-	{
-		/* Grab packet length and bail out if the packet goes beyond the end of the buffer */
-		packlen = sNetToNative32(context->m_receiveBuffer);
-		if (packlen+4 > context->m_receiveOfs)
-			break;
-
-		/* Process message */
-		sProcessMessage(context, context->m_receiveBuffer);
-
-		/* Move packet to front of buffer */
-		memmove(context->m_receiveBuffer, context->m_receiveBuffer+packlen+4, context->m_receiveOfs-packlen-4);
-		context->m_receiveOfs -= packlen+4;
-	}
-
-	/* Throw away over-sized packets */
-	if (packlen > USYNERGY_RECEIVE_BUFFER_SIZE)
-	{
-		/* Oversized packet, ditch tail end */
-		char buffer[128];
-		sprintf(buffer, "Oversized packet: '%c%c%c%c' (length %d)", context->m_receiveBuffer[4], context->m_receiveBuffer[5], context->m_receiveBuffer[6], context->m_receiveBuffer[7], packlen);
-		sTrace(context, buffer);
-		num_received = context->m_receiveOfs-4; // 4 bytes for the size field
-		while (num_received != packlen)
-		{
-			int buffer_left = packlen - num_received;
-			int to_receive = buffer_left < USYNERGY_RECEIVE_BUFFER_SIZE ? buffer_left : USYNERGY_RECEIVE_BUFFER_SIZE;
-			int ditch_received = 0;
-			if (context->m_receiveFunc(context->m_cookie, context->m_receiveBuffer, to_receive, &ditch_received) == USYNERGY_FALSE)
-			{
-				/* Receive failed, let's try to reconnect */
-				sTrace(context, "Receive failed, trying to reconnect in a second");
-				sSetDisconnected(context);
-				context->m_sleepFunc(context->m_cookie, 1000);
-				break;
-			}
-			else
-			{
-				num_received += ditch_received;
-			}
-		}
-		context->m_receiveOfs = 0;
-	}
-}
-
-
-//---------------------------------------------------------------------------------------------------------------------
-//	Public interface
-//---------------------------------------------------------------------------------------------------------------------
-
-
-
-/**
-@brief Initialize uSynergy context
-**/
-void uSynergyInit(uSynergyContext *context)
-{
-	/* Zero memory */
-	memset(context, 0, sizeof(uSynergyContext));
-
-	/* Initialize to default state */
-	sSetDisconnected(context);
-}
-
-
-/**
-@brief Update uSynergy
-**/
-void uSynergyUpdate(uSynergyContext *context)
-{
-	if (context->m_connected)
-	{
-		/* Update context, receive data, call callbacks */
-		sUpdateContext(context);
-	}
-	else
-	{
-		/* Try to connect */
-		if (context->m_connectFunc(context->m_cookie))
-			context->m_connected = USYNERGY_TRUE;
-	}
-}
-
-
-
-/**
-@brief Send clipboard data
-**/
-void uSynergySendClipboard(uSynergyContext *context, const char *text)
-{
-	// Calculate maximum size that will fit in a reply packet
-	uint32_t overhead_size =	4 +					/* Message size */
-								4 +					/* Message ID */
-								1 +					/* Clipboard index */
-								4 +					/* Sequence number */
-								4 +					/* Rest of message size (because it's a Synergy string from here on) */
-								4 +					/* Number of clipboard formats */
-								4 +					/* Clipboard format */
-								4;					/* Clipboard data length */
-	uint32_t max_length = USYNERGY_REPLY_BUFFER_SIZE - overhead_size;
-	
-	// Clip text to max length
-	uint32_t text_length = (uint32_t)strlen(text);
-	if (text_length > max_length)
-	{
-		char buffer[128];
-		sprintf(buffer, "Clipboard buffer too small, clipboard truncated at %d characters", max_length);
-		sTrace(context, buffer);
-		text_length = max_length;
-	}
-
-	// Assemble packet
-	sAddString(context, "DCLP");
-	sAddUInt8(context, 0);							/* Clipboard index */
-	sAddUInt32(context, context->m_sequenceNumber);
-	sAddUInt32(context, 4+4+4+text_length);			/* Rest of message size: numFormats, format, length, data */
-	sAddUInt32(context, 1);							/* Number of formats (only text for now) */
-	sAddUInt32(context, USYNERGY_CLIPBOARD_FORMAT_TEXT);
-	sAddUInt32(context, text_length);
-	sAddString(context, text);
-	sSendReply(context);
-}
+/*
+uSynergy client -- Implementation for the embedded Synergy client library
+  version 1.0.0, July 7th, 2012
+
+Copyright (c) 2012 Alex Evans
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of 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. The origin of this software must not be misrepresented; you must not
+   claim that you wrote the original software. If you use this software
+   in a product, an acknowledgment in the product documentation would be
+   appreciated but is not required.
+
+   2. Altered source versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+   3. This notice may not be removed or altered from any source
+   distribution.
+*/
+#include "uSynergy.h"
+#include <stdio.h>
+#include <string.h>
+
+
+
+//---------------------------------------------------------------------------------------------------------------------
+//	Internal helpers
+//---------------------------------------------------------------------------------------------------------------------
+
+
+
+/**
+@brief Read 16 bit integer in network byte order and convert to native byte order
+**/
+static int16_t sNetToNative16(const unsigned char *value)
+{
+#ifdef USYNERGY_LITTLE_ENDIAN
+	return value[1] | (value[0] << 8);
+#else
+	return value[0] | (value[1] << 8);
+#endif
+}
+
+
+
+/**
+@brief Read 32 bit integer in network byte order and convert to native byte order
+**/
+static int32_t sNetToNative32(const unsigned char *value)
+{
+#ifdef USYNERGY_LITTLE_ENDIAN
+	return value[3] | (value[2] << 8) | (value[1] << 16) | (value[0] << 24);
+#else
+	return value[0] | (value[1] << 8) | (value[2] << 16) | (value[3] << 24);
+#endif
+}
+
+
+
+/**
+@brief Trace text to client
+**/
+static void sTrace(uSynergyContext *context, const char* text)
+{
+	// Don't trace if we don't have a trace function
+	if (context->m_traceFunc != 0L)
+		context->m_traceFunc(context->m_cookie, text);
+}
+
+
+
+/**
+@brief Add string to reply packet
+**/
+static void sAddString(uSynergyContext *context, const char *string)
+{
+	size_t len = strlen(string);
+	memcpy(context->m_replyCur, string, len);
+	context->m_replyCur += len;
+}
+
+
+
+/**
+@brief Add uint8 to reply packet
+**/
+static void sAddUInt8(uSynergyContext *context, uint8_t value)
+{
+	*context->m_replyCur++ = value;
+}
+
+
+
+/**
+@brief Add uint16 to reply packet
+**/
+static void sAddUInt16(uSynergyContext *context, uint16_t value)
+{
+	uint8_t *reply = context->m_replyCur;
+	*reply++ = (uint8_t)(value >> 8);
+	*reply++ = (uint8_t)value;
+	context->m_replyCur = reply;
+}
+
+
+
+/**
+@brief Add uint32 to reply packet
+**/
+static void sAddUInt32(uSynergyContext *context, uint32_t value)
+{
+	uint8_t *reply = context->m_replyCur;
+	*reply++ = (uint8_t)(value >> 24);
+	*reply++ = (uint8_t)(value >> 16);
+	*reply++ = (uint8_t)(value >> 8);
+	*reply++ = (uint8_t)value;
+	context->m_replyCur = reply;
+}
+
+
+
+/**
+@brief Send reply packet
+**/
+static uSynergyBool sSendReply(uSynergyContext *context)
+{
+	// Set header size
+	uint8_t		*reply_buf	= context->m_replyBuffer;
+	uint32_t	reply_len	= (uint32_t)(context->m_replyCur - reply_buf);				/* Total size of reply */
+	uint32_t	body_len	= reply_len - 4;											/* Size of body */
+	uSynergyBool ret;
+	reply_buf[0] = (uint8_t)(body_len >> 24);
+	reply_buf[1] = (uint8_t)(body_len >> 16);
+	reply_buf[2] = (uint8_t)(body_len >> 8);
+	reply_buf[3] = (uint8_t)body_len;
+
+	// Send reply
+	ret = context->m_sendFunc(context->m_cookie, context->m_replyBuffer, reply_len);
+
+	// Reset reply buffer write pointer
+	context->m_replyCur = context->m_replyBuffer+4;
+	return ret;
+}
+
+
+
+/**
+@brief Call mouse callback after a mouse event
+**/
+static void sSendMouseCallback(uSynergyContext *context)
+{
+	// Skip if no callback is installed
+	if (context->m_mouseCallback == 0L)
+		return;
+
+	// Send callback
+	context->m_mouseCallback(context->m_cookie, context->m_mouseX, context->m_mouseY, context->m_mouseWheelX,
+		context->m_mouseWheelY, context->m_mouseButtonLeft, context->m_mouseButtonRight, context->m_mouseButtonMiddle);
+}
+
+
+
+/**
+@brief Send keyboard callback when a key has been pressed or released
+**/
+static void sSendKeyboardCallback(uSynergyContext *context, uint16_t key, uint16_t modifiers, uSynergyBool down, uSynergyBool repeat)
+{
+	// Skip if no callback is installed
+	if (context->m_keyboardCallback == 0L)
+		return;
+
+	// Send callback
+	context->m_keyboardCallback(context->m_cookie, key, modifiers, down, repeat);
+}
+
+
+
+/**
+@brief Send joystick callback
+**/
+static void sSendJoystickCallback(uSynergyContext *context, uint8_t joyNum)
+{
+	int8_t *sticks;
+
+	// Skip if no callback is installed
+	if (context->m_joystickCallback == 0L)
+		return;
+
+	// Send callback
+	sticks = context->m_joystickSticks[joyNum];
+	context->m_joystickCallback(context->m_cookie, joyNum, context->m_joystickButtons[joyNum], sticks[0], sticks[1], sticks[2], sticks[3]);
+}
+
+
+
+/**
+@brief Parse a single client message, update state, send callbacks and send replies
+**/
+#define USYNERGY_IS_PACKET(pkt_id)	memcmp(message+4, pkt_id, 4)==0
+static void sProcessMessage(uSynergyContext *context, const uint8_t *message)
+{
+	// We have a packet!
+	if (memcmp(message+4, "Synergy", 7)==0)
+	{
+		// Welcome message
+		//		kMsgHello			= "Synergy%2i%2i"
+		//		kMsgHelloBack		= "Synergy%2i%2i%s"
+		sAddString(context, "Synergy");
+		sAddUInt16(context, USYNERGY_PROTOCOL_MAJOR);
+		sAddUInt16(context, USYNERGY_PROTOCOL_MINOR);
+		sAddUInt32(context, (uint32_t)strlen(context->m_clientName));
+		sAddString(context, context->m_clientName);
+		if (!sSendReply(context))
+		{
+			// Send reply failed, let's try to reconnect
+			sTrace(context, "SendReply failed, trying to reconnect in a second");
+			context->m_connected = USYNERGY_FALSE;
+			context->m_sleepFunc(context->m_cookie, 1000);
+		}
+		else
+		{
+			// Let's assume we're connected
+			char buffer[256+1];
+			sprintf(buffer, "Connected as client \"%s\"", context->m_clientName);
+			sTrace(context, buffer);
+			context->m_hasReceivedHello = USYNERGY_TRUE;
+		}
+		return;
+	}
+	else if (USYNERGY_IS_PACKET("QINF"))
+	{
+		// Screen info. Reply with DINF
+		//		kMsgQInfo			= "QINF"
+		//		kMsgDInfo			= "DINF%2i%2i%2i%2i%2i%2i%2i"
+		uint16_t x = 0, y = 0, warp = 0;
+		sAddString(context, "DINF");
+		sAddUInt16(context, x);
+		sAddUInt16(context, y);
+		sAddUInt16(context, context->m_clientWidth);
+		sAddUInt16(context, context->m_clientHeight);
+		sAddUInt16(context, warp);
+		sAddUInt16(context, 0);		// mx?
+		sAddUInt16(context, 0);		// my?
+		sSendReply(context);
+		return;
+	}
+	else if (USYNERGY_IS_PACKET("CIAK"))
+	{
+		// Do nothing?
+		//		kMsgCInfoAck		= "CIAK"
+		return;
+	}
+	else if (USYNERGY_IS_PACKET("CROP"))
+	{
+		// Do nothing?
+		//		kMsgCResetOptions	= "CROP"
+		return;
+	}
+	else if (USYNERGY_IS_PACKET("CINN"))
+	{
+		// Screen enter. Reply with CNOP
+		//		kMsgCEnter 			= "CINN%2i%2i%4i%2i"
+
+		// Obtain the Synergy sequence number
+		context->m_sequenceNumber = sNetToNative32(message + 12);
+		context->m_isCaptured = USYNERGY_TRUE;
+
+		// Call callback
+		if (context->m_screenActiveCallback != 0L)
+			context->m_screenActiveCallback(context->m_cookie, USYNERGY_TRUE);
+	}
+	else if (USYNERGY_IS_PACKET("COUT"))
+	{
+		// Screen leave
+		//		kMsgCLeave 			= "COUT"
+		context->m_isCaptured = USYNERGY_FALSE;
+
+		// Call callback
+		if (context->m_screenActiveCallback != 0L)
+			context->m_screenActiveCallback(context->m_cookie, USYNERGY_FALSE);
+	}
+	else if (USYNERGY_IS_PACKET("DMDN"))
+	{
+		// Mouse down
+		//		kMsgDMouseDown		= "DMDN%1i"
+		char btn = message[8]-1;
+		if (btn==2)
+			context->m_mouseButtonRight		= USYNERGY_TRUE;
+		else if (btn==1)
+			context->m_mouseButtonMiddle	= USYNERGY_TRUE;
+		else
+			context->m_mouseButtonLeft		= USYNERGY_TRUE;
+		sSendMouseCallback(context);
+	}
+	else if (USYNERGY_IS_PACKET("DMUP"))
+	{
+		// Mouse up
+		//		kMsgDMouseUp		= "DMUP%1i"
+		char btn = message[8]-1;
+		if (btn==2)
+			context->m_mouseButtonRight		= USYNERGY_FALSE;
+		else if (btn==1)
+			context->m_mouseButtonMiddle	= USYNERGY_FALSE;
+		else
+			context->m_mouseButtonLeft		= USYNERGY_FALSE;
+		sSendMouseCallback(context);
+	}
+	else if (USYNERGY_IS_PACKET("DMMV"))
+	{
+		// Mouse move. Reply with CNOP
+		//		kMsgDMouseMove		= "DMMV%2i%2i"
+		context->m_mouseX = sNetToNative16(message+8);
+		context->m_mouseY = sNetToNative16(message+10);
+		sSendMouseCallback(context);
+	}
+	else if (USYNERGY_IS_PACKET("DMWM"))
+	{
+		// Mouse wheel
+		//		kMsgDMouseWheel		= "DMWM%2i%2i"
+		//		kMsgDMouseWheel1_0	= "DMWM%2i"
+		context->m_mouseWheelX += sNetToNative16(message+8);
+		context->m_mouseWheelY += sNetToNative16(message+10);
+		sSendMouseCallback(context);
+	}
+	else if (USYNERGY_IS_PACKET("DKDN"))
+	{
+		// Key down
+		//		kMsgDKeyDown		= "DKDN%2i%2i%2i"
+		//		kMsgDKeyDown1_0		= "DKDN%2i%2i"
+		//uint16_t id = sNetToNative16(message+8);
+		uint16_t mod = sNetToNative16(message+10);
+		uint16_t key = sNetToNative16(message+12);
+		sSendKeyboardCallback(context, key, mod, USYNERGY_TRUE, USYNERGY_FALSE);
+	}
+	else if (USYNERGY_IS_PACKET("DKRP"))
+	{
+		// Key repeat
+		//		kMsgDKeyRepeat		= "DKRP%2i%2i%2i%2i"
+		//		kMsgDKeyRepeat1_0	= "DKRP%2i%2i%2i"
+		uint16_t mod = sNetToNative16(message+10);
+//		uint16_t count = sNetToNative16(message+12);
+		uint16_t key = sNetToNative16(message+14);
+		sSendKeyboardCallback(context, key, mod, USYNERGY_TRUE, USYNERGY_TRUE);
+	}
+	else if (USYNERGY_IS_PACKET("DKUP"))
+	{
+		// Key up
+		//		kMsgDKeyUp			= "DKUP%2i%2i%2i"
+		//		kMsgDKeyUp1_0		= "DKUP%2i%2i"
+		//uint16 id=Endian::sNetToNative(sbuf[4]);
+		uint16_t mod = sNetToNative16(message+10);
+		uint16_t key = sNetToNative16(message+12);
+		sSendKeyboardCallback(context, key, mod, USYNERGY_FALSE, USYNERGY_FALSE);
+	}
+	else if (USYNERGY_IS_PACKET("DGBT"))
+	{
+		// Joystick buttons
+		//		kMsgDGameButtons	= "DGBT%1i%2i";
+		uint8_t	joy_num = message[8];
+		if (joy_num<USYNERGY_NUM_JOYSTICKS)
+		{
+			// Copy button state, then send callback
+			context->m_joystickButtons[joy_num] = (message[9] << 8) | message[10];
+			sSendJoystickCallback(context, joy_num);
+		}
+	}
+	else if (USYNERGY_IS_PACKET("DGST"))
+	{
+		// Joystick sticks
+		//		kMsgDGameSticks		= "DGST%1i%1i%1i%1i%1i";
+		uint8_t	joy_num = message[8];
+		if (joy_num<USYNERGY_NUM_JOYSTICKS)
+		{
+			// Copy stick state, then send callback
+			memcpy(context->m_joystickSticks[joy_num], message+9, 4);
+			sSendJoystickCallback(context, joy_num);
+		}
+	}
+	else if (USYNERGY_IS_PACKET("DSOP"))
+	{
+		// Set options
+		//		kMsgDSetOptions		= "DSOP%4I"
+	}
+	else if (USYNERGY_IS_PACKET("CALV"))
+	{
+		// Keepalive, reply with CALV and then CNOP
+		//		kMsgCKeepAlive		= "CALV"
+		sAddString(context, "CALV");
+		sSendReply(context);
+		// now reply with CNOP
+	}
+	else if (USYNERGY_IS_PACKET("DCLP"))
+	{
+		// Clipboard message
+		//		kMsgDClipboard		= "DCLP%1i%4i%s"
+		//
+		// The clipboard message contains:
+		//		1 uint32:	The size of the message
+		//		4 chars: 	The identifier ("DCLP")
+		//		1 uint8: 	The clipboard index
+		//		1 uint32:	The sequence number. It's zero, because this message is always coming from the server?
+		//		1 uint32:	The total size of the remaining 'string' (as per the Synergy %s string format (which is 1 uint32 for size followed by a char buffer (not necessarily null terminated)).
+		//		1 uint32:	The number of formats present in the message
+		// And then 'number of formats' times the following:
+		//		1 uint32:	The format of the clipboard data
+		//		1 uint32:	The size n of the clipboard data
+		//		n uint8:	The clipboard data
+		const uint8_t *	parse_msg	= message+17;
+		uint32_t		num_formats = sNetToNative32(parse_msg);
+		parse_msg += 4;
+		for (; num_formats; num_formats--)
+		{
+			// Parse clipboard format header
+			uint32_t format	= sNetToNative32(parse_msg);
+			uint32_t size	= sNetToNative32(parse_msg+4);
+			parse_msg += 8;
+			
+			// Call callback
+			if (context->m_clipboardCallback)
+				context->m_clipboardCallback(context->m_cookie, format, parse_msg, size);
+
+			parse_msg += size;
+		}
+	}
+	else
+	{
+		// Unknown packet, could be any of these
+		//		kMsgCNoop 			= "CNOP"
+		//		kMsgCClose 			= "CBYE"
+		//		kMsgCClipboard 		= "CCLP%1i%4i"
+		//		kMsgCScreenSaver 	= "CSEC%1i"
+		//		kMsgDKeyRepeat		= "DKRP%2i%2i%2i%2i"
+		//		kMsgDKeyRepeat1_0	= "DKRP%2i%2i%2i"
+		//		kMsgDMouseRelMove	= "DMRM%2i%2i"
+		//		kMsgEIncompatible	= "EICV%2i%2i"
+		//		kMsgEBusy 			= "EBSY"
+		//		kMsgEUnknown		= "EUNK"
+		//		kMsgEBad			= "EBAD"
+		char buffer[64];
+		sprintf(buffer, "Unknown packet '%c%c%c%c'", message[4], message[5], message[6], message[7]);
+		sTrace(context, buffer);
+		return;
+	}
+
+	// Reply with CNOP maybe?
+	sAddString(context, "CNOP");
+	sSendReply(context);
+}
+#undef USYNERGY_IS_PACKET
+
+
+
+/**
+@brief Mark context as being disconnected
+**/
+static void sSetDisconnected(uSynergyContext *context)
+{
+	context->m_connected		= USYNERGY_FALSE;
+	context->m_hasReceivedHello = USYNERGY_FALSE;
+	context->m_isCaptured		= USYNERGY_FALSE;
+	context->m_replyCur			= context->m_replyBuffer + 4;
+	context->m_sequenceNumber	= 0;
+}
+
+
+
+/**
+@brief Update a connected context
+**/
+static void sUpdateContext(uSynergyContext *context)
+{
+	/* Receive data (blocking) */
+	int receive_size = USYNERGY_RECEIVE_BUFFER_SIZE - context->m_receiveOfs;
+	int num_received = 0;
+	int packlen = 0;
+	if (context->m_receiveFunc(context->m_cookie, context->m_receiveBuffer + context->m_receiveOfs, receive_size, &num_received) == USYNERGY_FALSE)
+	{
+		/* Receive failed, let's try to reconnect */
+		char buffer[128];
+		sprintf(buffer, "Receive failed (%d bytes asked, %d bytes received), trying to reconnect in a second", receive_size, num_received);
+		sTrace(context, buffer);
+		sSetDisconnected(context);
+		context->m_sleepFunc(context->m_cookie, 1000);
+		return;
+	}
+	context->m_receiveOfs += num_received;
+
+	/*	If we didn't receive any data then we're probably still polling to get connected and
+		therefore not getting any data back. To avoid overloading the system with a Synergy
+		thread that would hammer on polling, we let it rest for a bit if there's no data. */
+	if (num_received == 0)
+		context->m_sleepFunc(context->m_cookie, 500);
+
+	/* Check for timeouts */
+	if (context->m_hasReceivedHello)
+	{
+		uint32_t cur_time = context->m_getTimeFunc();
+		if (num_received == 0)
+		{
+			/* Timeout after 2 secs of inactivity (we received no CALV) */
+			if ((cur_time - context->m_lastMessageTime) > USYNERGY_IDLE_TIMEOUT)
+				sSetDisconnected(context);
+		}
+		else
+			context->m_lastMessageTime = cur_time;
+	}
+
+	/* Eat packets */
+	for (;;)
+	{
+		/* Grab packet length and bail out if the packet goes beyond the end of the buffer */
+		packlen = sNetToNative32(context->m_receiveBuffer);
+		if (packlen+4 > context->m_receiveOfs)
+			break;
+
+		/* Process message */
+		sProcessMessage(context, context->m_receiveBuffer);
+
+		/* Move packet to front of buffer */
+		memmove(context->m_receiveBuffer, context->m_receiveBuffer+packlen+4, context->m_receiveOfs-packlen-4);
+		context->m_receiveOfs -= packlen+4;
+	}
+
+	/* Throw away over-sized packets */
+	if (packlen > USYNERGY_RECEIVE_BUFFER_SIZE)
+	{
+		/* Oversized packet, ditch tail end */
+		char buffer[128];
+		sprintf(buffer, "Oversized packet: '%c%c%c%c' (length %d)", context->m_receiveBuffer[4], context->m_receiveBuffer[5], context->m_receiveBuffer[6], context->m_receiveBuffer[7], packlen);
+		sTrace(context, buffer);
+		num_received = context->m_receiveOfs-4; // 4 bytes for the size field
+		while (num_received != packlen)
+		{
+			int buffer_left = packlen - num_received;
+			int to_receive = buffer_left < USYNERGY_RECEIVE_BUFFER_SIZE ? buffer_left : USYNERGY_RECEIVE_BUFFER_SIZE;
+			int ditch_received = 0;
+			if (context->m_receiveFunc(context->m_cookie, context->m_receiveBuffer, to_receive, &ditch_received) == USYNERGY_FALSE)
+			{
+				/* Receive failed, let's try to reconnect */
+				sTrace(context, "Receive failed, trying to reconnect in a second");
+				sSetDisconnected(context);
+				context->m_sleepFunc(context->m_cookie, 1000);
+				break;
+			}
+			else
+			{
+				num_received += ditch_received;
+			}
+		}
+		context->m_receiveOfs = 0;
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------
+//	Public interface
+//---------------------------------------------------------------------------------------------------------------------
+
+
+
+/**
+@brief Initialize uSynergy context
+**/
+void uSynergyInit(uSynergyContext *context)
+{
+	/* Zero memory */
+	memset(context, 0, sizeof(uSynergyContext));
+
+	/* Initialize to default state */
+	sSetDisconnected(context);
+}
+
+
+/**
+@brief Update uSynergy
+**/
+void uSynergyUpdate(uSynergyContext *context)
+{
+	if (context->m_connected)
+	{
+		/* Update context, receive data, call callbacks */
+		sUpdateContext(context);
+	}
+	else
+	{
+		/* Try to connect */
+		if (context->m_connectFunc(context->m_cookie))
+			context->m_connected = USYNERGY_TRUE;
+	}
+}
+
+
+
+/**
+@brief Send clipboard data
+**/
+void uSynergySendClipboard(uSynergyContext *context, const char *text)
+{
+	// Calculate maximum size that will fit in a reply packet
+	uint32_t overhead_size =	4 +					/* Message size */
+								4 +					/* Message ID */
+								1 +					/* Clipboard index */
+								4 +					/* Sequence number */
+								4 +					/* Rest of message size (because it's a Synergy string from here on) */
+								4 +					/* Number of clipboard formats */
+								4 +					/* Clipboard format */
+								4;					/* Clipboard data length */
+	uint32_t max_length = USYNERGY_REPLY_BUFFER_SIZE - overhead_size;
+	
+	// Clip text to max length
+	uint32_t text_length = (uint32_t)strlen(text);
+	if (text_length > max_length)
+	{
+		char buffer[128];
+		sprintf(buffer, "Clipboard buffer too small, clipboard truncated at %d characters", max_length);
+		sTrace(context, buffer);
+		text_length = max_length;
+	}
+
+	// Assemble packet
+	sAddString(context, "DCLP");
+	sAddUInt8(context, 0);							/* Clipboard index */
+	sAddUInt32(context, context->m_sequenceNumber);
+	sAddUInt32(context, 4+4+4+text_length);			/* Rest of message size: numFormats, format, length, data */
+	sAddUInt32(context, 1);							/* Number of formats (only text for now) */
+	sAddUInt32(context, USYNERGY_CLIPBOARD_FORMAT_TEXT);
+	sAddUInt32(context, text_length);
+	sAddString(context, text);
+	sSendReply(context);
+}

+ 29 - 17
imgui.cpp

@@ -1407,7 +1407,7 @@ ImU32 ImHashStr(const char* data_p, size_t data_size, ImU32 seed)
 
 FILE* ImFileOpen(const char* filename, const char* mode)
 {
-#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__GNUC__)
+#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(__CYGWIN__) && !defined(__GNUC__)
     // We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames. Converting both strings from UTF-8 to wchar format (using a single allocation, because we can)
     const int filename_wsize = ImTextCountCharsFromUtf8(filename, NULL) + 1;
     const int mode_wsize = ImTextCountCharsFromUtf8(mode, NULL) + 1;
@@ -6289,14 +6289,14 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
         window->WorkRect.Max.x = window->WorkRect.Min.x + work_rect_size_x;
         window->WorkRect.Max.y = window->WorkRect.Min.y + work_rect_size_y;
 
-        // [LEGACY] Contents Region
-        // FIXME-OBSOLETE: window->ContentsRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it.
+        // [LEGACY] Content Region
+        // FIXME-OBSOLETE: window->ContentRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it.
         // Used by:
         // - Mouse wheel scrolling + many other things
-        window->ContentsRegionRect.Min.x = window->Pos.x - window->Scroll.x + window->WindowPadding.x;
-        window->ContentsRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + decoration_up_height;
-        window->ContentsRegionRect.Max.x = window->ContentsRegionRect.Min.x + (window->ContentSizeExplicit.x != 0.0f ? window->ContentSizeExplicit.x : (window->Size.x - window->WindowPadding.x * 2.0f - window->ScrollbarSizes.x));
-        window->ContentsRegionRect.Max.y = window->ContentsRegionRect.Min.y + (window->ContentSizeExplicit.y != 0.0f ? window->ContentSizeExplicit.y : (window->Size.y - window->WindowPadding.y * 2.0f - decoration_up_height - window->ScrollbarSizes.y));
+        window->ContentRegionRect.Min.x = window->Pos.x - window->Scroll.x + window->WindowPadding.x;
+        window->ContentRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + decoration_up_height;
+        window->ContentRegionRect.Max.x = window->ContentRegionRect.Min.x + (window->ContentSizeExplicit.x != 0.0f ? window->ContentSizeExplicit.x : (window->Size.x - window->WindowPadding.x * 2.0f - window->ScrollbarSizes.x));
+        window->ContentRegionRect.Max.y = window->ContentRegionRect.Min.y + (window->ContentSizeExplicit.y != 0.0f ? window->ContentSizeExplicit.y : (window->Size.y - window->WindowPadding.y * 2.0f - decoration_up_height - window->ScrollbarSizes.y));
 
         // Setup drawing context
         // (NB: That term "drawing context / DC" lost its meaning a long time ago. Initially was meant to hold transient data only. Nowadays difference between window-> and window->DC-> is dubious.)
@@ -7316,7 +7316,7 @@ ImVec2 ImGui::GetContentRegionMax()
 {
     ImGuiContext& g = *GImGui;
     ImGuiWindow* window = g.CurrentWindow;
-    ImVec2 mx = window->ContentsRegionRect.Max - window->Pos;
+    ImVec2 mx = window->ContentRegionRect.Max - window->Pos;
     if (window->DC.CurrentColumns)
         mx.x = window->WorkRect.Max.x - window->Pos.x;
     return mx;
@@ -7327,7 +7327,7 @@ ImVec2 ImGui::GetContentRegionMaxAbs()
 {
     ImGuiContext& g = *GImGui;
     ImGuiWindow* window = g.CurrentWindow;
-    ImVec2 mx = window->ContentsRegionRect.Max;
+    ImVec2 mx = window->ContentRegionRect.Max;
     if (window->DC.CurrentColumns)
         mx.x = window->WorkRect.Max.x;
     return mx;
@@ -7343,19 +7343,19 @@ ImVec2 ImGui::GetContentRegionAvail()
 ImVec2 ImGui::GetWindowContentRegionMin()
 {
     ImGuiWindow* window = GImGui->CurrentWindow;
-    return window->ContentsRegionRect.Min - window->Pos;
+    return window->ContentRegionRect.Min - window->Pos;
 }
 
 ImVec2 ImGui::GetWindowContentRegionMax()
 {
     ImGuiWindow* window = GImGui->CurrentWindow;
-    return window->ContentsRegionRect.Max - window->Pos;
+    return window->ContentRegionRect.Max - window->Pos;
 }
 
 float ImGui::GetWindowContentRegionWidth()
 {
     ImGuiWindow* window = GImGui->CurrentWindow;
-    return window->ContentsRegionRect.GetWidth();
+    return window->ContentRegionRect.GetWidth();
 }
 
 float ImGui::GetTextLineHeight()
@@ -14677,8 +14677,8 @@ void ImGui::ShowMetricsWindow(bool* p_open)
     }
 
     // State
-    enum { WRT_OuterRect, WRT_OuterRectClipped, WRT_InnerRect, WRT_InnerClipRect, WRT_WorkRect, WRT_Contents, WRT_ContentsRegionRect, WRT_Count }; // Windows Rect Type
-    const char* wrt_rects_names[WRT_Count] = { "OuterRect", "OuterRectClipped", "InnerRect", "InnerClipRect", "WorkRect", "Contents", "ContentsRegionRect" };
+    enum { WRT_OuterRect, WRT_OuterRectClipped, WRT_InnerRect, WRT_InnerClipRect, WRT_WorkRect, WRT_Content, WRT_ContentRegionRect, WRT_Count }; // Windows Rect Type
+    const char* wrt_rects_names[WRT_Count] = { "OuterRect", "OuterRectClipped", "InnerRect", "InnerClipRect", "WorkRect", "Content", "ContentRegionRect" };
     static bool show_windows_rects = false;
     static int  show_windows_rect_type = WRT_WorkRect;
     static bool show_windows_begin_order = false;
@@ -14712,8 +14712,8 @@ void ImGui::ShowMetricsWindow(bool* p_open)
             else if (rect_type == WRT_InnerRect)            { return window->InnerRect; }
             else if (rect_type == WRT_InnerClipRect)        { return window->InnerClipRect; }
             else if (rect_type == WRT_WorkRect)             { return window->WorkRect; }
-            else if (rect_type == WRT_Contents)             { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSize); }
-            else if (rect_type == WRT_ContentsRegionRect)   { return window->ContentsRegionRect; }
+            else if (rect_type == WRT_Content)              { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSize); }
+            else if (rect_type == WRT_ContentRegionRect)    { return window->ContentRegionRect; }
             IM_ASSERT(0);
             return ImRect();
         }
@@ -14846,7 +14846,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
                     NodeColumns(&window->ColumnsStorage[n]);
                 ImGui::TreePop();
             }
-            ImGui::BulletText("Storage: %d bytes", window->StateStorage.Data.size_in_bytes());
+            NodeStorage(&window->StateStorage, "Storage");
             ImGui::TreePop();
         }
 
@@ -14949,6 +14949,18 @@ void ImGui::ShowMetricsWindow(bool* p_open)
                 ImGui::TreePop();
             }
         }
+
+        static void NodeStorage(ImGuiStorage* storage, const char* label)
+        {
+            if (!ImGui::TreeNode(label, "%s: %d entries, %d bytes", label, storage->Data.Size, storage->Data.size_in_bytes()))
+                return;
+            for (int n = 0; n < storage->Data.Size; n++)
+            {
+                const ImGuiStorage::ImGuiStoragePair& p = storage->Data[n];
+                ImGui::BulletText("Key 0x%08X Value { i: %d }", p.key, p.val_i); // Important: we currently don't store a type, real value may not be integer.
+            }
+            ImGui::TreePop();
+        }
     };
 
     Funcs::NodeWindows(g.Windows, "Windows");

+ 5 - 5
imgui_internal.h

@@ -1515,9 +1515,9 @@ struct IMGUI_API ImGuiWindow
     ImRect                  OuterRectClipped;                   // == Window->Rect() just after setup in Begin(). == window->Rect() for root window.
     ImRect                  InnerRect;                          // Inner rectangle (omit title bar, menu bar, scroll bar)
     ImRect                  InnerClipRect;                      // == InnerRect shrunk by WindowPadding*0.5f on each side, clipped within viewport or parent clip rect.
-    ImRect                  WorkRect;                           // Cover the whole scrolling region, shrunk by WindowPadding*1.0f on each side. This is meant to replace ContentsRegionRect over time (from 1.71+ onward).
+    ImRect                  WorkRect;                           // Cover the whole scrolling region, shrunk by WindowPadding*1.0f on each side. This is meant to replace ContentRegionRect over time (from 1.71+ onward).
     ImRect                  ClipRect;                           // Current clipping/scissoring rectangle, evolve as we are using PushClipRect(), etc. == DrawList->clip_rect_stack.back().
-    ImRect                  ContentsRegionRect;                 // FIXME: This is currently confusing/misleading. It is essentially WorkRect but not handling of scrolling. We currently rely on it as right/bottom aligned sizing operation need some size to rely on.
+    ImRect                  ContentRegionRect;                  // FIXME: This is currently confusing/misleading. It is essentially WorkRect but not handling of scrolling. We currently rely on it as right/bottom aligned sizing operation need some size to rely on.
     ImVec2ih                HitTestHoleSize, HitTestHoleOffset;
 
     int                     LastFrameActive;                    // Last frame number the window was Active.
@@ -1607,7 +1607,7 @@ enum ImGuiTabBarFlagsPrivate_
 // Extend ImGuiTabItemFlags_
 enum ImGuiTabItemFlagsPrivate_
 {
-    ImGuiTabItemFlags_NoCloseButton             = 1 << 20,  // Store whether p_open is set or not, which we need to recompute WidthContents during layout.
+    ImGuiTabItemFlags_NoCloseButton             = 1 << 20,  // Store whether p_open is set or not, which we need to recompute ContentWidth during layout.
     ImGuiTabItemFlags_Unsorted                  = 1 << 21,  // [Docking] Trailing tabs with the _Unsorted flag will be sorted based on the DockOrder of their Window.
     ImGuiTabItemFlags_Preview                   = 1 << 22   // [Docking] Display tab shape for docking preview (height is adjusted slightly to compensate for the yet missing tab bar)
 };
@@ -1623,9 +1623,9 @@ struct ImGuiTabItem
     int                 NameOffset;             // When Window==NULL, offset to name within parent ImGuiTabBar::TabsNames
     float               Offset;                 // Position relative to beginning of tab
     float               Width;                  // Width currently displayed
-    float               WidthContents;          // Width of actual contents, stored during BeginTabItem() call
+    float               ContentWidth;           // Width of actual contents, stored during BeginTabItem() call
 
-    ImGuiTabItem()      { ID = Flags = 0; Window = NULL; LastFrameVisible = LastFrameSelected = -1; NameOffset = -1; Offset = Width = WidthContents = 0.0f; }
+    ImGuiTabItem()      { ID = Flags = 0; Window = NULL; LastFrameVisible = LastFrameSelected = -1; NameOffset = -1; Offset = Width = ContentWidth = 0.0f; }
 };
 
 // Storage for a tab bar (sizeof() 92~96 bytes)

+ 8 - 8
imgui_widgets.cpp

@@ -6585,13 +6585,13 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
         // and we cannot wait for the next BeginTabItem() call. We cannot compute this width within TabBarAddTab() because font size depends on the active window.
         const char* tab_name = tab_bar->GetTabName(tab);
         const bool has_close_button = tab->Window ? tab->Window->HasCloseButton : ((tab->Flags & ImGuiTabItemFlags_NoCloseButton) == 0);
-        tab->WidthContents = TabItemCalcSize(tab_name, has_close_button).x;
+        tab->ContentWidth = TabItemCalcSize(tab_name, has_close_button).x;
 
-        width_total_contents += (tab_n > 0 ? g.Style.ItemInnerSpacing.x : 0.0f) + tab->WidthContents;
+        width_total_contents += (tab_n > 0 ? g.Style.ItemInnerSpacing.x : 0.0f) + tab->ContentWidth;
 
         // Store data so we can build an array sorted by width if we need to shrink tabs down
         g.ShrinkWidthBuffer[tab_n].Index = tab_n;
-        g.ShrinkWidthBuffer[tab_n].Width = tab->WidthContents;
+        g.ShrinkWidthBuffer[tab_n].Width = tab->ContentWidth;
     }
 
     // Compute width
@@ -6611,7 +6611,7 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
         for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++)
         {
             ImGuiTabItem* tab = &tab_bar->Tabs[tab_n];
-            tab->Width = ImMin(tab->WidthContents, tab_max_width);
+            tab->Width = ImMin(tab->ContentWidth, tab_max_width);
             IM_ASSERT(tab->Width > 0.0f);
         }
     }
@@ -6627,7 +6627,7 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
         if (scroll_track_selected_tab_id == 0 && g.NavJustMovedToId == tab->ID)
             scroll_track_selected_tab_id = tab->ID;
         offset_x += tab->Width + g.Style.ItemInnerSpacing.x;
-        offset_x_ideal += tab->WidthContents + g.Style.ItemInnerSpacing.x;
+        offset_x_ideal += tab->ContentWidth + g.Style.ItemInnerSpacing.x;
     }
     tab_bar->OffsetMax = ImMax(offset_x - g.Style.ItemInnerSpacing.x, 0.0f);
     tab_bar->OffsetMaxIdeal = ImMax(offset_x_ideal - g.Style.ItemInnerSpacing.x, 0.0f);
@@ -6983,7 +6983,7 @@ bool    ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
         tab_is_new = true;
     }
     tab_bar->LastTabItemIdx = (short)tab_bar->Tabs.index_from_ptr(tab);
-    tab->WidthContents = size.x;
+    tab->ContentWidth = size.x;
 
     if (p_open == NULL)
         flags |= ImGuiTabItemFlags_NoCloseButton;
@@ -7147,10 +7147,10 @@ bool    ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
     }
 
 #if 0
-    if (hovered && g.HoveredIdNotActiveTimer > 0.50f && bb.GetWidth() < tab->WidthContents)
+    if (hovered && g.HoveredIdNotActiveTimer > 0.50f && bb.GetWidth() < tab->ContentWidth)
     {
         // Enlarge tab display when hovering
-        bb.Max.x = bb.Min.x + IM_FLOOR(ImLerp(bb.GetWidth(), tab->WidthContents, ImSaturate((g.HoveredIdNotActiveTimer - 0.40f) * 6.0f)));
+        bb.Max.x = bb.Min.x + IM_FLOOR(ImLerp(bb.GetWidth(), tab->ContentWidth, ImSaturate((g.HoveredIdNotActiveTimer - 0.40f) * 6.0f)));
         display_draw_list = GetForegroundDrawList(window);
         TabItemBackground(display_draw_list, bb, flags, GetColorU32(ImGuiCol_TitleBgActive));
     }