Merged Daniel's Google Summer of Code work from SDL-gsoc2010_IME
authorSam Lantinga <slouken@libsdl.org>
Sun, 22 Aug 2010 12:39:27 -0700
changeset 4763518d1679d2d0
parent 4762 833a225613e2
parent 4761 bb2e32f5a556
child 4764 102675835e08
Merged Daniel's Google Summer of Code work from SDL-gsoc2010_IME
include/SDL_stdinc.h
src/SDL_compat.c
src/events/SDL_keyboard.c
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/win32/SDL_win32events.c
src/video/win32/SDL_win32keyboard.c
src/video/win32/SDL_win32video.c
src/video/win32/SDL_win32video.h
src/video/win32/SDL_win32window.c
test/testime.c
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/EXCLUDE/GLIMM/GLIMM.sln	Sun Aug 22 12:39:27 2010 -0700
     1.3 @@ -0,0 +1,20 @@
     1.4 +
     1.5 +Microsoft Visual Studio Solution File, Format Version 10.00
     1.6 +# Visual Studio 2008
     1.7 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GLIMM", "GLIMM.vcproj", "{F21B830F-20A9-4473-B67A-21D1743C6E19}"
     1.8 +EndProject
     1.9 +Global
    1.10 +	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    1.11 +		Debug|Win32 = Debug|Win32
    1.12 +		Release|Win32 = Release|Win32
    1.13 +	EndGlobalSection
    1.14 +	GlobalSection(ProjectConfigurationPlatforms) = postSolution
    1.15 +		{F21B830F-20A9-4473-B67A-21D1743C6E19}.Debug|Win32.ActiveCfg = Debug|Win32
    1.16 +		{F21B830F-20A9-4473-B67A-21D1743C6E19}.Debug|Win32.Build.0 = Debug|Win32
    1.17 +		{F21B830F-20A9-4473-B67A-21D1743C6E19}.Release|Win32.ActiveCfg = Release|Win32
    1.18 +		{F21B830F-20A9-4473-B67A-21D1743C6E19}.Release|Win32.Build.0 = Release|Win32
    1.19 +	EndGlobalSection
    1.20 +	GlobalSection(SolutionProperties) = preSolution
    1.21 +		HideSolutionNode = FALSE
    1.22 +	EndGlobalSection
    1.23 +EndGlobal
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/EXCLUDE/GLIMM/GLIMM.vcproj	Sun Aug 22 12:39:27 2010 -0700
     2.3 @@ -0,0 +1,233 @@
     2.4 +<?xml version="1.0" encoding="Windows-1252"?>
     2.5 +<VisualStudioProject
     2.6 +	ProjectType="Visual C++"
     2.7 +	Version="9.00"
     2.8 +	Name="GLIMM"
     2.9 +	ProjectGUID="{F21B830F-20A9-4473-B67A-21D1743C6E19}"
    2.10 +	RootNamespace="GLIMM"
    2.11 +	Keyword="Win32Proj"
    2.12 +	TargetFrameworkVersion="196613"
    2.13 +	>
    2.14 +	<Platforms>
    2.15 +		<Platform
    2.16 +			Name="Win32"
    2.17 +		/>
    2.18 +	</Platforms>
    2.19 +	<ToolFiles>
    2.20 +	</ToolFiles>
    2.21 +	<Configurations>
    2.22 +		<Configuration
    2.23 +			Name="Debug|Win32"
    2.24 +			OutputDirectory="$(SolutionDir)bin"
    2.25 +			IntermediateDirectory="obj\$(ConfigurationName)"
    2.26 +			ConfigurationType="1"
    2.27 +			CharacterSet="1"
    2.28 +			>
    2.29 +			<Tool
    2.30 +				Name="VCPreBuildEventTool"
    2.31 +			/>
    2.32 +			<Tool
    2.33 +				Name="VCCustomBuildTool"
    2.34 +			/>
    2.35 +			<Tool
    2.36 +				Name="VCXMLDataGeneratorTool"
    2.37 +			/>
    2.38 +			<Tool
    2.39 +				Name="VCWebServiceProxyGeneratorTool"
    2.40 +			/>
    2.41 +			<Tool
    2.42 +				Name="VCMIDLTool"
    2.43 +			/>
    2.44 +			<Tool
    2.45 +				Name="VCCLCompilerTool"
    2.46 +				Optimization="0"
    2.47 +				AdditionalIncludeDirectories="include"
    2.48 +				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
    2.49 +				MinimalRebuild="true"
    2.50 +				BasicRuntimeChecks="3"
    2.51 +				RuntimeLibrary="3"
    2.52 +				UsePrecompiledHeader="0"
    2.53 +				WarningLevel="3"
    2.54 +				DebugInformationFormat="4"
    2.55 +			/>
    2.56 +			<Tool
    2.57 +				Name="VCManagedResourceCompilerTool"
    2.58 +			/>
    2.59 +			<Tool
    2.60 +				Name="VCResourceCompilerTool"
    2.61 +			/>
    2.62 +			<Tool
    2.63 +				Name="VCPreLinkEventTool"
    2.64 +			/>
    2.65 +			<Tool
    2.66 +				Name="VCLinkerTool"
    2.67 +				AdditionalDependencies="imm32.lib"
    2.68 +				LinkIncremental="2"
    2.69 +				GenerateDebugInformation="true"
    2.70 +				SubSystem="1"
    2.71 +				TargetMachine="1"
    2.72 +			/>
    2.73 +			<Tool
    2.74 +				Name="VCALinkTool"
    2.75 +			/>
    2.76 +			<Tool
    2.77 +				Name="VCManifestTool"
    2.78 +			/>
    2.79 +			<Tool
    2.80 +				Name="VCXDCMakeTool"
    2.81 +			/>
    2.82 +			<Tool
    2.83 +				Name="VCBscMakeTool"
    2.84 +			/>
    2.85 +			<Tool
    2.86 +				Name="VCFxCopTool"
    2.87 +			/>
    2.88 +			<Tool
    2.89 +				Name="VCAppVerifierTool"
    2.90 +			/>
    2.91 +			<Tool
    2.92 +				Name="VCPostBuildEventTool"
    2.93 +			/>
    2.94 +		</Configuration>
    2.95 +		<Configuration
    2.96 +			Name="Release|Win32"
    2.97 +			OutputDirectory="$(SolutionDir)bin"
    2.98 +			IntermediateDirectory="obj\$(ConfigurationName)"
    2.99 +			ConfigurationType="1"
   2.100 +			CharacterSet="1"
   2.101 +			WholeProgramOptimization="1"
   2.102 +			>
   2.103 +			<Tool
   2.104 +				Name="VCPreBuildEventTool"
   2.105 +			/>
   2.106 +			<Tool
   2.107 +				Name="VCCustomBuildTool"
   2.108 +			/>
   2.109 +			<Tool
   2.110 +				Name="VCXMLDataGeneratorTool"
   2.111 +			/>
   2.112 +			<Tool
   2.113 +				Name="VCWebServiceProxyGeneratorTool"
   2.114 +			/>
   2.115 +			<Tool
   2.116 +				Name="VCMIDLTool"
   2.117 +			/>
   2.118 +			<Tool
   2.119 +				Name="VCCLCompilerTool"
   2.120 +				Optimization="2"
   2.121 +				EnableIntrinsicFunctions="true"
   2.122 +				AdditionalIncludeDirectories="include"
   2.123 +				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
   2.124 +				RuntimeLibrary="2"
   2.125 +				EnableFunctionLevelLinking="true"
   2.126 +				UsePrecompiledHeader="0"
   2.127 +				WarningLevel="3"
   2.128 +				DebugInformationFormat="3"
   2.129 +			/>
   2.130 +			<Tool
   2.131 +				Name="VCManagedResourceCompilerTool"
   2.132 +			/>
   2.133 +			<Tool
   2.134 +				Name="VCResourceCompilerTool"
   2.135 +			/>
   2.136 +			<Tool
   2.137 +				Name="VCPreLinkEventTool"
   2.138 +			/>
   2.139 +			<Tool
   2.140 +				Name="VCLinkerTool"
   2.141 +				AdditionalDependencies="imm32.lib"
   2.142 +				LinkIncremental="1"
   2.143 +				GenerateDebugInformation="true"
   2.144 +				SubSystem="1"
   2.145 +				OptimizeReferences="2"
   2.146 +				EnableCOMDATFolding="2"
   2.147 +				TargetMachine="1"
   2.148 +			/>
   2.149 +			<Tool
   2.150 +				Name="VCALinkTool"
   2.151 +			/>
   2.152 +			<Tool
   2.153 +				Name="VCManifestTool"
   2.154 +			/>
   2.155 +			<Tool
   2.156 +				Name="VCXDCMakeTool"
   2.157 +			/>
   2.158 +			<Tool
   2.159 +				Name="VCBscMakeTool"
   2.160 +			/>
   2.161 +			<Tool
   2.162 +				Name="VCFxCopTool"
   2.163 +			/>
   2.164 +			<Tool
   2.165 +				Name="VCAppVerifierTool"
   2.166 +			/>
   2.167 +			<Tool
   2.168 +				Name="VCPostBuildEventTool"
   2.169 +			/>
   2.170 +		</Configuration>
   2.171 +	</Configurations>
   2.172 +	<References>
   2.173 +	</References>
   2.174 +	<Files>
   2.175 +		<Filter
   2.176 +			Name="Source Files"
   2.177 +			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
   2.178 +			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
   2.179 +			>
   2.180 +			<File
   2.181 +				RelativePath=".\src\App.cpp"
   2.182 +				>
   2.183 +			</File>
   2.184 +			<File
   2.185 +				RelativePath=".\src\IMM.cpp"
   2.186 +				>
   2.187 +			</File>
   2.188 +			<File
   2.189 +				RelativePath=".\src\Main.cpp"
   2.190 +				>
   2.191 +			</File>
   2.192 +			<File
   2.193 +				RelativePath=".\src\Video_Mode.cpp"
   2.194 +				>
   2.195 +			</File>
   2.196 +			<File
   2.197 +				RelativePath=".\src\Window.cpp"
   2.198 +				>
   2.199 +			</File>
   2.200 +		</Filter>
   2.201 +		<Filter
   2.202 +			Name="Header Files"
   2.203 +			Filter="h;hpp;hxx;hm;inl;inc;xsd"
   2.204 +			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
   2.205 +			>
   2.206 +			<File
   2.207 +				RelativePath=".\include\App.hpp"
   2.208 +				>
   2.209 +			</File>
   2.210 +			<File
   2.211 +				RelativePath=".\include\IMM.hpp"
   2.212 +				>
   2.213 +			</File>
   2.214 +			<File
   2.215 +				RelativePath=".\include\Video_Mode.hpp"
   2.216 +				>
   2.217 +			</File>
   2.218 +			<File
   2.219 +				RelativePath=".\include\Window.hpp"
   2.220 +				>
   2.221 +			</File>
   2.222 +			<File
   2.223 +				RelativePath=".\include\Window_Listener.hpp"
   2.224 +				>
   2.225 +			</File>
   2.226 +		</Filter>
   2.227 +		<Filter
   2.228 +			Name="Resource Files"
   2.229 +			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
   2.230 +			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
   2.231 +			>
   2.232 +		</Filter>
   2.233 +	</Files>
   2.234 +	<Globals>
   2.235 +	</Globals>
   2.236 +</VisualStudioProject>
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/EXCLUDE/GLIMM/include/App.hpp	Sun Aug 22 12:39:27 2010 -0700
     3.3 @@ -0,0 +1,37 @@
     3.4 +#ifndef APP_HPP
     3.5 +#define APP_HPP
     3.6 +
     3.7 +#include "Window.hpp"
     3.8 +
     3.9 +class App : public Window_Listener
    3.10 +{
    3.11 +public:
    3.12 +	App();
    3.13 +	virtual ~App();
    3.14 +
    3.15 +	void Initialize();
    3.16 +	void Finalize();
    3.17 +
    3.18 +	void Run();
    3.19 +
    3.20 +	virtual void On_Close();
    3.21 +	virtual void On_Key_Down(int Key);
    3.22 +	virtual void On_Key_Up(int Key);
    3.23 +	virtual void On_Char(unsigned int Char);
    3.24 +	virtual void On_Resized(unsigned int Width, unsigned int Height);
    3.25 +	virtual void On_Mouse_Button_Down(Mouse_Button Button);
    3.26 +
    3.27 +private:
    3.28 +	void Update();
    3.29 +	void Draw();
    3.30 +
    3.31 +	static const int Width = 800;
    3.32 +	static const int Height = 600;
    3.33 +	static const int Bits_Per_Pixel = 32;
    3.34 +	static const bool Fullscreen = true;
    3.35 +
    3.36 +	Window my_Window;
    3.37 +	bool my_Done;
    3.38 +};
    3.39 +
    3.40 +#endif
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/EXCLUDE/GLIMM/include/IMM.hpp	Sun Aug 22 12:39:27 2010 -0700
     4.3 @@ -0,0 +1,41 @@
     4.4 +#ifndef IMM_HPP
     4.5 +#define IMM_HPP
     4.6 +
     4.7 +#define WIN32_LEAN_AND_MEAN
     4.8 +#include <Windows.h>
     4.9 +#include <msctf.h>
    4.10 +
    4.11 +class IMM
    4.12 +{
    4.13 +public:
    4.14 +	IMM();
    4.15 +	~IMM();
    4.16 +
    4.17 +	void Initialize(HWND Window);
    4.18 +	void Finalize();
    4.19 +
    4.20 +	LRESULT Handle_Message(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam, bool &Ate);
    4.21 +
    4.22 +	void Enable();
    4.23 +	void Disable();
    4.24 +	bool Is_Enabled();
    4.25 +	void Toggle();
    4.26 +
    4.27 +	void Focus_Gained();
    4.28 +	void Focus_Lost();
    4.29 +
    4.30 +private:
    4.31 +	void Update_Input_Locale();
    4.32 +	void Cancel_Composition();
    4.33 +	void Input_Language_Changed();
    4.34 +
    4.35 +	bool my_COM_Initialized;
    4.36 +	ITfThreadMgr *my_Thread_Manager;
    4.37 +	HWND my_Window;
    4.38 +	HIMC my_Context;
    4.39 +	HKL my_HKL;
    4.40 +	bool my_Vertical_Candidates;
    4.41 +	bool my_Enabled;
    4.42 +};
    4.43 +
    4.44 +#endif
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/EXCLUDE/GLIMM/include/Video_Mode.hpp	Sun Aug 22 12:39:27 2010 -0700
     5.3 @@ -0,0 +1,30 @@
     5.4 +#ifndef VIDEO_MODE_HPP
     5.5 +#define VIDEO_MODE_HPP
     5.6 +
     5.7 +#include <cstddef>
     5.8 +
     5.9 +class Video_Mode
    5.10 +{
    5.11 +public:
    5.12 +	Video_Mode();
    5.13 +	Video_Mode(unsigned int The_Width, unsigned int The_Height, unsigned int The_Bits_Per_Pixel);
    5.14 +
    5.15 +	static Video_Mode Get_Desktop_Mode();
    5.16 +
    5.17 +	static std::size_t Get_Mode_Count();
    5.18 +	static Video_Mode Get_Mode(std::size_t Index);
    5.19 +
    5.20 +	bool Is_Valid() const;
    5.21 +
    5.22 +	bool operator==(const Video_Mode &Mode) const;
    5.23 +	bool operator!=(const Video_Mode &Mode) const;
    5.24 +
    5.25 +	unsigned int Width;
    5.26 +	unsigned int Height;
    5.27 +	unsigned int Bits_Per_Pixel;
    5.28 +
    5.29 +private:
    5.30 +	static void Initialize_Modes();
    5.31 +};
    5.32 +
    5.33 +#endif
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/EXCLUDE/GLIMM/include/Window.hpp	Sun Aug 22 12:39:27 2010 -0700
     6.3 @@ -0,0 +1,63 @@
     6.4 +#ifndef WINDOW_HPP
     6.5 +#define WINDOW_HPP
     6.6 +
     6.7 +#include <string>
     6.8 +
     6.9 +#define WIN32_LEAN_AND_MEAN
    6.10 +#include <Windows.h>
    6.11 +
    6.12 +#include "Video_Mode.hpp"
    6.13 +#include "Window_Listener.hpp"
    6.14 +#include "IMM.hpp"
    6.15 +
    6.16 +class Window
    6.17 +{
    6.18 +public:
    6.19 +	Window();
    6.20 +	~Window();
    6.21 +
    6.22 +	void Initialize(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen);
    6.23 +	void Finalize();
    6.24 +
    6.25 +	void Set_Listener(Window_Listener *Listener);
    6.26 +
    6.27 +	void Show();
    6.28 +	void Hide();
    6.29 +
    6.30 +	void Handle_Events();
    6.31 +	void Display();
    6.32 +
    6.33 +	void Show_Cursor();
    6.34 +	void Hide_Cursor();
    6.35 +
    6.36 +	HWND Get_Handle();
    6.37 +	IMM &Get_IMM();
    6.38 +
    6.39 +private:
    6.40 +	static const wchar_t *Window_Class_Name;
    6.41 +
    6.42 +	void Register_Class();
    6.43 +	void Unregister_Class();
    6.44 +
    6.45 +	void Create_Window(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen);
    6.46 +	void Destroy_Window();
    6.47 +
    6.48 +	void Create_Context(const Video_Mode &Mode);
    6.49 +	void Destroy_Context();
    6.50 +
    6.51 +	void Switch_To_Fullscreen(const Video_Mode &Mode);
    6.52 +
    6.53 +	LRESULT Handle_Message(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam);
    6.54 +	static LRESULT CALLBACK Window_Procedure(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam);
    6.55 +
    6.56 +	HWND my_Handle;
    6.57 +	Video_Mode my_Video_Mode;
    6.58 +	bool my_Fullscreen;
    6.59 +	HDC my_Device_Context;
    6.60 +	HGLRC my_GL_Context;
    6.61 +	bool my_Class_Registered;
    6.62 +	Window_Listener *my_Listener;
    6.63 +	IMM my_IMM;
    6.64 +};
    6.65 +
    6.66 +#endif
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/EXCLUDE/GLIMM/include/Window_Listener.hpp	Sun Aug 22 12:39:27 2010 -0700
     7.3 @@ -0,0 +1,23 @@
     7.4 +#ifndef WINDOW_LISTENER_HPP
     7.5 +#define WINDOW_LISTENER_HPP
     7.6 +
     7.7 +enum Mouse_Button
     7.8 +{
     7.9 +	Mouse_Button_Left,
    7.10 +	Mouse_Button_Right
    7.11 +};
    7.12 +
    7.13 +class Window_Listener
    7.14 +{
    7.15 +public:
    7.16 +	virtual void On_Close(){}
    7.17 +	virtual void On_Key_Down(int Key){}
    7.18 +	virtual void On_Key_Up(int Key){}
    7.19 +	virtual void On_Char(unsigned int Char){}
    7.20 +	virtual void On_Resized(unsigned int Width, unsigned int Height){}
    7.21 +	virtual void On_Mouse_Button_Down(Mouse_Button Button){}
    7.22 +	virtual void On_Mouse_Button_Up(Mouse_Button Button){}
    7.23 +
    7.24 +};
    7.25 +
    7.26 +#endif
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/EXCLUDE/GLIMM/src/App.cpp	Sun Aug 22 12:39:27 2010 -0700
     8.3 @@ -0,0 +1,113 @@
     8.4 +#include "App.hpp"
     8.5 +#include <GL/gl.h>
     8.6 +#include <GL/glu.h>
     8.7 +
     8.8 +#pragma comment(lib, "glu32.lib")
     8.9 +
    8.10 +GLfloat Rotation = 0.0f;
    8.11 +
    8.12 +App::App() : my_Done(false)
    8.13 +{
    8.14 +
    8.15 +}
    8.16 +
    8.17 +App::~App()
    8.18 +{
    8.19 +	Finalize();
    8.20 +}
    8.21 +
    8.22 +void App::Initialize()
    8.23 +{
    8.24 +	Finalize();
    8.25 +
    8.26 +	my_Window.Initialize(L"GLIMM", Video_Mode(Width, Height, Bits_Per_Pixel), Fullscreen);
    8.27 +	my_Window.Set_Listener(this);
    8.28 +	my_Window.Show();
    8.29 +	my_Window.Hide_Cursor();
    8.30 +}
    8.31 +
    8.32 +void App::Finalize()
    8.33 +{
    8.34 +	my_Window.Finalize();
    8.35 +}
    8.36 +
    8.37 +void App::Run()
    8.38 +{
    8.39 +	Initialize();
    8.40 +	while (!my_Done)
    8.41 +	{
    8.42 +		my_Window.Handle_Events();
    8.43 +
    8.44 +		Update();
    8.45 +		Draw();
    8.46 +		my_Window.Display();
    8.47 +	}
    8.48 +}
    8.49 +
    8.50 +void App::On_Close()
    8.51 +{
    8.52 +	my_Done = true;
    8.53 +	my_Window.Hide();
    8.54 +}
    8.55 +
    8.56 +void App::On_Key_Down(int Key)
    8.57 +{
    8.58 +	switch (Key)
    8.59 +	{
    8.60 +	case VK_ESCAPE:
    8.61 +		On_Close();
    8.62 +		break;
    8.63 +	}
    8.64 +}
    8.65 +
    8.66 +void App::On_Key_Up(int Key)
    8.67 +{
    8.68 +
    8.69 +}
    8.70 +
    8.71 +void App::On_Char(unsigned int Char)
    8.72 +{
    8.73 +	printf("Char: U+%04X\n", Char);
    8.74 +}
    8.75 +
    8.76 +void App::On_Resized(unsigned int Width, unsigned int Height)
    8.77 +{
    8.78 +	glViewport(0, 0, Width, Height);
    8.79 +	glMatrixMode(GL_PROJECTION);
    8.80 +	glLoadIdentity();
    8.81 +
    8.82 +	glMatrixMode(GL_MODELVIEW);
    8.83 +	glLoadIdentity();
    8.84 +}
    8.85 +
    8.86 +void App::On_Mouse_Button_Down(Mouse_Button Button)
    8.87 +{
    8.88 +	switch (Button)
    8.89 +	{
    8.90 +	case Mouse_Button_Left:
    8.91 +		my_Window.Get_IMM().Toggle();
    8.92 +		break;
    8.93 +	}
    8.94 +}
    8.95 +
    8.96 +void App::Update()
    8.97 +{
    8.98 +	Rotation += 0.2f;
    8.99 +}
   8.100 +
   8.101 +void App::Draw()
   8.102 +{
   8.103 +	glClear(GL_COLOR_BUFFER_BIT);
   8.104 +
   8.105 +	glLoadIdentity();
   8.106 +	glRotatef(Rotation, 0.0f, 0.0f, -1.0f);
   8.107 +
   8.108 +	glBegin(GL_TRIANGLES);
   8.109 +		glColor3f(0.7f, 0.0f, 0.0f);
   8.110 +		glVertex3f(0.0f, 0.5f, 0.0f);
   8.111 +		glColor3f(0.0f, 0.7f, 0.0f);
   8.112 +		glVertex3f(-0.5f, -0.5f, 0.0f);
   8.113 +		glColor3f(0.0f, 0.0f, 0.7f);
   8.114 +		glVertex3f(0.5f, -0.5f, 0.0f);
   8.115 +	glEnd();
   8.116 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/EXCLUDE/GLIMM/src/IMM.cpp	Sun Aug 22 12:39:27 2010 -0700
     9.3 @@ -0,0 +1,237 @@
     9.4 +#include "IMM.hpp"
     9.5 +#include <stdexcept>
     9.6 +
     9.7 +IMM::IMM() : my_COM_Initialized(false),
     9.8 +			 my_Thread_Manager(0),
     9.9 +			 my_Window(0),
    9.10 +			 my_Context(0),
    9.11 +			 my_HKL(0),
    9.12 +			 my_Vertical_Candidates(false),
    9.13 +			 my_Enabled(false)
    9.14 +{
    9.15 +
    9.16 +}
    9.17 +
    9.18 +IMM::~IMM()
    9.19 +{
    9.20 +	Finalize();
    9.21 +}
    9.22 +
    9.23 +void IMM::Initialize(HWND Window)
    9.24 +{
    9.25 +	Finalize();
    9.26 +
    9.27 +	my_Window = Window;
    9.28 +
    9.29 +	if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
    9.30 +	{
    9.31 +		my_COM_Initialized = true;
    9.32 +		if (SUCCEEDED(CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, reinterpret_cast<LPVOID *>(&my_Thread_Manager))))
    9.33 +		{
    9.34 +			ITfDocumentMgr *Document_Manager = 0;
    9.35 +			if (SUCCEEDED(my_Thread_Manager->AssociateFocus(Window, NULL, &Document_Manager)))
    9.36 +			{
    9.37 +				if (Document_Manager)
    9.38 +					Document_Manager->Release();
    9.39 +			}
    9.40 +			else
    9.41 +				printf("Warning: ITfThreadMgr->AssociateFocus failed\n");
    9.42 +		}
    9.43 +		else
    9.44 +			printf("Warning: Failed to create ITfThreadMgr instance\n");
    9.45 +	}
    9.46 +	else
    9.47 +		printf("Warning: Failed to initialize COM\n");
    9.48 +
    9.49 +	ImmDisableTextFrameService((DWORD)-1);
    9.50 +
    9.51 +	my_Context = ImmGetContext(my_Window);
    9.52 +	ImmReleaseContext(my_Window, my_Context);
    9.53 +	if (!my_Context)
    9.54 +		throw std::runtime_error("No context (No IME installed?)");
    9.55 +
    9.56 +	Update_Input_Locale();
    9.57 +	Cancel_Composition();
    9.58 +	Disable();
    9.59 +}
    9.60 +
    9.61 +void IMM::Finalize()
    9.62 +{
    9.63 +	if (my_Thread_Manager)
    9.64 +	{
    9.65 +		my_Thread_Manager->Release();
    9.66 +		my_Thread_Manager = 0;
    9.67 +	}
    9.68 +	if (my_COM_Initialized)
    9.69 +	{
    9.70 +		CoUninitialize();
    9.71 +		my_COM_Initialized = false;
    9.72 +	}
    9.73 +}
    9.74 +
    9.75 +#define GET_LANG(hkl) LOWORD((hkl))
    9.76 +#define GET_PRIMLANG(hkl) ((WORD)PRIMARYLANGID(GET_LANG((hkl))))
    9.77 +#define GET_SUBLANG(hkl) SUBLANGID(GET_LANG((hkl)))
    9.78 +
    9.79 +void IMM::Update_Input_Locale()
    9.80 +{
    9.81 +	static HKL Previous_HKL = 0;
    9.82 +	my_HKL = GetKeyboardLayout(0);
    9.83 +	if (Previous_HKL == my_HKL)
    9.84 +		return;
    9.85 +
    9.86 +	Previous_HKL = my_HKL;
    9.87 +	my_Vertical_Candidates = false;
    9.88 +	switch (GET_PRIMLANG(my_HKL))
    9.89 +	{
    9.90 +	case LANG_CHINESE:
    9.91 +		my_Vertical_Candidates = true;
    9.92 +		switch (GET_SUBLANG(my_HKL))
    9.93 +		{
    9.94 +		case SUBLANG_CHINESE_SIMPLIFIED:
    9.95 +			my_Vertical_Candidates = false;
    9.96 +			break;
    9.97 +		}
    9.98 +		break;
    9.99 +	case LANG_JAPANESE:
   9.100 +		my_Vertical_Candidates = true;
   9.101 +		break;
   9.102 +	}
   9.103 +}
   9.104 +
   9.105 +LRESULT IMM::Handle_Message(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam, bool &Ate)
   9.106 +{
   9.107 +	Ate = false;
   9.108 +	switch (Message)
   9.109 +	{
   9.110 +	case WM_INPUTLANGCHANGE:
   9.111 +		Input_Language_Changed();
   9.112 +		break;
   9.113 +	case WM_IME_SETCONTEXT:
   9.114 +		lParam = 0;
   9.115 +		break;
   9.116 +	case WM_IME_STARTCOMPOSITION:
   9.117 +		Ate = true;
   9.118 +		break;
   9.119 +	case WM_IME_COMPOSITION:
   9.120 +		{
   9.121 +			Ate = true;
   9.122 +			HIMC Context = ImmGetContext(Window);
   9.123 +			if (!Context)
   9.124 +				break;
   9.125 +
   9.126 +			if (lParam & GCS_RESULTSTR)
   9.127 +			{
   9.128 +				LONG Length = ImmGetCompositionStringW(Context, GCS_RESULTSTR, 0, 0);
   9.129 +				std::wstring Composition(Length / sizeof(wchar_t), 0);
   9.130 +				Length = ImmGetCompositionStringW(Context, GCS_RESULTSTR, &Composition[0], Composition.size() * sizeof(Composition[0]));
   9.131 +				printf("GCS_RESULTSTR: ");
   9.132 +				for (LONG i = 0; i < Length / sizeof(wchar_t); ++i)
   9.133 +					printf("U+%04X ", Composition[i]);
   9.134 +
   9.135 +				printf("\n");
   9.136 +			}
   9.137 +			if (lParam & GCS_COMPSTR)
   9.138 +			{
   9.139 +				LONG Length = ImmGetCompositionStringW(Context, GCS_COMPSTR, 0, 0);
   9.140 +				std::wstring Composition(Length / sizeof(wchar_t), 0);
   9.141 +				Length = ImmGetCompositionStringW(Context, GCS_COMPSTR, &Composition[0], Composition.size() * sizeof(Composition[0]));
   9.142 +				printf("GCS_COMPSTR: ");
   9.143 +				for (LONG i = 0; i < Length / sizeof(wchar_t); ++i)
   9.144 +					printf("U+%04X ", Composition[i]);
   9.145 +
   9.146 +				printf("\n");
   9.147 +			}
   9.148 +			ImmReleaseContext(Window, Context);
   9.149 +		}
   9.150 +		break;
   9.151 +	case WM_IME_ENDCOMPOSITION:
   9.152 +		break;
   9.153 +	case WM_IME_NOTIFY:
   9.154 +		switch (wParam)
   9.155 +		{
   9.156 +		case IMN_SETCONVERSIONMODE:
   9.157 +
   9.158 +			break;
   9.159 +		case IMN_SETOPENSTATUS:
   9.160 +			Update_Input_Locale();
   9.161 +			break;
   9.162 +		case IMN_OPENCANDIDATE:
   9.163 +		case IMN_CHANGECANDIDATE:
   9.164 +			Ate = true;
   9.165 +			break;
   9.166 +		case IMN_CLOSECANDIDATE:
   9.167 +			Ate = true;
   9.168 +			break;
   9.169 +		default:
   9.170 +			Ate = true;
   9.171 +			break;
   9.172 +		}
   9.173 +		break;
   9.174 +	}
   9.175 +	return 0;
   9.176 +}
   9.177 +
   9.178 +void IMM::Enable()
   9.179 +{
   9.180 +	ImmAssociateContext(my_Window, my_Context);
   9.181 +	Update_Input_Locale();
   9.182 +	my_Enabled = true;
   9.183 +	printf("* Enabled\n");
   9.184 +}
   9.185 +
   9.186 +void IMM::Disable()
   9.187 +{
   9.188 +	ImmAssociateContext(my_Window, 0);
   9.189 +	my_Enabled = false;
   9.190 +	printf("* Disabled\n");
   9.191 +}
   9.192 +
   9.193 +bool IMM::Is_Enabled()
   9.194 +{
   9.195 +	return my_Enabled;
   9.196 +}
   9.197 +
   9.198 +void IMM::Toggle()
   9.199 +{
   9.200 +	if (my_Enabled)
   9.201 +		Disable();
   9.202 +	else
   9.203 +		Enable();
   9.204 +}
   9.205 +
   9.206 +void IMM::Focus_Gained()
   9.207 +{
   9.208 +	if (my_Enabled)
   9.209 +		Enable();
   9.210 +}
   9.211 +
   9.212 +void IMM::Focus_Lost()
   9.213 +{
   9.214 +	bool Enabled = my_Enabled;
   9.215 +	Cancel_Composition();
   9.216 +	Disable();
   9.217 +	my_Enabled = Enabled;
   9.218 +}
   9.219 +
   9.220 +void IMM::Cancel_Composition()
   9.221 +{
   9.222 +	HIMC hIMC = ImmGetContext(my_Window);
   9.223 +	if (!hIMC)
   9.224 +		return;
   9.225 +
   9.226 +	ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
   9.227 +	ImmNotifyIME(hIMC, NI_CLOSECANDIDATE, 0, 0);
   9.228 +	ImmReleaseContext(my_Window, hIMC);
   9.229 +}
   9.230 +
   9.231 +void IMM::Input_Language_Changed()
   9.232 +{
   9.233 +	Update_Input_Locale();
   9.234 +	HWND hwndImeDef = ImmGetDefaultIMEWnd(my_Window);
   9.235 +	if (hwndImeDef)
   9.236 +	{
   9.237 +		SendMessageA(hwndImeDef, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0);
   9.238 +		SendMessageA(hwndImeDef, WM_IME_CONTROL, IMC_CLOSESTATUSWINDOW, 0);
   9.239 +	}
   9.240 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/EXCLUDE/GLIMM/src/Main.cpp	Sun Aug 22 12:39:27 2010 -0700
    10.3 @@ -0,0 +1,24 @@
    10.4 +#include "App.hpp"
    10.5 +#include <stdexcept>
    10.6 +
    10.7 +int main(int argc, char *argv[])
    10.8 +{
    10.9 +	int Result = EXIT_SUCCESS;
   10.10 +	try
   10.11 +	{
   10.12 +		App theApp;
   10.13 +		theApp.Run();
   10.14 +	}
   10.15 +	catch (const std::exception& e)
   10.16 +	{
   10.17 +		printf("Error: %s\n", e.what());
   10.18 +		Result = EXIT_FAILURE;
   10.19 +	}
   10.20 +	catch (...)
   10.21 +	{
   10.22 +		printf("Unhandled exception\n");
   10.23 +		Result = EXIT_FAILURE;
   10.24 +	}
   10.25 +	system("PAUSE");
   10.26 +	return Result;
   10.27 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/EXCLUDE/GLIMM/src/Video_Mode.cpp	Sun Aug 22 12:39:27 2010 -0700
    11.3 @@ -0,0 +1,100 @@
    11.4 +#include "Video_Mode.hpp"
    11.5 +#include <vector>
    11.6 +#include <algorithm>
    11.7 +#define WIN32_LEAN_AND_MEAN
    11.8 +#include <Windows.h>
    11.9 +
   11.10 +namespace
   11.11 +{
   11.12 +
   11.13 +	typedef std::vector<Video_Mode> Video_Mode_List;
   11.14 +	Video_Mode_List Supported_Modes;
   11.15 +
   11.16 +	struct Compare_Modes
   11.17 +	{
   11.18 +		bool operator()(const Video_Mode &Mode_1, const Video_Mode &Mode_2) const
   11.19 +		{
   11.20 +			if (Mode_1.Bits_Per_Pixel > Mode_2.Bits_Per_Pixel)
   11.21 +				return true;
   11.22 +			else if (Mode_1.Bits_Per_Pixel < Mode_2.Bits_Per_Pixel)
   11.23 +				return false;
   11.24 +			else if (Mode_1.Width > Mode_2.Width)
   11.25 +				return true;
   11.26 +			else if (Mode_1.Width < Mode_2.Width)
   11.27 +				return false;
   11.28 +			else
   11.29 +				return Mode_1.Height > Mode_2.Height;
   11.30 +		}
   11.31 +	};
   11.32 +
   11.33 +}
   11.34 +
   11.35 +Video_Mode::Video_Mode() : Width(0),
   11.36 +						   Height(0),
   11.37 +						   Bits_Per_Pixel(0)
   11.38 +{
   11.39 +
   11.40 +}
   11.41 +
   11.42 +Video_Mode::Video_Mode(unsigned int The_Width, unsigned int The_Height, unsigned int The_Bits_Per_Pixel)
   11.43 +	: Width(The_Width),
   11.44 +	  Height(The_Height),
   11.45 +	  Bits_Per_Pixel(The_Bits_Per_Pixel)
   11.46 +{
   11.47 +
   11.48 +}
   11.49 +
   11.50 +Video_Mode Video_Mode::Get_Desktop_Mode()
   11.51 +{
   11.52 +	DEVMODE Device_Mode = {0};
   11.53 +	Device_Mode.dmSize = sizeof(Device_Mode);
   11.54 +	EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &Device_Mode);
   11.55 +	return Video_Mode(Device_Mode.dmPelsWidth, Device_Mode.dmPelsHeight, Device_Mode.dmBitsPerPel);
   11.56 +}
   11.57 +
   11.58 +std::size_t Video_Mode::Get_Mode_Count()
   11.59 +{
   11.60 +	Initialize_Modes();
   11.61 +	return Supported_Modes.size();
   11.62 +}
   11.63 +
   11.64 +Video_Mode Video_Mode::Get_Mode(std::size_t Index)
   11.65 +{
   11.66 +	Initialize_Modes();
   11.67 +	return Supported_Modes[Index];
   11.68 +}
   11.69 +
   11.70 +bool Video_Mode::Is_Valid() const
   11.71 +{
   11.72 +	Initialize_Modes();
   11.73 +	return Supported_Modes.end() != std::find(Supported_Modes.begin(), Supported_Modes.end(), *this);
   11.74 +}
   11.75 +
   11.76 +bool Video_Mode::operator==(const Video_Mode &Mode) const
   11.77 +{
   11.78 +	return (Width == Mode.Width
   11.79 +		&&  Height == Mode.Height
   11.80 +		&&  Bits_Per_Pixel == Mode.Bits_Per_Pixel);
   11.81 +}
   11.82 +
   11.83 +bool Video_Mode::operator!=(const Video_Mode &Mode) const
   11.84 +{
   11.85 +	return !(*this == Mode);
   11.86 +}
   11.87 +
   11.88 +void Video_Mode::Initialize_Modes()
   11.89 +{
   11.90 +	static bool Initialized = false;
   11.91 +	if (!Initialized)
   11.92 +	{
   11.93 +		DEVMODE Device_Mode = {0};
   11.94 +		Device_Mode.dmSize = sizeof(Device_Mode);
   11.95 +		for (std::size_t i = 0; 0 != EnumDisplaySettings(NULL, i, &Device_Mode); ++i)
   11.96 +		{
   11.97 +			Video_Mode Mode(Device_Mode.dmPelsWidth, Device_Mode.dmPelsHeight, Device_Mode.dmBitsPerPel);
   11.98 +			if (Supported_Modes.end() == std::find(Supported_Modes.begin(), Supported_Modes.end(), Mode))
   11.99 +				Supported_Modes.push_back(Mode);
  11.100 +		}
  11.101 +		std::sort(Supported_Modes.begin(), Supported_Modes.end(), Compare_Modes());
  11.102 +	}
  11.103 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/EXCLUDE/GLIMM/src/Window.cpp	Sun Aug 22 12:39:27 2010 -0700
    12.3 @@ -0,0 +1,317 @@
    12.4 +#include "Window.hpp"
    12.5 +#include <gl/GL.h>
    12.6 +
    12.7 +#pragma comment(lib, "opengl32.lib")
    12.8 +
    12.9 +const wchar_t *Window::Window_Class_Name = L"GLTSF";
   12.10 +
   12.11 +Window::Window() : my_Handle(0),
   12.12 +				   my_Device_Context(0),
   12.13 +				   my_GL_Context(0),
   12.14 +				   my_Class_Registered(false),
   12.15 +				   my_Listener(0)
   12.16 +{
   12.17 +
   12.18 +}
   12.19 +
   12.20 +Window::~Window()
   12.21 +{
   12.22 +	Finalize();
   12.23 +	Show_Cursor();
   12.24 +}
   12.25 +
   12.26 +void Window::Initialize(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen)
   12.27 +{
   12.28 +	Finalize();
   12.29 +
   12.30 +	my_Video_Mode = Mode;
   12.31 +	if (!my_Video_Mode.Is_Valid())
   12.32 +		throw std::runtime_error("Invalid video mode");
   12.33 +
   12.34 +	my_Fullscreen = Fullscreen;
   12.35 +	Register_Class();
   12.36 +	Create_Window(Title, Mode, Fullscreen);
   12.37 +	Show();
   12.38 +	my_IMM.Initialize(my_Handle);
   12.39 +}
   12.40 +
   12.41 +void Window::Finalize()
   12.42 +{
   12.43 +	my_IMM.Finalize();
   12.44 +	Destroy_Window();
   12.45 +	Unregister_Class();
   12.46 +}
   12.47 +
   12.48 +void Window::Set_Listener(Window_Listener *Listener)
   12.49 +{
   12.50 +	my_Listener = Listener;
   12.51 +}
   12.52 +
   12.53 +void Window::Show()
   12.54 +{
   12.55 +	if (my_Handle)
   12.56 +		ShowWindow(my_Handle, SW_SHOW);
   12.57 +}
   12.58 +
   12.59 +void Window::Hide()
   12.60 +{
   12.61 +	if (my_Handle)
   12.62 +		ShowWindow(my_Handle, SW_HIDE);
   12.63 +}
   12.64 +
   12.65 +void Window::Handle_Events()
   12.66 +{
   12.67 +	MSG Message = {0};
   12.68 +	while (PeekMessageW(&Message, NULL, 0, 0, PM_REMOVE))
   12.69 +	{
   12.70 +		TranslateMessage(&Message);
   12.71 +		DispatchMessageW(&Message);
   12.72 +	}
   12.73 +}
   12.74 +
   12.75 +void Window::Display()
   12.76 +{
   12.77 +	if (my_Device_Context && my_GL_Context)
   12.78 +		SwapBuffers(my_Device_Context);
   12.79 +}
   12.80 +
   12.81 +void Window::Show_Cursor()
   12.82 +{
   12.83 +	ShowCursor(TRUE);
   12.84 +}
   12.85 +
   12.86 +void Window::Hide_Cursor()
   12.87 +{
   12.88 +	ShowCursor(FALSE);
   12.89 +}
   12.90 +
   12.91 +HWND Window::Get_Handle()
   12.92 +{
   12.93 +	return my_Handle;
   12.94 +}
   12.95 +
   12.96 +IMM & Window::Get_IMM()
   12.97 +{
   12.98 +	return my_IMM;
   12.99 +}
  12.100 +
  12.101 +void Window::Register_Class()
  12.102 +{
  12.103 +	WNDCLASSEXW Window_Class = {0};
  12.104 +	Window_Class.cbSize = sizeof(Window_Class);
  12.105 +	Window_Class.style = 0;
  12.106 +	Window_Class.lpfnWndProc = &Window::Window_Procedure;
  12.107 +	Window_Class.cbClsExtra = 0;
  12.108 +	Window_Class.cbWndExtra = 0;
  12.109 +	Window_Class.hInstance = GetModuleHandle(NULL);
  12.110 +	Window_Class.hIcon = NULL;
  12.111 +	Window_Class.hCursor = NULL;
  12.112 +	Window_Class.hbrBackground = NULL;
  12.113 +	Window_Class.lpszMenuName = NULL;
  12.114 +	Window_Class.lpszClassName = Window_Class_Name;
  12.115 +	Window_Class.hIconSm = NULL;
  12.116 +	if (0 == RegisterClassExW(&Window_Class))
  12.117 +		throw std::runtime_error("Failed to register window class");
  12.118 +
  12.119 +	my_Class_Registered = true;
  12.120 +}
  12.121 +
  12.122 +void Window::Unregister_Class()
  12.123 +{
  12.124 +	if (my_Class_Registered)
  12.125 +	{
  12.126 +		if (0 == UnregisterClassW(Window_Class_Name, GetModuleHandle(NULL)))
  12.127 +			printf("Warning: Failed to unregister window class\n");
  12.128 +
  12.129 +		my_Class_Registered = false;
  12.130 +	}
  12.131 +}
  12.132 +
  12.133 +void Window::Create_Window(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen)
  12.134 +{
  12.135 +	HDC Screen_DC = GetDC(NULL);
  12.136 +	int Left = (GetDeviceCaps(Screen_DC, HORZRES) - my_Video_Mode.Width) / 2;
  12.137 +	int Top = (GetDeviceCaps(Screen_DC, VERTRES) - my_Video_Mode.Height) / 2;
  12.138 +	int Width = my_Video_Mode.Width;
  12.139 +	int Height = my_Video_Mode.Height;
  12.140 +	ReleaseDC(NULL, Screen_DC);
  12.141 +
  12.142 +	DWORD Style = WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU;
  12.143 +	if (!my_Fullscreen)
  12.144 +	{
  12.145 +		RECT Rect = {0, 0, Width, Height};
  12.146 +		AdjustWindowRect(&Rect, Style, false);
  12.147 +		Width = Rect.right - Rect.left;
  12.148 +		Height = Rect.bottom - Rect.top;
  12.149 +	}
  12.150 +	my_Handle = CreateWindowW(Window_Class_Name, Title.c_str(), Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
  12.151 +	if (!my_Handle)
  12.152 +		throw std::runtime_error("Failed to create window");
  12.153 +
  12.154 +	if (Fullscreen)
  12.155 +		Switch_To_Fullscreen(Mode);
  12.156 +
  12.157 +	Create_Context(Mode);
  12.158 +
  12.159 +	RECT Rect = {0};
  12.160 +	GetClientRect(my_Handle, &Rect);
  12.161 +	//TODO: ...
  12.162 +}
  12.163 +
  12.164 +void Window::Destroy_Window()
  12.165 +{
  12.166 +	Destroy_Context();
  12.167 +	if (my_Handle)
  12.168 +	{
  12.169 +		DestroyWindow(my_Handle);
  12.170 +		my_Handle = 0;
  12.171 +
  12.172 +		if (my_Fullscreen)
  12.173 +			ChangeDisplaySettings(NULL, 0);
  12.174 +	}
  12.175 +}
  12.176 +
  12.177 +void Window::Create_Context(const Video_Mode &Mode)
  12.178 +{
  12.179 +	my_Device_Context = GetDC(my_Handle);
  12.180 +	if (!my_Device_Context)
  12.181 +		throw std::runtime_error("Failed to get device context");
  12.182 +
  12.183 +	PIXELFORMATDESCRIPTOR Pixel_Descriptor = {0};
  12.184 +	Pixel_Descriptor.nSize = sizeof(Pixel_Descriptor);
  12.185 +	Pixel_Descriptor.nVersion = 1;
  12.186 +	Pixel_Descriptor.iLayerType = PFD_MAIN_PLANE;
  12.187 +	Pixel_Descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
  12.188 +	Pixel_Descriptor.iPixelType = PFD_TYPE_RGBA;
  12.189 +	Pixel_Descriptor.cColorBits = static_cast<BYTE>(Mode.Bits_Per_Pixel);
  12.190 +	Pixel_Descriptor.cDepthBits = 24;
  12.191 +	Pixel_Descriptor.cStencilBits = 8;
  12.192 +	Pixel_Descriptor.cAlphaBits = Mode.Bits_Per_Pixel == 32 ? 8 : 0;
  12.193 +
  12.194 +	int Best_Format = ChoosePixelFormat(my_Device_Context, &Pixel_Descriptor);
  12.195 +	if (0 == Best_Format)
  12.196 +		throw std::runtime_error("Failed to find suitable pixel format");
  12.197 +
  12.198 +	PIXELFORMATDESCRIPTOR Actual_Format = {0};
  12.199 +	Actual_Format.nSize = sizeof(Actual_Format);
  12.200 +	Actual_Format.nVersion = 1;
  12.201 +	DescribePixelFormat(my_Device_Context, Best_Format, sizeof(Actual_Format), &Actual_Format);
  12.202 +	if (!SetPixelFormat(my_Device_Context, Best_Format, &Actual_Format))
  12.203 +		throw std::runtime_error("Failed to set device pixel format");
  12.204 +
  12.205 +	my_GL_Context = wglCreateContext(my_Device_Context);
  12.206 +	if (!my_GL_Context)
  12.207 +		throw std::runtime_error("Failed to create OpenGL context");
  12.208 +
  12.209 +	wglMakeCurrent(my_Device_Context, my_GL_Context);
  12.210 +}
  12.211 +
  12.212 +void Window::Destroy_Context()
  12.213 +{
  12.214 +	if (my_GL_Context)
  12.215 +	{
  12.216 +		wglDeleteContext(my_GL_Context);
  12.217 +		my_GL_Context = 0;
  12.218 +	}
  12.219 +	if (my_Device_Context)
  12.220 +	{
  12.221 +		ReleaseDC(my_Handle, my_Device_Context);
  12.222 +		my_Device_Context = 0;
  12.223 +	}
  12.224 +}
  12.225 +
  12.226 +void Window::Switch_To_Fullscreen(const Video_Mode &Mode)
  12.227 +{
  12.228 +	DEVMODE Device_Mode = {0};
  12.229 +	Device_Mode.dmSize = sizeof(Device_Mode);
  12.230 +	Device_Mode.dmPelsWidth = Mode.Width;
  12.231 +	Device_Mode.dmPelsHeight = Mode.Height;
  12.232 +	Device_Mode.dmBitsPerPel = Mode.Bits_Per_Pixel;
  12.233 +	Device_Mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
  12.234 +
  12.235 +	if (DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettings(&Device_Mode, CDS_FULLSCREEN))
  12.236 +		throw std::runtime_error("Failed to change to fullscreen mode");
  12.237 +
  12.238 +	SetWindowLong(my_Handle, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
  12.239 +	SetWindowLong(my_Handle, GWL_EXSTYLE, WS_EX_APPWINDOW);
  12.240 +
  12.241 +	SetWindowPos(my_Handle, HWND_TOP, 0, 0, Mode.Width, Mode.Height, SWP_FRAMECHANGED);
  12.242 +}
  12.243 +
  12.244 +LRESULT CALLBACK Window::Window_Procedure(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam)
  12.245 +{
  12.246 +	switch (Message)
  12.247 +	{
  12.248 +	case WM_CREATE:
  12.249 +		{
  12.250 +			LONG This = reinterpret_cast<LONG>(reinterpret_cast<CREATESTRUCT *>(lParam)->lpCreateParams);
  12.251 +			SetWindowLongPtr(Handle, GWLP_USERDATA, This);
  12.252 +			return 0;
  12.253 +		}
  12.254 +		break;
  12.255 +	case WM_DESTROY:
  12.256 +		PostQuitMessage(0);
  12.257 +		return 0;
  12.258 +		break;
  12.259 +	default:
  12.260 +		{
  12.261 +			Window* Win = reinterpret_cast<Window *>(GetWindowLongPtr(Handle, GWLP_USERDATA));
  12.262 +			if (Win)
  12.263 +				return Win->Handle_Message(Handle, Message, wParam, lParam);
  12.264 +		}
  12.265 +		break;
  12.266 +	}
  12.267 +	return DefWindowProcW(Handle, Message, wParam, lParam);
  12.268 +}
  12.269 +
  12.270 +#define Call_Listener(x)\
  12.271 +	if (my_Listener) my_Listener->x
  12.272 +
  12.273 +LRESULT Window::Handle_Message(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam)
  12.274 +{
  12.275 +	bool IMM_Message = false;
  12.276 +	LRESULT Result = my_IMM.Handle_Message(Handle, Message, wParam, lParam, IMM_Message);
  12.277 +	if (IMM_Message)
  12.278 +		return Result;
  12.279 +
  12.280 +	switch (Message)
  12.281 +	{
  12.282 +	case WM_SIZE:
  12.283 +		Call_Listener(On_Resized(LOWORD(lParam), HIWORD(lParam)));
  12.284 +		break;
  12.285 +	case WM_CLOSE:
  12.286 +		Call_Listener(On_Close());
  12.287 +		break;
  12.288 +	case WM_KEYDOWN:
  12.289 +		Call_Listener(On_Key_Down(wParam));
  12.290 +		break;
  12.291 +	case WM_KEYUP:
  12.292 +		Call_Listener(On_Key_Up(wParam));
  12.293 +		break;
  12.294 +	case WM_CHAR:
  12.295 +		Call_Listener(On_Char(wParam));
  12.296 +		break;
  12.297 +	case WM_SETFOCUS:
  12.298 +			my_IMM.Focus_Gained();
  12.299 +		break;
  12.300 +	case WM_KILLFOCUS:
  12.301 +			my_IMM.Focus_Lost();
  12.302 +		break;
  12.303 +	case WM_LBUTTONDOWN:
  12.304 +		Call_Listener(On_Mouse_Button_Down(Mouse_Button_Left));
  12.305 +		break;
  12.306 +	case WM_LBUTTONUP:
  12.307 +		Call_Listener(On_Mouse_Button_Up(Mouse_Button_Left));
  12.308 +		break;
  12.309 +	case WM_RBUTTONDOWN:
  12.310 +		Call_Listener(On_Mouse_Button_Down(Mouse_Button_Right));
  12.311 +		break;
  12.312 +	case WM_RBUTTONUP:
  12.313 +		Call_Listener(On_Mouse_Button_Up(Mouse_Button_Right));
  12.314 +		break;
  12.315 +	default:
  12.316 +		return DefWindowProcW(Handle, Message, wParam, lParam);
  12.317 +		break;
  12.318 +	}
  12.319 +	return 0;
  12.320 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/EXCLUDE/GLTSF/GLTSF.sln	Sun Aug 22 12:39:27 2010 -0700
    13.3 @@ -0,0 +1,20 @@
    13.4 +
    13.5 +Microsoft Visual Studio Solution File, Format Version 11.00
    13.6 +# Visual Studio 2010
    13.7 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GLTSF", "GLTSF.vcxproj", "{790D58BA-E5F6-4286-A9C6-0DC28779789D}"
    13.8 +EndProject
    13.9 +Global
   13.10 +	GlobalSection(SolutionConfigurationPlatforms) = preSolution
   13.11 +		Debug|Win32 = Debug|Win32
   13.12 +		Release|Win32 = Release|Win32
   13.13 +	EndGlobalSection
   13.14 +	GlobalSection(ProjectConfigurationPlatforms) = postSolution
   13.15 +		{790D58BA-E5F6-4286-A9C6-0DC28779789D}.Debug|Win32.ActiveCfg = Debug|Win32
   13.16 +		{790D58BA-E5F6-4286-A9C6-0DC28779789D}.Debug|Win32.Build.0 = Debug|Win32
   13.17 +		{790D58BA-E5F6-4286-A9C6-0DC28779789D}.Release|Win32.ActiveCfg = Release|Win32
   13.18 +		{790D58BA-E5F6-4286-A9C6-0DC28779789D}.Release|Win32.Build.0 = Release|Win32
   13.19 +	EndGlobalSection
   13.20 +	GlobalSection(SolutionProperties) = preSolution
   13.21 +		HideSolutionNode = FALSE
   13.22 +	EndGlobalSection
   13.23 +EndGlobal
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/EXCLUDE/GLTSF/GLTSF.vcproj	Sun Aug 22 12:39:27 2010 -0700
    14.3 @@ -0,0 +1,231 @@
    14.4 +<?xml version="1.0" encoding="Windows-1252"?>
    14.5 +<VisualStudioProject
    14.6 +	ProjectType="Visual C++"
    14.7 +	Version="9.00"
    14.8 +	Name="GLTSF"
    14.9 +	ProjectGUID="{FC8A9A48-6667-4BDE-8E9B-5859408AEE83}"
   14.10 +	RootNamespace="GLTSF"
   14.11 +	Keyword="Win32Proj"
   14.12 +	TargetFrameworkVersion="196613"
   14.13 +	>
   14.14 +	<Platforms>
   14.15 +		<Platform
   14.16 +			Name="Win32"
   14.17 +		/>
   14.18 +	</Platforms>
   14.19 +	<ToolFiles>
   14.20 +	</ToolFiles>
   14.21 +	<Configurations>
   14.22 +		<Configuration
   14.23 +			Name="Debug|Win32"
   14.24 +			OutputDirectory="$(SolutionDir)bin"
   14.25 +			IntermediateDirectory="obj\$(ConfigurationName)"
   14.26 +			ConfigurationType="1"
   14.27 +			CharacterSet="1"
   14.28 +			>
   14.29 +			<Tool
   14.30 +				Name="VCPreBuildEventTool"
   14.31 +			/>
   14.32 +			<Tool
   14.33 +				Name="VCCustomBuildTool"
   14.34 +			/>
   14.35 +			<Tool
   14.36 +				Name="VCXMLDataGeneratorTool"
   14.37 +			/>
   14.38 +			<Tool
   14.39 +				Name="VCWebServiceProxyGeneratorTool"
   14.40 +			/>
   14.41 +			<Tool
   14.42 +				Name="VCMIDLTool"
   14.43 +			/>
   14.44 +			<Tool
   14.45 +				Name="VCCLCompilerTool"
   14.46 +				Optimization="0"
   14.47 +				AdditionalIncludeDirectories="include"
   14.48 +				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
   14.49 +				MinimalRebuild="true"
   14.50 +				BasicRuntimeChecks="3"
   14.51 +				RuntimeLibrary="3"
   14.52 +				UsePrecompiledHeader="0"
   14.53 +				WarningLevel="3"
   14.54 +				DebugInformationFormat="4"
   14.55 +			/>
   14.56 +			<Tool
   14.57 +				Name="VCManagedResourceCompilerTool"
   14.58 +			/>
   14.59 +			<Tool
   14.60 +				Name="VCResourceCompilerTool"
   14.61 +			/>
   14.62 +			<Tool
   14.63 +				Name="VCPreLinkEventTool"
   14.64 +			/>
   14.65 +			<Tool
   14.66 +				Name="VCLinkerTool"
   14.67 +				LinkIncremental="2"
   14.68 +				GenerateDebugInformation="true"
   14.69 +				SubSystem="1"
   14.70 +				TargetMachine="1"
   14.71 +			/>
   14.72 +			<Tool
   14.73 +				Name="VCALinkTool"
   14.74 +			/>
   14.75 +			<Tool
   14.76 +				Name="VCManifestTool"
   14.77 +			/>
   14.78 +			<Tool
   14.79 +				Name="VCXDCMakeTool"
   14.80 +			/>
   14.81 +			<Tool
   14.82 +				Name="VCBscMakeTool"
   14.83 +			/>
   14.84 +			<Tool
   14.85 +				Name="VCFxCopTool"
   14.86 +			/>
   14.87 +			<Tool
   14.88 +				Name="VCAppVerifierTool"
   14.89 +			/>
   14.90 +			<Tool
   14.91 +				Name="VCPostBuildEventTool"
   14.92 +			/>
   14.93 +		</Configuration>
   14.94 +		<Configuration
   14.95 +			Name="Release|Win32"
   14.96 +			OutputDirectory="$(SolutionDir)bin"
   14.97 +			IntermediateDirectory="obj\$(ConfigurationName)"
   14.98 +			ConfigurationType="1"
   14.99 +			CharacterSet="1"
  14.100 +			WholeProgramOptimization="1"
  14.101 +			>
  14.102 +			<Tool
  14.103 +				Name="VCPreBuildEventTool"
  14.104 +			/>
  14.105 +			<Tool
  14.106 +				Name="VCCustomBuildTool"
  14.107 +			/>
  14.108 +			<Tool
  14.109 +				Name="VCXMLDataGeneratorTool"
  14.110 +			/>
  14.111 +			<Tool
  14.112 +				Name="VCWebServiceProxyGeneratorTool"
  14.113 +			/>
  14.114 +			<Tool
  14.115 +				Name="VCMIDLTool"
  14.116 +			/>
  14.117 +			<Tool
  14.118 +				Name="VCCLCompilerTool"
  14.119 +				Optimization="2"
  14.120 +				EnableIntrinsicFunctions="true"
  14.121 +				AdditionalIncludeDirectories="include"
  14.122 +				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
  14.123 +				RuntimeLibrary="2"
  14.124 +				EnableFunctionLevelLinking="true"
  14.125 +				UsePrecompiledHeader="0"
  14.126 +				WarningLevel="3"
  14.127 +				DebugInformationFormat="3"
  14.128 +			/>
  14.129 +			<Tool
  14.130 +				Name="VCManagedResourceCompilerTool"
  14.131 +			/>
  14.132 +			<Tool
  14.133 +				Name="VCResourceCompilerTool"
  14.134 +			/>
  14.135 +			<Tool
  14.136 +				Name="VCPreLinkEventTool"
  14.137 +			/>
  14.138 +			<Tool
  14.139 +				Name="VCLinkerTool"
  14.140 +				LinkIncremental="1"
  14.141 +				GenerateDebugInformation="true"
  14.142 +				SubSystem="1"
  14.143 +				OptimizeReferences="2"
  14.144 +				EnableCOMDATFolding="2"
  14.145 +				TargetMachine="1"
  14.146 +			/>
  14.147 +			<Tool
  14.148 +				Name="VCALinkTool"
  14.149 +			/>
  14.150 +			<Tool
  14.151 +				Name="VCManifestTool"
  14.152 +			/>
  14.153 +			<Tool
  14.154 +				Name="VCXDCMakeTool"
  14.155 +			/>
  14.156 +			<Tool
  14.157 +				Name="VCBscMakeTool"
  14.158 +			/>
  14.159 +			<Tool
  14.160 +				Name="VCFxCopTool"
  14.161 +			/>
  14.162 +			<Tool
  14.163 +				Name="VCAppVerifierTool"
  14.164 +			/>
  14.165 +			<Tool
  14.166 +				Name="VCPostBuildEventTool"
  14.167 +			/>
  14.168 +		</Configuration>
  14.169 +	</Configurations>
  14.170 +	<References>
  14.171 +	</References>
  14.172 +	<Files>
  14.173 +		<Filter
  14.174 +			Name="Source Files"
  14.175 +			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
  14.176 +			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
  14.177 +			>
  14.178 +			<File
  14.179 +				RelativePath=".\src\App.cpp"
  14.180 +				>
  14.181 +			</File>
  14.182 +			<File
  14.183 +				RelativePath=".\src\Main.cpp"
  14.184 +				>
  14.185 +			</File>
  14.186 +			<File
  14.187 +				RelativePath=".\src\TSF.cpp"
  14.188 +				>
  14.189 +			</File>
  14.190 +			<File
  14.191 +				RelativePath=".\src\Video_Mode.cpp"
  14.192 +				>
  14.193 +			</File>
  14.194 +			<File
  14.195 +				RelativePath=".\src\Window.cpp"
  14.196 +				>
  14.197 +			</File>
  14.198 +		</Filter>
  14.199 +		<Filter
  14.200 +			Name="Header Files"
  14.201 +			Filter="h;hpp;hxx;hm;inl;inc;xsd"
  14.202 +			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
  14.203 +			>
  14.204 +			<File
  14.205 +				RelativePath=".\include\App.hpp"
  14.206 +				>
  14.207 +			</File>
  14.208 +			<File
  14.209 +				RelativePath=".\include\TSF.hpp"
  14.210 +				>
  14.211 +			</File>
  14.212 +			<File
  14.213 +				RelativePath=".\include\Video_Mode.hpp"
  14.214 +				>
  14.215 +			</File>
  14.216 +			<File
  14.217 +				RelativePath=".\include\Window.hpp"
  14.218 +				>
  14.219 +			</File>
  14.220 +			<File
  14.221 +				RelativePath=".\include\Window_Listener.hpp"
  14.222 +				>
  14.223 +			</File>
  14.224 +		</Filter>
  14.225 +		<Filter
  14.226 +			Name="Resource Files"
  14.227 +			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
  14.228 +			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
  14.229 +			>
  14.230 +		</Filter>
  14.231 +	</Files>
  14.232 +	<Globals>
  14.233 +	</Globals>
  14.234 +</VisualStudioProject>
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/EXCLUDE/GLTSF/GLTSF.vcxproj	Sun Aug 22 12:39:27 2010 -0700
    15.3 @@ -0,0 +1,99 @@
    15.4 +<?xml version="1.0" encoding="utf-8"?>
    15.5 +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    15.6 +  <ItemGroup Label="ProjectConfigurations">
    15.7 +    <ProjectConfiguration Include="Debug|Win32">
    15.8 +      <Configuration>Debug</Configuration>
    15.9 +      <Platform>Win32</Platform>
   15.10 +    </ProjectConfiguration>
   15.11 +    <ProjectConfiguration Include="Release|Win32">
   15.12 +      <Configuration>Release</Configuration>
   15.13 +      <Platform>Win32</Platform>
   15.14 +    </ProjectConfiguration>
   15.15 +  </ItemGroup>
   15.16 +  <PropertyGroup Label="Globals">
   15.17 +    <ProjectGuid>{790D58BA-E5F6-4286-A9C6-0DC28779789D}</ProjectGuid>
   15.18 +    <Keyword>Win32Proj</Keyword>
   15.19 +    <RootNamespace>GLTSF</RootNamespace>
   15.20 +  </PropertyGroup>
   15.21 +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   15.22 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
   15.23 +    <ConfigurationType>Application</ConfigurationType>
   15.24 +    <UseDebugLibraries>true</UseDebugLibraries>
   15.25 +    <CharacterSet>Unicode</CharacterSet>
   15.26 +  </PropertyGroup>
   15.27 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
   15.28 +    <ConfigurationType>Application</ConfigurationType>
   15.29 +    <UseDebugLibraries>false</UseDebugLibraries>
   15.30 +    <WholeProgramOptimization>true</WholeProgramOptimization>
   15.31 +    <CharacterSet>Unicode</CharacterSet>
   15.32 +  </PropertyGroup>
   15.33 +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   15.34 +  <ImportGroup Label="ExtensionSettings">
   15.35 +  </ImportGroup>
   15.36 +  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
   15.37 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   15.38 +  </ImportGroup>
   15.39 +  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   15.40 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   15.41 +  </ImportGroup>
   15.42 +  <PropertyGroup Label="UserMacros" />
   15.43 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
   15.44 +    <LinkIncremental>true</LinkIncremental>
   15.45 +    <OutDir>$(SolutionDir)bin\</OutDir>
   15.46 +    <IntDir>obj\$(Configuration)\</IntDir>
   15.47 +  </PropertyGroup>
   15.48 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   15.49 +    <LinkIncremental>false</LinkIncremental>
   15.50 +    <OutDir>$(SolutionDir)bin\</OutDir>
   15.51 +    <IntDir>obj\$(Configuration)\</IntDir>
   15.52 +  </PropertyGroup>
   15.53 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
   15.54 +    <ClCompile>
   15.55 +      <PrecompiledHeader>
   15.56 +      </PrecompiledHeader>
   15.57 +      <WarningLevel>Level3</WarningLevel>
   15.58 +      <Optimization>Disabled</Optimization>
   15.59 +      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
   15.60 +      <AdditionalIncludeDirectories>include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
   15.61 +    </ClCompile>
   15.62 +    <Link>
   15.63 +      <SubSystem>Console</SubSystem>
   15.64 +      <GenerateDebugInformation>true</GenerateDebugInformation>
   15.65 +    </Link>
   15.66 +  </ItemDefinitionGroup>
   15.67 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   15.68 +    <ClCompile>
   15.69 +      <WarningLevel>Level3</WarningLevel>
   15.70 +      <PrecompiledHeader>
   15.71 +      </PrecompiledHeader>
   15.72 +      <Optimization>MaxSpeed</Optimization>
   15.73 +      <FunctionLevelLinking>true</FunctionLevelLinking>
   15.74 +      <IntrinsicFunctions>true</IntrinsicFunctions>
   15.75 +      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
   15.76 +      <AdditionalIncludeDirectories>include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
   15.77 +    </ClCompile>
   15.78 +    <Link>
   15.79 +      <SubSystem>Console</SubSystem>
   15.80 +      <GenerateDebugInformation>true</GenerateDebugInformation>
   15.81 +      <EnableCOMDATFolding>true</EnableCOMDATFolding>
   15.82 +      <OptimizeReferences>true</OptimizeReferences>
   15.83 +    </Link>
   15.84 +  </ItemDefinitionGroup>
   15.85 +  <ItemGroup>
   15.86 +    <ClInclude Include="include\App.hpp" />
   15.87 +    <ClInclude Include="include\TSF.hpp" />
   15.88 +    <ClInclude Include="include\Video_Mode.hpp" />
   15.89 +    <ClInclude Include="include\Window.hpp" />
   15.90 +    <ClInclude Include="include\Window_Listener.hpp" />
   15.91 +  </ItemGroup>
   15.92 +  <ItemGroup>
   15.93 +    <ClCompile Include="src\App.cpp" />
   15.94 +    <ClCompile Include="src\Main.cpp" />
   15.95 +    <ClCompile Include="src\TSF.cpp" />
   15.96 +    <ClCompile Include="src\Video_Mode.cpp" />
   15.97 +    <ClCompile Include="src\Window.cpp" />
   15.98 +  </ItemGroup>
   15.99 +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  15.100 +  <ImportGroup Label="ExtensionTargets">
  15.101 +  </ImportGroup>
  15.102 +</Project>
  15.103 \ No newline at end of file
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/EXCLUDE/GLTSF/GLTSF.vcxproj.filters	Sun Aug 22 12:39:27 2010 -0700
    16.3 @@ -0,0 +1,51 @@
    16.4 +<?xml version="1.0" encoding="utf-8"?>
    16.5 +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    16.6 +  <ItemGroup>
    16.7 +    <Filter Include="Source Files">
    16.8 +      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
    16.9 +      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
   16.10 +    </Filter>
   16.11 +    <Filter Include="Header Files">
   16.12 +      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
   16.13 +      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
   16.14 +    </Filter>
   16.15 +    <Filter Include="Resource Files">
   16.16 +      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
   16.17 +      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
   16.18 +    </Filter>
   16.19 +  </ItemGroup>
   16.20 +  <ItemGroup>
   16.21 +    <ClInclude Include="include\App.hpp">
   16.22 +      <Filter>Header Files</Filter>
   16.23 +    </ClInclude>
   16.24 +    <ClInclude Include="include\Video_Mode.hpp">
   16.25 +      <Filter>Header Files</Filter>
   16.26 +    </ClInclude>
   16.27 +    <ClInclude Include="include\Window.hpp">
   16.28 +      <Filter>Header Files</Filter>
   16.29 +    </ClInclude>
   16.30 +    <ClInclude Include="include\Window_Listener.hpp">
   16.31 +      <Filter>Header Files</Filter>
   16.32 +    </ClInclude>
   16.33 +    <ClInclude Include="include\TSF.hpp">
   16.34 +      <Filter>Header Files</Filter>
   16.35 +    </ClInclude>
   16.36 +  </ItemGroup>
   16.37 +  <ItemGroup>
   16.38 +    <ClCompile Include="src\App.cpp">
   16.39 +      <Filter>Source Files</Filter>
   16.40 +    </ClCompile>
   16.41 +    <ClCompile Include="src\Main.cpp">
   16.42 +      <Filter>Source Files</Filter>
   16.43 +    </ClCompile>
   16.44 +    <ClCompile Include="src\Video_Mode.cpp">
   16.45 +      <Filter>Source Files</Filter>
   16.46 +    </ClCompile>
   16.47 +    <ClCompile Include="src\Window.cpp">
   16.48 +      <Filter>Source Files</Filter>
   16.49 +    </ClCompile>
   16.50 +    <ClCompile Include="src\TSF.cpp">
   16.51 +      <Filter>Source Files</Filter>
   16.52 +    </ClCompile>
   16.53 +  </ItemGroup>
   16.54 +</Project>
   16.55 \ No newline at end of file
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/EXCLUDE/GLTSF/GLTSF_vs2008.sln	Sun Aug 22 12:39:27 2010 -0700
    17.3 @@ -0,0 +1,20 @@
    17.4 +
    17.5 +Microsoft Visual Studio Solution File, Format Version 10.00
    17.6 +# Visual Studio 2008
    17.7 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GLTSF", "GLTSF.vcproj", "{FC8A9A48-6667-4BDE-8E9B-5859408AEE83}"
    17.8 +EndProject
    17.9 +Global
   17.10 +	GlobalSection(SolutionConfigurationPlatforms) = preSolution
   17.11 +		Debug|Win32 = Debug|Win32
   17.12 +		Release|Win32 = Release|Win32
   17.13 +	EndGlobalSection
   17.14 +	GlobalSection(ProjectConfigurationPlatforms) = postSolution
   17.15 +		{FC8A9A48-6667-4BDE-8E9B-5859408AEE83}.Debug|Win32.ActiveCfg = Debug|Win32
   17.16 +		{FC8A9A48-6667-4BDE-8E9B-5859408AEE83}.Debug|Win32.Build.0 = Debug|Win32
   17.17 +		{FC8A9A48-6667-4BDE-8E9B-5859408AEE83}.Release|Win32.ActiveCfg = Release|Win32
   17.18 +		{FC8A9A48-6667-4BDE-8E9B-5859408AEE83}.Release|Win32.Build.0 = Release|Win32
   17.19 +	EndGlobalSection
   17.20 +	GlobalSection(SolutionProperties) = preSolution
   17.21 +		HideSolutionNode = FALSE
   17.22 +	EndGlobalSection
   17.23 +EndGlobal
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/EXCLUDE/GLTSF/include/App.hpp	Sun Aug 22 12:39:27 2010 -0700
    18.3 @@ -0,0 +1,36 @@
    18.4 +#ifndef APP_HPP
    18.5 +#define APP_HPP
    18.6 +
    18.7 +#include "Window.hpp"
    18.8 +
    18.9 +class App : public Window_Listener
   18.10 +{
   18.11 +public:
   18.12 +	App();
   18.13 +	virtual ~App();
   18.14 +
   18.15 +	void Initialize();
   18.16 +	void Finalize();
   18.17 +
   18.18 +	void Run();
   18.19 +
   18.20 +	virtual void On_Close();
   18.21 +	virtual void On_Key_Down(int Key);
   18.22 +	virtual void On_Key_Up(int Key);
   18.23 +	virtual void On_Char(unsigned int Char);
   18.24 +	virtual void On_Resized(unsigned int Width, unsigned int Height);
   18.25 +
   18.26 +private:
   18.27 +	void Update();
   18.28 +	void Draw();
   18.29 +
   18.30 +	static const int Width = 800;
   18.31 +	static const int Height = 600;
   18.32 +	static const int Bits_Per_Pixel = 32;
   18.33 +	static const bool Fullscreen = true;
   18.34 +
   18.35 +	Window my_Window;
   18.36 +	bool my_Done;
   18.37 +};
   18.38 +
   18.39 +#endif
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/EXCLUDE/GLTSF/include/TSF.hpp	Sun Aug 22 12:39:27 2010 -0700
    19.3 @@ -0,0 +1,83 @@
    19.4 +#ifndef TSF_HPP
    19.5 +#define TSF_HPP
    19.6 +
    19.7 +#include <msctf.h>
    19.8 +#include <atlbase.h>
    19.9 +
   19.10 +class TSF
   19.11 +{
   19.12 +public:
   19.13 +	static void Initialize();
   19.14 +	static void Finalize();
   19.15 +
   19.16 +private:
   19.17 +	class TSF_Text_Store : public ITextStoreACP, public ITfContextOwnerCompositionSink
   19.18 +	{
   19.19 +	public:
   19.20 +		//IUnknown
   19.21 +		STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject);
   19.22 +		STDMETHODIMP_(ULONG) AddRef();
   19.23 +		STDMETHODIMP_(ULONG) Release();
   19.24 +
   19.25 +		//ITextStoreACP
   19.26 +		STDMETHODIMP AdviseSink(REFIID riid, IUnknown *punk, DWORD dwMask);
   19.27 +		STDMETHODIMP UnadviseSink(IUnknown *punk);
   19.28 +		STDMETHODIMP RequestLock(DWORD dwLockFlags, HRESULT *phrSession);
   19.29 +		STDMETHODIMP GetStatus(TS_STATUS *pdcs);
   19.30 +		STDMETHODIMP QueryInsert(LONG acpTestStart, LONG acpTestEnd, ULONG cch, LONG *pacpResultStart, LONG *pacpResultEnd);
   19.31 +		STDMETHODIMP GetSelection(ULONG ulIndex, ULONG ulCount, TS_SELECTION_ACP *pSelection, ULONG *pcFetched);
   19.32 +		STDMETHODIMP SetSelection(ULONG ulCount, const TS_SELECTION_ACP *pSelection);
   19.33 +		STDMETHODIMP GetText(LONG acpStart, LONG acpEnd, WCHAR *pchPlain, ULONG cchPlainReq, ULONG *pcchPlainRet, TS_RUNINFO *prgRunInfo, ULONG cRunInfoReq, ULONG *pcRunInfoRet, LONG *pacpNext);
   19.34 +		STDMETHODIMP SetText(DWORD dwFlags, LONG acpStart, LONG acpEnd, const WCHAR *pchText, ULONG cch, TS_TEXTCHANGE *pChange);
   19.35 +		STDMETHODIMP GetFormattedText(LONG acpStart, LONG acpEnd, IDataObject **ppDataObject);
   19.36 +		STDMETHODIMP GetEmbedded(LONG acpPos, REFGUID rguidService, REFIID riid, IUnknown **ppunk);
   19.37 +		STDMETHODIMP QueryInsertEmbedded(const GUID *pguidService, const FORMATETC *pFormatEtc, BOOL *pfInsertable);
   19.38 +		STDMETHODIMP InsertEmbedded(DWORD dwFlags, LONG acpStart, LONG acpEnd, IDataObject *pDataObject, TS_TEXTCHANGE *pChange);
   19.39 +		STDMETHODIMP InsertTextAtSelection(DWORD dwFlags, const WCHAR *pchText, ULONG cch, LONG *pacpStart, LONG *pacpEnd, TS_TEXTCHANGE *pChange);
   19.40 +		STDMETHODIMP InsertEmbeddedAtSelection(DWORD dwFlags, IDataObject *pDataObject, LONG *pacpStart, LONG *pacpEnd, TS_TEXTCHANGE *pChange);
   19.41 +		STDMETHODIMP RequestSupportedAttrs(DWORD dwFlags, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs);
   19.42 +		STDMETHODIMP RequestAttrsAtPosition(LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags);
   19.43 +		STDMETHODIMP RequestAttrsTransitioningAtPosition(LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags);
   19.44 +		STDMETHODIMP FindNextAttrTransition(LONG acpStart, LONG acpHalt, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags, LONG *pacpNext, BOOL *pfFound, LONG *plFoundOffset);
   19.45 +		STDMETHODIMP RetrieveRequestedAttrs(ULONG ulCount, TS_ATTRVAL *paAttrVals, ULONG *pcFetched);
   19.46 +		STDMETHODIMP GetEndACP(LONG *pacp);
   19.47 +		STDMETHODIMP GetActiveView(TsViewCookie *pvcView);
   19.48 +		STDMETHODIMP GetACPFromPoint(TsViewCookie vcView, const POINT *ptScreen, DWORD dwFlags, LONG *pacp);
   19.49 +		STDMETHODIMP GetTextExt(TsViewCookie vcView, LONG acpStart, LONG acpEnd, RECT *prc, BOOL *pfClipped);
   19.50 +		STDMETHODIMP GetScreenExt(TsViewCookie vcView, RECT *prc);
   19.51 +		STDMETHODIMP GetWnd(TsViewCookie vcView, HWND *phwnd);
   19.52 +
   19.53 +		//ITfOwnerCompositionSink
   19.54 +		STDMETHODIMP OnStartComposition(ITfCompositionView *pComposition, BOOL *pfOk);
   19.55 +		STDMETHODIMP OnUpdateComposition(ITfCompositionView *pComposition, ITfRange *pRangeNew);
   19.56 +		STDMETHODIMP OnEndComposition(ITfCompositionView *pComposition);
   19.57 +
   19.58 +		void Initialize();
   19.59 +		void Finalize();
   19.60 +
   19.61 +		TSF_Text_Store();
   19.62 +		~TSF_Text_Store();
   19.63 +
   19.64 +	private:
   19.65 +		ULONG my_Reference_Count;
   19.66 +		CComPtr<ITfDocumentMgr> my_Document_Manager;
   19.67 +		CComPtr<ITfContext> my_Context;
   19.68 +		DWORD my_Edit_Cookie;
   19.69 +		CComPtr<ITextStoreACPSink> my_Sink;
   19.70 +		DWORD my_Sink_Mask;
   19.71 +		DWORD my_Lock;
   19.72 +		DWORD my_Lock_Queued;
   19.73 +		CComPtr<ITfCompositionView> my_Composition_View;
   19.74 +		TS_SELECTION_ACP my_Composition_Selection;
   19.75 +	};
   19.76 +
   19.77 +	TSF();
   19.78 +
   19.79 +	static bool COM_Initialized;
   19.80 +
   19.81 +	static CComPtr<ITfThreadMgr> Thread_Manager;
   19.82 +	static TfClientId Client_Id;
   19.83 +	static TSF_Text_Store *Text_Store;
   19.84 +};
   19.85 +
   19.86 +#endif
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/EXCLUDE/GLTSF/include/Video_Mode.hpp	Sun Aug 22 12:39:27 2010 -0700
    20.3 @@ -0,0 +1,30 @@
    20.4 +#ifndef VIDEO_MODE_HPP
    20.5 +#define VIDEO_MODE_HPP
    20.6 +
    20.7 +#include <cstddef>
    20.8 +
    20.9 +class Video_Mode
   20.10 +{
   20.11 +public:
   20.12 +	Video_Mode();
   20.13 +	Video_Mode(unsigned int The_Width, unsigned int The_Height, unsigned int The_Bits_Per_Pixel);
   20.14 +
   20.15 +	static Video_Mode Get_Desktop_Mode();
   20.16 +
   20.17 +	static std::size_t Get_Mode_Count();
   20.18 +	static Video_Mode Get_Mode(std::size_t Index);
   20.19 +
   20.20 +	bool Is_Valid() const;
   20.21 +
   20.22 +	bool operator==(const Video_Mode &Mode) const;
   20.23 +	bool operator!=(const Video_Mode &Mode) const;
   20.24 +
   20.25 +	unsigned int Width;
   20.26 +	unsigned int Height;
   20.27 +	unsigned int Bits_Per_Pixel;
   20.28 +
   20.29 +private:
   20.30 +	static void Initialize_Modes();
   20.31 +};
   20.32 +
   20.33 +#endif
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/EXCLUDE/GLTSF/include/Window.hpp	Sun Aug 22 12:39:27 2010 -0700
    21.3 @@ -0,0 +1,59 @@
    21.4 +#ifndef WINDOW_HPP
    21.5 +#define WINDOW_HPP
    21.6 +
    21.7 +#include <string>
    21.8 +
    21.9 +#define WIN32_LEAN_AND_MEAN
   21.10 +#include <Windows.h>
   21.11 +
   21.12 +#include "Video_Mode.hpp"
   21.13 +#include "Window_Listener.hpp"
   21.14 +#include "TSF.hpp"
   21.15 +
   21.16 +class Window
   21.17 +{
   21.18 +public:
   21.19 +	Window();
   21.20 +	~Window();
   21.21 +
   21.22 +	void Initialize(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen);
   21.23 +	void Finalize();
   21.24 +
   21.25 +	void Set_Listener(Window_Listener *Listener);
   21.26 +
   21.27 +	void Show();
   21.28 +	void Hide();
   21.29 +
   21.30 +	void Handle_Events();
   21.31 +	void Display();
   21.32 +
   21.33 +	void Show_Cursor();
   21.34 +	void Hide_Cursor();
   21.35 +
   21.36 +private:
   21.37 +	static const wchar_t *Window_Class_Name;
   21.38 +
   21.39 +	void Register_Class();
   21.40 +	void Unregister_Class();
   21.41 +
   21.42 +	void Create_Window(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen);
   21.43 +	void Destroy_Window();
   21.44 +
   21.45 +	void Create_Context(const Video_Mode &Mode);
   21.46 +	void Destroy_Context();
   21.47 +
   21.48 +	void Switch_To_Fullscreen(const Video_Mode &Mode);
   21.49 +
   21.50 +	LRESULT Handle_Message(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam);
   21.51 +	static LRESULT CALLBACK Window_Procedure(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam);
   21.52 +
   21.53 +	HWND my_Handle;
   21.54 +	Video_Mode my_Video_Mode;
   21.55 +	bool my_Fullscreen;
   21.56 +	HDC my_Device_Context;
   21.57 +	HGLRC my_GL_Context;
   21.58 +	bool my_Class_Registered;
   21.59 +	Window_Listener *my_Listener;
   21.60 +};
   21.61 +
   21.62 +#endif
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/EXCLUDE/GLTSF/include/Window_Listener.hpp	Sun Aug 22 12:39:27 2010 -0700
    22.3 @@ -0,0 +1,14 @@
    22.4 +#ifndef WINDOW_LISTENER_HPP
    22.5 +#define WINDOW_LISTENER_HPP
    22.6 +
    22.7 +class Window_Listener
    22.8 +{
    22.9 +public:
   22.10 +	virtual void On_Close(){}
   22.11 +	virtual void On_Key_Down(int Key){}
   22.12 +	virtual void On_Key_Up(int Key){}
   22.13 +	virtual void On_Char(unsigned int Char){}
   22.14 +	virtual void On_Resized(unsigned int Width, unsigned int Height){}
   22.15 +};
   22.16 +
   22.17 +#endif
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/EXCLUDE/GLTSF/src/App.cpp	Sun Aug 22 12:39:27 2010 -0700
    23.3 @@ -0,0 +1,105 @@
    23.4 +#include "App.hpp"
    23.5 +#include "TSF.hpp"
    23.6 +#include <GL/gl.h>
    23.7 +#include <GL/glu.h>
    23.8 +
    23.9 +#pragma comment(lib, "glu32.lib")
   23.10 +
   23.11 +GLfloat Rotation = 0.0f;
   23.12 +
   23.13 +App::App() : my_Done(false)
   23.14 +{
   23.15 +	TSF::Initialize();
   23.16 +}
   23.17 +
   23.18 +App::~App()
   23.19 +{
   23.20 +	Finalize();
   23.21 +	TSF::Finalize();
   23.22 +}
   23.23 +
   23.24 +void App::Initialize()
   23.25 +{
   23.26 +	Finalize();
   23.27 +
   23.28 +	my_Window.Initialize(L"GLTSF", Video_Mode(Width, Height, Bits_Per_Pixel), Fullscreen);
   23.29 +	my_Window.Set_Listener(this);
   23.30 +	my_Window.Show();
   23.31 +	my_Window.Hide_Cursor();
   23.32 +}
   23.33 +
   23.34 +void App::Finalize()
   23.35 +{
   23.36 +	my_Window.Finalize();
   23.37 +}
   23.38 +
   23.39 +void App::Run()
   23.40 +{
   23.41 +	Initialize();
   23.42 +	while (!my_Done)
   23.43 +	{
   23.44 +		my_Window.Handle_Events();
   23.45 +
   23.46 +		Update();
   23.47 +		Draw();
   23.48 +		my_Window.Display();
   23.49 +	}
   23.50 +}
   23.51 +
   23.52 +void App::On_Close()
   23.53 +{
   23.54 +	my_Done = true;
   23.55 +	my_Window.Hide();
   23.56 +}
   23.57 +
   23.58 +void App::On_Key_Down(int Key)
   23.59 +{
   23.60 +	switch (Key)
   23.61 +	{
   23.62 +	case VK_ESCAPE:
   23.63 +		On_Close();
   23.64 +		break;
   23.65 +	}
   23.66 +}
   23.67 +
   23.68 +void App::On_Key_Up(int Key)
   23.69 +{
   23.70 +
   23.71 +}
   23.72 +
   23.73 +void App::On_Char(unsigned int Char)
   23.74 +{
   23.75 +	printf("Char: U+%04X\n", Char);
   23.76 +}
   23.77 +
   23.78 +void App::On_Resized(unsigned int Width, unsigned int Height)
   23.79 +{
   23.80 +	glViewport(0, 0, Width, Height);
   23.81 +	glMatrixMode(GL_PROJECTION);
   23.82 +	glLoadIdentity();
   23.83 +
   23.84 +	glMatrixMode(GL_MODELVIEW);
   23.85 +	glLoadIdentity();
   23.86 +}
   23.87 +
   23.88 +void App::Update()
   23.89 +{
   23.90 +	Rotation += 0.2f;
   23.91 +}
   23.92 +
   23.93 +void App::Draw()
   23.94 +{
   23.95 +	glClear(GL_COLOR_BUFFER_BIT);
   23.96 +
   23.97 +	glLoadIdentity();
   23.98 +	glRotatef(Rotation, 0.0f, 0.0f, -1.0f);
   23.99 +
  23.100 +	glBegin(GL_TRIANGLES);
  23.101 +		glColor3f(0.7f, 0.0f, 0.0f);
  23.102 +		glVertex3f(0.0f, 0.5f, 0.0f);
  23.103 +		glColor3f(0.0f, 0.7f, 0.0f);
  23.104 +		glVertex3f(-0.5f, -0.5f, 0.0f);
  23.105 +		glColor3f(0.0f, 0.0f, 0.7f);
  23.106 +		glVertex3f(0.5f, -0.5f, 0.0f);
  23.107 +	glEnd();
  23.108 +}
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/EXCLUDE/GLTSF/src/Main.cpp	Sun Aug 22 12:39:27 2010 -0700
    24.3 @@ -0,0 +1,24 @@
    24.4 +#include "App.hpp"
    24.5 +#include <stdexcept>
    24.6 +
    24.7 +int main(int argc, char *argv[])
    24.8 +{
    24.9 +	int Result = EXIT_SUCCESS;
   24.10 +	try
   24.11 +	{
   24.12 +		App theApp;
   24.13 +		theApp.Run();
   24.14 +	}
   24.15 +	catch (const std::exception& e)
   24.16 +	{
   24.17 +		printf("Error: %s\n", e.what());
   24.18 +		Result = EXIT_FAILURE;
   24.19 +	}
   24.20 +	catch (...)
   24.21 +	{
   24.22 +		printf("Unhandled exception\n");
   24.23 +		Result = EXIT_FAILURE;
   24.24 +	}
   24.25 +	system("PAUSE");
   24.26 +	return Result;
   24.27 +}
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/EXCLUDE/GLTSF/src/TSF.cpp	Sun Aug 22 12:39:27 2010 -0700
    25.3 @@ -0,0 +1,360 @@
    25.4 +#include "TSF.hpp"
    25.5 +#include <stdexcept>
    25.6 +
    25.7 +bool TSF::COM_Initialized = false;
    25.8 +CComPtr<ITfThreadMgr> TSF::Thread_Manager;
    25.9 +TfClientId TSF::Client_Id;
   25.10 +TSF::TSF_Text_Store *TSF::Text_Store = NULL;
   25.11 +
   25.12 +void TSF::Initialize()
   25.13 +{
   25.14 +	if (!COM_Initialized)
   25.15 +	{
   25.16 +		HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
   25.17 +		if (S_OK != hr && S_FALSE != hr)
   25.18 +			throw std::runtime_error("Failed to initialize COM");
   25.19 +
   25.20 +		COM_Initialized = true;
   25.21 +	}
   25.22 +	if (!Thread_Manager)
   25.23 +	{
   25.24 +		if (FAILED(CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, reinterpret_cast<void **>(&Thread_Manager))))
   25.25 +			throw std::runtime_error("Failed to create ITfThreadMgr instance");
   25.26 +
   25.27 +		if (FAILED(Thread_Manager->Activate(&Client_Id)))
   25.28 +			throw std::runtime_error("ITfThreadMgr::Activate failed");
   25.29 +
   25.30 +		Text_Store = new TSF_Text_Store;
   25.31 +		Text_Store->Initialize();
   25.32 +	}
   25.33 +}
   25.34 +
   25.35 +void TSF::Finalize()
   25.36 +{
   25.37 +	if (Thread_Manager)
   25.38 +	{
   25.39 +		Thread_Manager->Deactivate();
   25.40 +		Thread_Manager = NULL;
   25.41 +	}
   25.42 +	if (COM_Initialized)
   25.43 +	{
   25.44 +		CoUninitialize();
   25.45 +		COM_Initialized = false;
   25.46 +	}
   25.47 +}
   25.48 +
   25.49 +STDMETHODIMP TSF::TSF_Text_Store::QueryInterface(REFIID riid, void **ppvObject)
   25.50 +{
   25.51 +	*ppvObject = NULL;
   25.52 +	if (IID_IUnknown == riid || IID_ITextStoreACP == riid)
   25.53 +		*ppvObject = static_cast<ITextStoreACP *>(this);
   25.54 +	else if (IID_ITfContextOwnerCompositionSink == riid)
   25.55 +		*ppvObject = static_cast<ITfContextOwnerCompositionSink *>(this);
   25.56 +
   25.57 +	if (*ppvObject)
   25.58 +	{
   25.59 +		AddRef();
   25.60 +		return S_OK;
   25.61 +	}
   25.62 +	return E_NOINTERFACE;
   25.63 +}
   25.64 +
   25.65 +STDMETHODIMP_(ULONG) TSF::TSF_Text_Store::AddRef()
   25.66 +{
   25.67 +	return ++my_Reference_Count;
   25.68 +}
   25.69 +
   25.70 +STDMETHODIMP_(ULONG) TSF::TSF_Text_Store::Release()
   25.71 +{
   25.72 +	--my_Reference_Count;
   25.73 +	if (0 != my_Reference_Count)
   25.74 +		return my_Reference_Count;
   25.75 +
   25.76 +	delete this;
   25.77 +	return 0;
   25.78 +}
   25.79 +
   25.80 +#define CHECK_CONDITION(condition, retval, function, line)						\
   25.81 +	if (!condition)																\
   25.82 +	{																			\
   25.83 +		printf("%s:%d: Condition failure: %s\n", function, line, #condition);	\
   25.84 +	}
   25.85 +
   25.86 +#define ENSURE(condition, retval)	CHECK_CONDITION(condition, retval, __FUNCTION__, __LINE__)
   25.87 +
   25.88 +STDMETHODIMP TSF::TSF_Text_Store::AdviseSink(REFIID riid, IUnknown *punk, DWORD dwMask)
   25.89 +{
   25.90 +	ENSURE(punk && IID_ITextStoreACP == riid, E_INVALIDARG);
   25.91 +
   25.92 +	if (!my_Sink)
   25.93 +	{
   25.94 +		HRESULT hr = punk->QueryInterface(&my_Sink);
   25.95 +		ENSURE(SUCCEEDED(hr) && my_Sink, E_UNEXPECTED);
   25.96 +	}
   25.97 +	else
   25.98 +	{
   25.99 +		CComPtr<IUnknown> Unknown_1, Unknown_2;
  25.100 +		punk->QueryInterface(&Unknown_1);
  25.101 +		my_Sink->QueryInterface(&Unknown_2);
  25.102 +		if (Unknown_1 != Unknown_2)
  25.103 +			return CONNECT_E_ADVISELIMIT;
  25.104 +	}
  25.105 +	my_Sink_Mask = dwMask;
  25.106 +	return S_OK;
  25.107 +}
  25.108 +
  25.109 +STDMETHODIMP TSF::TSF_Text_Store::UnadviseSink(IUnknown *punk)
  25.110 +{
  25.111 +	ENSURE(punk, E_INVALIDARG);
  25.112 +	ENSURE(my_Sink, CONNECT_E_NOCONNECTION);
  25.113 +
  25.114 +	CComPtr<IUnknown> Unknown_1, Unknown_2;
  25.115 +	punk->QueryInterface(&Unknown_1);
  25.116 +	my_Sink->QueryInterface(&Unknown_2);
  25.117 +
  25.118 +	if (Unknown_1 != Unknown_2)
  25.119 +		return CONNECT_E_NOCONNECTION;
  25.120 +
  25.121 +	my_Sink = NULL;
  25.122 +	my_Sink_Mask = 0;
  25.123 +	return S_OK;
  25.124 +}
  25.125 +
  25.126 +STDMETHODIMP TSF::TSF_Text_Store::RequestLock(DWORD dwLockFlags, HRESULT *phrSession)
  25.127 +{
  25.128 +	ENSURE(my_Sink, E_FAIL);
  25.129 +	ENSURE(phrSession, E_INVALIDARG);
  25.130 +	if (my_Lock)
  25.131 +	{
  25.132 +		if (TS_LF_READ == (my_Lock & TS_LF_READWRITE)
  25.133 +			&& TS_LF_READWRITE == (dwLockFlags & TS_LF_READWRITE)
  25.134 +			&& !(dwLockFlags & TS_LF_SYNC))
  25.135 +		{
  25.136 +			*phrSession = TS_S_ASYNC;
  25.137 +			my_Lock_Queued = dwLockFlags & (~TS_LF_SYNC);
  25.138 +		}
  25.139 +		else
  25.140 +		{
  25.141 +			*phrSession = TS_E_SYNCHRONOUS;
  25.142 +			return E_FAIL;
  25.143 +		}
  25.144 +	}
  25.145 +	else
  25.146 +	{
  25.147 +		my_Lock = dwLockFlags & (~TS_LF_SYNC);
  25.148 +		*phrSession = my_Sink->OnLockGranted(my_Lock);
  25.149 +		while (my_Lock_Queued)
  25.150 +		{
  25.151 +			my_Lock = my_Lock_Queued;
  25.152 +			my_Lock_Queued = 0;
  25.153 +			my_Sink->OnLockGranted(my_Lock);
  25.154 +		}
  25.155 +		my_Lock = 0;
  25.156 +	}
  25.157 +	return S_OK;
  25.158 +}
  25.159 +
  25.160 +STDMETHODIMP TSF::TSF_Text_Store::GetStatus(TS_STATUS *pdcs)
  25.161 +{
  25.162 +	ENSURE(pdcs, E_INVALIDARG);
  25.163 +	pdcs->dwDynamicFlags = 0;
  25.164 +	pdcs->dwStaticFlags = TS_SS_NOHIDDENTEXT;
  25.165 +	return S_OK;
  25.166 +}
  25.167 +
  25.168 +STDMETHODIMP TSF::TSF_Text_Store::QueryInsert(LONG acpTestStart, LONG acpTestEnd, ULONG cch, LONG *pacpResultStart, LONG *pacpResultEnd)
  25.169 +{
  25.170 +	ENSURE(0 <= acpTestStart && acpTestStart <= acpTestEnd && pacpResultStart && pacpResultEnd, E_INVALIDARG);
  25.171 +
  25.172 +	*pacpResultStart = acpTestStart;
  25.173 +	*pacpResultEnd = acpTestStart + cch;
  25.174 +	return S_OK;
  25.175 +}
  25.176 +
  25.177 +STDMETHODIMP TSF::TSF_Text_Store::GetSelection(ULONG ulIndex, ULONG ulCount, TS_SELECTION_ACP *pSelection, ULONG *pcFetched)
  25.178 +{
  25.179 +	ENSURE(TS_LF_READ == (my_Lock && TS_LF_READ), TS_E_NOLOCK);
  25.180 +	ENSURE(ulCount && pSelection && pcFetched, E_INVALIDARG);
  25.181 +
  25.182 +	*pcFetched = 0;
  25.183 +	ENSURE(TS_DEFAULT_SELECTION == ulIndex || 0 == ulIndex, TS_E_NOSELECTION);
  25.184 +	if (my_Composition_View)
  25.185 +	{
  25.186 +		*pSelection = my_Composition_Selection;
  25.187 +	}
  25.188 +	else
  25.189 +	{
  25.190 +		//TODO
  25.191 +	}
  25.192 +	*pcFetched = 1;
  25.193 +	return S_OK;
  25.194 +}
  25.195 +
  25.196 +STDMETHODIMP TSF::TSF_Text_Store::SetSelection(ULONG ulCount, const TS_SELECTION_ACP *pSelection)
  25.197 +{
  25.198 +	return E_NOTIMPL;
  25.199 +}
  25.200 +
  25.201 +STDMETHODIMP TSF::TSF_Text_Store::GetText(LONG acpStart, LONG acpEnd, WCHAR *pchPlain, ULONG cchPlainReq, ULONG *pcchPlainRet, TS_RUNINFO *prgRunInfo, ULONG cRunInfoReq, ULONG *pcRunInfoRet, LONG *pacpNext)
  25.202 +{
  25.203 +	ENSURE(TS_LF_READ == (my_Lock & TS_LF_READ), TS_E_NOLOCK);
  25.204 +	ENSURE(pcchPlainRet && (pchPlain || prgRunInfo)
  25.205 +		&& (!cchPlainReq == !pchPlain)
  25.206 +		&& (!cRunInfoReq == !prgRunInfo), E_INVALIDARG);
  25.207 +	ENSURE(0 <= acpStart && -1 <= acpEnd
  25.208 +		&& (-1 == acpEnd || acpStart <= acpEnd), TS_E_INVALIDPOS);
  25.209 +
  25.210 +	*pcchPlainRet = 0;
  25.211 +	if (pchPlain && cchPlainReq) *pchPlain = 0;
  25.212 +	if (pcRunInfoRet) *pcRunInfoRet = 0;
  25.213 +	//TODO
  25.214 +	return S_OK;
  25.215 +}
  25.216 +
  25.217 +STDMETHODIMP TSF::TSF_Text_Store::SetText(DWORD dwFlags, LONG acpStart, LONG acpEnd, const WCHAR *pchText, ULONG cch, TS_TEXTCHANGE *pChange)
  25.218 +{
  25.219 +	return E_NOTIMPL;
  25.220 +}
  25.221 +
  25.222 +STDMETHODIMP TSF::TSF_Text_Store::GetFormattedText(LONG acpStart, LONG acpEnd, IDataObject **ppDataObject)
  25.223 +{
  25.224 +	//not needed
  25.225 +	return E_NOTIMPL;
  25.226 +}
  25.227 +
  25.228 +STDMETHODIMP TSF::TSF_Text_Store::GetEmbedded(LONG acpPos, REFGUID rguidService, REFIID riid, IUnknown **ppunk)
  25.229 +{
  25.230 +	//not needed
  25.231 +	return E_NOTIMPL;
  25.232 +}
  25.233 +
  25.234 +STDMETHODIMP TSF::TSF_Text_Store::QueryInsertEmbedded(const GUID *pguidService, const FORMATETC *pFormatEtc, BOOL *pfInsertable)
  25.235 +{
  25.236 +	if (!pfInsertable)
  25.237 +		return E_INVALIDARG;
  25.238 +
  25.239 +	//Not supported
  25.240 +	*pfInsertable = FALSE;
  25.241 +	return E_NOTIMPL;
  25.242 +}
  25.243 +
  25.244 +STDMETHODIMP TSF::TSF_Text_Store::InsertEmbedded(DWORD dwFlags, LONG acpStart, LONG acpEnd, IDataObject *pDataObject, TS_TEXTCHANGE *pChange)
  25.245 +{
  25.246 +	return E_NOTIMPL;
  25.247 +}
  25.248 +
  25.249 +STDMETHODIMP TSF::TSF_Text_Store::InsertTextAtSelection(DWORD dwFlags, const WCHAR *pchText, ULONG cch, LONG *pacpStart, LONG *pacpEnd, TS_TEXTCHANGE *pChange)
  25.250 +{
  25.251 +	return E_NOTIMPL;
  25.252 +}
  25.253 +
  25.254 +STDMETHODIMP TSF::TSF_Text_Store::InsertEmbeddedAtSelection(DWORD dwFlags, IDataObject *pDataObject, LONG *pacpStart, LONG *pacpEnd, TS_TEXTCHANGE *pChange)
  25.255 +{
  25.256 +	//not needed
  25.257 +	return E_NOTIMPL;
  25.258 +}
  25.259 +
  25.260 +STDMETHODIMP TSF::TSF_Text_Store::RequestSupportedAttrs(DWORD dwFlags, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs)
  25.261 +{
  25.262 +	//not needed
  25.263 +	return E_NOTIMPL;
  25.264 +}
  25.265 +
  25.266 +STDMETHODIMP TSF::TSF_Text_Store::RequestAttrsAtPosition(LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags)
  25.267 +{
  25.268 +	//not needed
  25.269 +	return E_NOTIMPL;
  25.270 +}
  25.271 +
  25.272 +STDMETHODIMP TSF::TSF_Text_Store::RequestAttrsTransitioningAtPosition(LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags)
  25.273 +{
  25.274 +	//not needed
  25.275 +	return E_NOTIMPL;
  25.276 +}
  25.277 +
  25.278 +STDMETHODIMP TSF::TSF_Text_Store::FindNextAttrTransition(LONG acpStart, LONG acpHalt, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags, LONG *pacpNext, BOOL *pfFound, LONG *plFoundOffset)
  25.279 +{
  25.280 +	//not needed
  25.281 +	return E_NOTIMPL;
  25.282 +}
  25.283 +
  25.284 +STDMETHODIMP TSF::TSF_Text_Store::RetrieveRequestedAttrs(ULONG ulCount, TS_ATTRVAL *paAttrVals, ULONG *pcFetched)
  25.285 +{
  25.286 +	//not needed
  25.287 +	return E_NOTIMPL;
  25.288 +}
  25.289 +
  25.290 +STDMETHODIMP TSF::TSF_Text_Store::GetEndACP(LONG *pacp)
  25.291 +{
  25.292 +	return E_NOTIMPL;
  25.293 +}
  25.294 +
  25.295 +STDMETHODIMP TSF::TSF_Text_Store::GetActiveView(TsViewCookie *pvcView)
  25.296 +{
  25.297 +	return E_NOTIMPL;
  25.298 +}
  25.299 +
  25.300 +STDMETHODIMP TSF::TSF_Text_Store::GetACPFromPoint(TsViewCookie vcView, const POINT *ptScreen, DWORD dwFlags, LONG *pacp)
  25.301 +{
  25.302 +	return E_NOTIMPL;
  25.303 +}
  25.304 +
  25.305 +STDMETHODIMP TSF::TSF_Text_Store::GetTextExt(TsViewCookie vcView, LONG acpStart, LONG acpEnd, RECT *prc, BOOL *pfClipped)
  25.306 +{
  25.307 +	return E_NOTIMPL;
  25.308 +}
  25.309 +
  25.310 +STDMETHODIMP TSF::TSF_Text_Store::GetScreenExt(TsViewCookie vcView, RECT *prc)
  25.311 +{
  25.312 +	return E_NOTIMPL;
  25.313 +}
  25.314 +
  25.315 +STDMETHODIMP TSF::TSF_Text_Store::GetWnd(TsViewCookie vcView, HWND *phwnd)
  25.316 +{
  25.317 +	return E_NOTIMPL;
  25.318 +}
  25.319 +
  25.320 +STDMETHODIMP TSF::TSF_Text_Store::OnStartComposition(ITfCompositionView *pComposition, BOOL *pfOk)
  25.321 +{
  25.322 +	return E_NOTIMPL;
  25.323 +}
  25.324 +
  25.325 +STDMETHODIMP TSF::TSF_Text_Store::OnUpdateComposition(ITfCompositionView *pComposition, ITfRange *pRangeNew)
  25.326 +{
  25.327 +	return E_NOTIMPL;
  25.328 +}
  25.329 +
  25.330 +STDMETHODIMP TSF::TSF_Text_Store::OnEndComposition(ITfCompositionView *pComposition)
  25.331 +{
  25.332 +	return E_NOTIMPL;
  25.333 +}
  25.334 +
  25.335 +TSF::TSF_Text_Store::TSF_Text_Store() : my_Reference_Count(1),
  25.336 +										my_Edit_Cookie(0),
  25.337 +										my_Lock(0),
  25.338 +										my_Lock_Queued(0)
  25.339 +{
  25.340 +
  25.341 +}
  25.342 +
  25.343 +TSF::TSF_Text_Store::~TSF_Text_Store()
  25.344 +{
  25.345 +
  25.346 +}
  25.347 +
  25.348 +void TSF::TSF_Text_Store::Initialize()
  25.349 +{
  25.350 +	if (FAILED(Thread_Manager->CreateDocumentMgr(&my_Document_Manager)))
  25.351 +		throw std::runtime_error("Failed to create document manager");
  25.352 +
  25.353 +	if (FAILED(my_Document_Manager->CreateContext(Client_Id, 0, static_cast<ITextStoreACP *>(this), &my_Context, &my_Edit_Cookie)))
  25.354 +		throw std::runtime_error("Failed to create document context");
  25.355 +
  25.356 +	if (FAILED(my_Document_Manager->Push(my_Context)))
  25.357 +		throw std::runtime_error("Failed to push context");
  25.358 +}
  25.359 +
  25.360 +void TSF::TSF_Text_Store::Finalize()
  25.361 +{
  25.362 +
  25.363 +}
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/EXCLUDE/GLTSF/src/Video_Mode.cpp	Sun Aug 22 12:39:27 2010 -0700
    26.3 @@ -0,0 +1,100 @@
    26.4 +#include "Video_Mode.hpp"
    26.5 +#include <vector>
    26.6 +#include <algorithm>
    26.7 +#define WIN32_LEAN_AND_MEAN
    26.8 +#include <Windows.h>
    26.9 +
   26.10 +namespace
   26.11 +{
   26.12 +
   26.13 +	typedef std::vector<Video_Mode> Video_Mode_List;
   26.14 +	Video_Mode_List Supported_Modes;
   26.15 +
   26.16 +	struct Compare_Modes
   26.17 +	{
   26.18 +		bool operator()(const Video_Mode &Mode_1, const Video_Mode &Mode_2) const
   26.19 +		{
   26.20 +			if (Mode_1.Bits_Per_Pixel > Mode_2.Bits_Per_Pixel)
   26.21 +				return true;
   26.22 +			else if (Mode_1.Bits_Per_Pixel < Mode_2.Bits_Per_Pixel)
   26.23 +				return false;
   26.24 +			else if (Mode_1.Width > Mode_2.Width)
   26.25 +				return true;
   26.26 +			else if (Mode_1.Width < Mode_2.Width)
   26.27 +				return false;
   26.28 +			else
   26.29 +				return Mode_1.Height > Mode_2.Height;
   26.30 +		}
   26.31 +	};
   26.32 +
   26.33 +}
   26.34 +
   26.35 +Video_Mode::Video_Mode() : Width(0),
   26.36 +						   Height(0),
   26.37 +						   Bits_Per_Pixel(0)
   26.38 +{
   26.39 +
   26.40 +}
   26.41 +
   26.42 +Video_Mode::Video_Mode(unsigned int The_Width, unsigned int The_Height, unsigned int The_Bits_Per_Pixel)
   26.43 +	: Width(The_Width),
   26.44 +	  Height(The_Height),
   26.45 +	  Bits_Per_Pixel(The_Bits_Per_Pixel)
   26.46 +{
   26.47 +
   26.48 +}
   26.49 +
   26.50 +Video_Mode Video_Mode::Get_Desktop_Mode()
   26.51 +{
   26.52 +	DEVMODE Device_Mode = {0};
   26.53 +	Device_Mode.dmSize = sizeof(Device_Mode);
   26.54 +	EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &Device_Mode);
   26.55 +	return Video_Mode(Device_Mode.dmPelsWidth, Device_Mode.dmPelsHeight, Device_Mode.dmBitsPerPel);
   26.56 +}
   26.57 +
   26.58 +std::size_t Video_Mode::Get_Mode_Count()
   26.59 +{
   26.60 +	Initialize_Modes();
   26.61 +	return Supported_Modes.size();
   26.62 +}
   26.63 +
   26.64 +Video_Mode Video_Mode::Get_Mode(std::size_t Index)
   26.65 +{
   26.66 +	Initialize_Modes();
   26.67 +	return Supported_Modes[Index];
   26.68 +}
   26.69 +
   26.70 +bool Video_Mode::Is_Valid() const
   26.71 +{
   26.72 +	Initialize_Modes();
   26.73 +	return Supported_Modes.end() != std::find(Supported_Modes.begin(), Supported_Modes.end(), *this);
   26.74 +}
   26.75 +
   26.76 +bool Video_Mode::operator==(const Video_Mode &Mode) const
   26.77 +{
   26.78 +	return (Width == Mode.Width
   26.79 +		&&  Height == Mode.Height
   26.80 +		&&  Bits_Per_Pixel == Mode.Bits_Per_Pixel);
   26.81 +}
   26.82 +
   26.83 +bool Video_Mode::operator!=(const Video_Mode &Mode) const
   26.84 +{
   26.85 +	return !(*this == Mode);
   26.86 +}
   26.87 +
   26.88 +void Video_Mode::Initialize_Modes()
   26.89 +{
   26.90 +	static bool Initialized = false;
   26.91 +	if (!Initialized)
   26.92 +	{
   26.93 +		DEVMODE Device_Mode = {0};
   26.94 +		Device_Mode.dmSize = sizeof(Device_Mode);
   26.95 +		for (std::size_t i = 0; 0 != EnumDisplaySettings(NULL, i, &Device_Mode); ++i)
   26.96 +		{
   26.97 +			Video_Mode Mode(Device_Mode.dmPelsWidth, Device_Mode.dmPelsHeight, Device_Mode.dmBitsPerPel);
   26.98 +			if (Supported_Modes.end() == std::find(Supported_Modes.begin(), Supported_Modes.end(), Mode))
   26.99 +				Supported_Modes.push_back(Mode);
  26.100 +		}
  26.101 +		std::sort(Supported_Modes.begin(), Supported_Modes.end(), Compare_Modes());
  26.102 +	}
  26.103 +}
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/EXCLUDE/GLTSF/src/Window.cpp	Sun Aug 22 12:39:27 2010 -0700
    27.3 @@ -0,0 +1,281 @@
    27.4 +#include "Window.hpp"
    27.5 +#include <gl/GL.h>
    27.6 +
    27.7 +#pragma comment(lib, "opengl32.lib")
    27.8 +
    27.9 +const wchar_t *Window::Window_Class_Name = L"GLTSF";
   27.10 +
   27.11 +Window::Window() : my_Handle(0),
   27.12 +				   my_Device_Context(0),
   27.13 +				   my_GL_Context(0),
   27.14 +				   my_Class_Registered(false),
   27.15 +				   my_Listener(0)
   27.16 +{
   27.17 +
   27.18 +}
   27.19 +
   27.20 +Window::~Window()
   27.21 +{
   27.22 +	Finalize();
   27.23 +	Show_Cursor();
   27.24 +}
   27.25 +
   27.26 +void Window::Initialize(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen)
   27.27 +{
   27.28 +	Finalize();
   27.29 +
   27.30 +	my_Video_Mode = Mode;
   27.31 +	if (!my_Video_Mode.Is_Valid())
   27.32 +		throw std::runtime_error("Invalid video mode");
   27.33 +
   27.34 +	my_Fullscreen = Fullscreen;
   27.35 +	Register_Class();
   27.36 +	Create_Window(Title, Mode, Fullscreen);
   27.37 +}
   27.38 +
   27.39 +void Window::Finalize()
   27.40 +{
   27.41 +	Destroy_Window();
   27.42 +	Unregister_Class();
   27.43 +}
   27.44 +
   27.45 +void Window::Set_Listener(Window_Listener *Listener)
   27.46 +{
   27.47 +	my_Listener = Listener;
   27.48 +}
   27.49 +
   27.50 +void Window::Register_Class()
   27.51 +{
   27.52 +	WNDCLASSEXW Window_Class = {0};
   27.53 +	Window_Class.cbSize = sizeof(Window_Class);
   27.54 +	Window_Class.style = 0;
   27.55 +	Window_Class.lpfnWndProc = &Window::Window_Procedure;
   27.56 +	Window_Class.cbClsExtra = 0;
   27.57 +	Window_Class.cbWndExtra = 0;
   27.58 +	Window_Class.hInstance = GetModuleHandle(NULL);
   27.59 +	Window_Class.hIcon = NULL;
   27.60 +	Window_Class.hCursor = NULL;
   27.61 +	Window_Class.hbrBackground = NULL;
   27.62 +	Window_Class.lpszMenuName = NULL;
   27.63 +	Window_Class.lpszClassName = Window_Class_Name;
   27.64 +	Window_Class.hIconSm = NULL;
   27.65 +	if (0 == RegisterClassExW(&Window_Class))
   27.66 +		throw std::runtime_error("Failed to register window class");
   27.67 +
   27.68 +	my_Class_Registered = true;
   27.69 +}
   27.70 +
   27.71 +void Window::Unregister_Class()
   27.72 +{
   27.73 +	if (my_Class_Registered)
   27.74 +	{
   27.75 +		if (0 == UnregisterClassW(Window_Class_Name, GetModuleHandle(NULL)))
   27.76 +			printf("Warning: Failed to unregister window class\n");
   27.77 +
   27.78 +		my_Class_Registered = false;
   27.79 +	}
   27.80 +}
   27.81 +
   27.82 +void Window::Create_Window(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen)
   27.83 +{
   27.84 +	HDC Screen_DC = GetDC(NULL);
   27.85 +	int Left = (GetDeviceCaps(Screen_DC, HORZRES) - my_Video_Mode.Width) / 2;
   27.86 +	int Top = (GetDeviceCaps(Screen_DC, VERTRES) - my_Video_Mode.Height) / 2;
   27.87 +	int Width = my_Video_Mode.Width;
   27.88 +	int Height = my_Video_Mode.Height;
   27.89 +	ReleaseDC(NULL, Screen_DC);
   27.90 +
   27.91 +	DWORD Style = WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU;
   27.92 +	if (!my_Fullscreen)
   27.93 +	{
   27.94 +		RECT Rect = {0, 0, Width, Height};
   27.95 +		AdjustWindowRect(&Rect, Style, false);
   27.96 +		Width = Rect.right - Rect.left;
   27.97 +		Height = Rect.bottom - Rect.top;
   27.98 +	}
   27.99 +	my_Handle = CreateWindowW(Window_Class_Name, Title.c_str(), Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
  27.100 +	if (!my_Handle)
  27.101 +		throw std::runtime_error("Failed to create window");
  27.102 +
  27.103 +	if (Fullscreen)
  27.104 +		Switch_To_Fullscreen(Mode);
  27.105 +
  27.106 +	Create_Context(Mode);
  27.107 +
  27.108 +	RECT Rect = {0};
  27.109 +	GetClientRect(my_Handle, &Rect);
  27.110 +	//TODO: ...
  27.111 +}
  27.112 +
  27.113 +void Window::Destroy_Window()
  27.114 +{
  27.115 +	Destroy_Context();
  27.116 +	if (my_Handle)
  27.117 +	{
  27.118 +		DestroyWindow(my_Handle);
  27.119 +		my_Handle = 0;
  27.120 +
  27.121 +		if (my_Fullscreen)
  27.122 +			ChangeDisplaySettings(NULL, 0);
  27.123 +	}
  27.124 +}
  27.125 +
  27.126 +void Window::Create_Context(const Video_Mode &Mode)
  27.127 +{
  27.128 +	my_Device_Context = GetDC(my_Handle);
  27.129 +	if (!my_Device_Context)
  27.130 +		throw std::runtime_error("Failed to get device context");
  27.131 +
  27.132 +	PIXELFORMATDESCRIPTOR Pixel_Descriptor = {0};
  27.133 +	Pixel_Descriptor.nSize = sizeof(Pixel_Descriptor);
  27.134 +	Pixel_Descriptor.nVersion = 1;
  27.135 +	Pixel_Descriptor.iLayerType = PFD_MAIN_PLANE;
  27.136 +	Pixel_Descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
  27.137 +	Pixel_Descriptor.iPixelType = PFD_TYPE_RGBA;
  27.138 +	Pixel_Descriptor.cColorBits = static_cast<BYTE>(Mode.Bits_Per_Pixel);
  27.139 +	Pixel_Descriptor.cDepthBits = 24;
  27.140 +	Pixel_Descriptor.cStencilBits = 8;
  27.141 +	Pixel_Descriptor.cAlphaBits = Mode.Bits_Per_Pixel == 32 ? 8 : 0;
  27.142 +
  27.143 +	int Best_Format = ChoosePixelFormat(my_Device_Context, &Pixel_Descriptor);
  27.144 +	if (0 == Best_Format)
  27.145 +		throw std::runtime_error("Failed to find suitable pixel format");
  27.146 +
  27.147 +	PIXELFORMATDESCRIPTOR Actual_Format = {0};
  27.148 +	Actual_Format.nSize = sizeof(Actual_Format);
  27.149 +	Actual_Format.nVersion = 1;
  27.150 +	DescribePixelFormat(my_Device_Context, Best_Format, sizeof(Actual_Format), &Actual_Format);
  27.151 +	if (!SetPixelFormat(my_Device_Context, Best_Format, &Actual_Format))
  27.152 +		throw std::runtime_error("Failed to set device pixel format");
  27.153 +
  27.154 +	my_GL_Context = wglCreateContext(my_Device_Context);
  27.155 +	if (!my_GL_Context)
  27.156 +		throw std::runtime_error("Failed to create OpenGL context");
  27.157 +
  27.158 +	wglMakeCurrent(my_Device_Context, my_GL_Context);
  27.159 +}
  27.160 +
  27.161 +void Window::Destroy_Context()
  27.162 +{
  27.163 +	if (my_GL_Context)
  27.164 +	{
  27.165 +		wglDeleteContext(my_GL_Context);
  27.166 +		my_GL_Context = 0;
  27.167 +	}
  27.168 +	if (my_Device_Context)
  27.169 +	{
  27.170 +		ReleaseDC(my_Handle, my_Device_Context);
  27.171 +		my_Device_Context = 0;
  27.172 +	}
  27.173 +}
  27.174 +
  27.175 +void Window::Switch_To_Fullscreen(const Video_Mode &Mode)
  27.176 +{
  27.177 +	DEVMODE Device_Mode = {0};
  27.178 +	Device_Mode.dmSize = sizeof(Device_Mode);
  27.179 +	Device_Mode.dmPelsWidth = Mode.Width;
  27.180 +	Device_Mode.dmPelsHeight = Mode.Height;
  27.181 +	Device_Mode.dmBitsPerPel = Mode.Bits_Per_Pixel;
  27.182 +	Device_Mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
  27.183 +
  27.184 +	if (DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettings(&Device_Mode, CDS_FULLSCREEN))
  27.185 +		throw std::runtime_error("Failed to change to fullscreen mode");
  27.186 +
  27.187 +	SetWindowLong(my_Handle, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
  27.188 +	SetWindowLong(my_Handle, GWL_EXSTYLE, WS_EX_APPWINDOW);
  27.189 +
  27.190 +	SetWindowPos(my_Handle, HWND_TOP, 0, 0, Mode.Width, Mode.Height, SWP_FRAMECHANGED);
  27.191 +}
  27.192 +
  27.193 +LRESULT CALLBACK Window::Window_Procedure(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam)
  27.194 +{
  27.195 +	switch (Message)
  27.196 +	{
  27.197 +	case WM_CREATE:
  27.198 +		{
  27.199 +			LONG This = reinterpret_cast<LONG>(reinterpret_cast<CREATESTRUCT *>(lParam)->lpCreateParams);
  27.200 +			SetWindowLongPtr(Handle, GWLP_USERDATA, This);
  27.201 +			return 0;
  27.202 +		}
  27.203 +		break;
  27.204 +	case WM_DESTROY:
  27.205 +		PostQuitMessage(0);
  27.206 +		return 0;
  27.207 +		break;
  27.208 +	default:
  27.209 +		{
  27.210 +			Window* Win = reinterpret_cast<Window *>(GetWindowLongPtr(Handle, GWLP_USERDATA));
  27.211 +			if (Win)
  27.212 +				return Win->Handle_Message(Handle, Message, wParam, lParam);
  27.213 +		}
  27.214 +		break;
  27.215 +	}
  27.216 +	return DefWindowProcW(Handle, Message, wParam, lParam);
  27.217 +}
  27.218 +
  27.219 +#define Call_Listener(x)\
  27.220 +	if (my_Listener) my_Listener->x
  27.221 +
  27.222 +LRESULT Window::Handle_Message(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam)
  27.223 +{
  27.224 +	switch (Message)
  27.225 +	{
  27.226 +	case WM_SIZE:
  27.227 +		Call_Listener(On_Resized(LOWORD(lParam), HIWORD(lParam)));
  27.228 +		break;
  27.229 +	case WM_CLOSE:
  27.230 +		Call_Listener(On_Close());
  27.231 +		break;
  27.232 +	case WM_KEYDOWN:
  27.233 +		Call_Listener(On_Key_Down(wParam));
  27.234 +		break;
  27.235 +	case WM_KEYUP:
  27.236 +		Call_Listener(On_Key_Up(wParam));
  27.237 +		break;
  27.238 +	case WM_CHAR:
  27.239 +		Call_Listener(On_Char(wParam));
  27.240 +		break;
  27.241 +	default:
  27.242 +		return DefWindowProcW(Handle, Message, wParam, lParam);
  27.243 +		break;
  27.244 +	}
  27.245 +	return 0;
  27.246 +}
  27.247 +
  27.248 +void Window::Show()
  27.249 +{
  27.250 +	if (my_Handle)
  27.251 +		ShowWindow(my_Handle, SW_SHOW);
  27.252 +}
  27.253 +
  27.254 +void Window::Hide()
  27.255 +{
  27.256 +	if (my_Handle)
  27.257 +		ShowWindow(my_Handle, SW_HIDE);
  27.258 +}
  27.259 +
  27.260 +void Window::Handle_Events()
  27.261 +{
  27.262 +	MSG Message = {0};
  27.263 +	while (PeekMessageW(&Message, NULL, 0, 0, PM_REMOVE))
  27.264 +	{
  27.265 +		TranslateMessage(&Message);
  27.266 +		DispatchMessageW(&Message);
  27.267 +	}
  27.268 +}
  27.269 +
  27.270 +void Window::Display()
  27.271 +{
  27.272 +	if (my_Device_Context && my_GL_Context)
  27.273 +		SwapBuffers(my_Device_Context);
  27.274 +}
  27.275 +
  27.276 +void Window::Show_Cursor()
  27.277 +{
  27.278 +	ShowCursor(TRUE);
  27.279 +}
  27.280 +
  27.281 +void Window::Hide_Cursor()
  27.282 +{
  27.283 +	ShowCursor(FALSE);
  27.284 +}
    28.1 --- a/include/SDL_stdinc.h	Sun Aug 22 12:35:34 2010 -0700
    28.2 +++ b/include/SDL_stdinc.h	Sun Aug 22 12:39:27 2010 -0700
    28.3 @@ -472,6 +472,19 @@
    28.4  extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t * string);
    28.5  #endif
    28.6  
    28.7 +#ifdef HAVE_WCSLCPY
    28.8 +#define SDL_wcslcpy      wcslcpy
    28.9 +#else
   28.10 +extern DECLSPEC size_t SDLCALL SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen);
   28.11 +#endif
   28.12 +
   28.13 +#ifdef HAVE_WCSLCAT
   28.14 +#define SDL_wcslcat      wcslcat
   28.15 +#else
   28.16 +extern DECLSPEC size_t SDLCALL SDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen);
   28.17 +#endif
   28.18 +
   28.19 +
   28.20  #ifdef HAVE_STRLCPY
   28.21  #define SDL_strlcpy     strlcpy
   28.22  #else
   28.23 @@ -479,6 +492,9 @@
   28.24                                             size_t maxlen);
   28.25  #endif
   28.26  
   28.27 +extern DECLSPEC size_t SDLCALL SDL_utf8strlcpy(char *dst, const char *src,
   28.28 +                                            size_t dst_bytes);
   28.29 +
   28.30  #ifdef HAVE_STRLCAT
   28.31  #define SDL_strlcat    strlcat
   28.32  #else
    29.1 --- a/src/events/SDL_keyboard.c	Sun Aug 22 12:35:34 2010 -0700
    29.2 +++ b/src/events/SDL_keyboard.c	Sun Aug 22 12:39:27 2010 -0700
    29.3 @@ -778,7 +778,7 @@
    29.4          SDL_Event event;
    29.5          event.text.type = SDL_TEXTINPUT;
    29.6          event.text.windowID = keyboard->focus ? keyboard->focus->id : 0;
    29.7 -        SDL_strlcpy(event.text.text, text, SDL_arraysize(event.text.text));
    29.8 +        SDL_utf8strlcpy(event.text.text, text, SDL_arraysize(event.text.text));
    29.9          event.text.windowID = keyboard->focus ? keyboard->focus->id : 0;
   29.10          posted = (SDL_PushEvent(&event) > 0);
   29.11      }
   29.12 @@ -799,7 +799,7 @@
   29.13          event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0;
   29.14          event.edit.start = start;
   29.15          event.edit.length = length;
   29.16 -        SDL_strlcpy(event.edit.text, text, SDL_arraysize(event.edit.text));
   29.17 +        SDL_utf8strlcpy(event.edit.text, text, SDL_arraysize(event.edit.text));
   29.18          posted = (SDL_PushEvent(&event) > 0);
   29.19      }
   29.20      return (posted);
    30.1 --- a/src/haptic/nds/SDL_syshaptic.c	Sun Aug 22 12:35:34 2010 -0700
    30.2 +++ b/src/haptic/nds/SDL_syshaptic.c	Sun Aug 22 12:39:27 2010 -0700
    30.3 @@ -43,35 +43,35 @@
    30.4  } NDS_HapticData;
    30.5  
    30.6  
    30.7 -
    30.8 void
    30.9 -NDS_EZF_OpenNorWrite() 
   30.10 +void
   30.11 +NDS_EZF_OpenNorWrite() 
   30.12  {
   30.13 -    
   30.14 GBA_BUS[0x0FF0000] = 0xD200;
   30.15 -    
   30.16 GBA_BUS[0x0000000] = 0x1500;
   30.17 -    
   30.18 GBA_BUS[0x0010000] = 0xD200;
   30.19 -    
   30.20 GBA_BUS[0x0020000] = 0x1500;
   30.21 -    
   30.22 GBA_BUS[0x0E20000] = 0x1500;
   30.23 -    
   30.24 GBA_BUS[0x0FE0000] = 0x1500;
   30.25 -
   30.26 } 
   30.27 
   30.28 
   30.29 void
   30.30 +    GBA_BUS[0x0FF0000] = 0xD200;
   30.31 +    GBA_BUS[0x0000000] = 0x1500;
   30.32 +    GBA_BUS[0x0010000] = 0xD200;
   30.33 +    GBA_BUS[0x0020000] = 0x1500;
   30.34 +    GBA_BUS[0x0E20000] = 0x1500;
   30.35 +    GBA_BUS[0x0FE0000] = 0x1500;
   30.36 +} 
   30.37 
   30.38 void
   30.39  
   30.40 -NDS_EZF_CloseNorWrite() 
   30.41 +NDS_EZF_CloseNorWrite() 
   30.42  {
   30.43 -    
   30.44 GBA_BUS[0x0FF0000] = 0xD200;
   30.45 -    
   30.46 GBA_BUS[0x0000000] = 0x1500;
   30.47 -    
   30.48 GBA_BUS[0x0010000] = 0xD200;
   30.49 -    
   30.50 GBA_BUS[0x0020000] = 0x1500;
   30.51 -    
   30.52 GBA_BUS[0x0E20000] = 0xD200;
   30.53 -    
   30.54 GBA_BUS[0x0FE0000] = 0x1500;
   30.55 -
   30.56 }
   30.57 +    GBA_BUS[0x0FF0000] = 0xD200;
   30.58 +    GBA_BUS[0x0000000] = 0x1500;
   30.59 +    GBA_BUS[0x0010000] = 0xD200;
   30.60 +    GBA_BUS[0x0020000] = 0x1500;
   30.61 +    GBA_BUS[0x0E20000] = 0xD200;
   30.62 +    GBA_BUS[0x0FE0000] = 0x1500;
   30.63 +}
   30.64  
   30.65  void
   30.66  NDS_EZF_ChipReset()
   30.67  {
   30.68 -    
   30.69 GBA_BUS[0x0000] = 0x00F0;
   30.70 -    
   30.71 GBA_BUS[0x1000] = 0x00F0;
   30.72 -} 
   30.73 uint32 NDS_EZF_IsPresent() 
   30.74 +    GBA_BUS[0x0000] = 0x00F0;
   30.75 +    GBA_BUS[0x1000] = 0x00F0;
   30.76 +} uint32 NDS_EZF_IsPresent() 
   30.77  {
   30.78 -    
   30.79 vuint16 id1, id2;
   30.80 +    vuint16 id1, id2;
   30.81  
   30.82      NDS_EZF_OpenNorWrite();
   30.83  
   30.84 @@ -81,35 +81,35 @@
   30.85      GBA_BUS[0x1555] = 0x00AA;
   30.86      GBA_BUS[0x12AA] = 0x0055;
   30.87      GBA_BUS[0x1555] = 0x0090;
   30.88 -    
   30.89 id1 = GBA_BUS[0x0001];
   30.90 -    
   30.91 id2 = GBA_BUS[0x1001];
   30.92 -    
   30.93 if ((id1 != 0x227E) || (id2 != 0x227E)) {
   30.94 +    id1 = GBA_BUS[0x0001];
   30.95 +    id2 = GBA_BUS[0x1001];
   30.96 +    if ((id1 != 0x227E) || (id2 != 0x227E)) {
   30.97          NDS_EZF_CloseNorWrite();
   30.98 -        
   30.99 return 0;
  30.100 +        return 0;
  30.101      }
  30.102 -    
  30.103 
  30.104 id1 = GBA_BUS[0x000E];
  30.105 -    
  30.106 id2 = GBA_BUS[0x100E];
  30.107 +    id1 = GBA_BUS[0x000E];
  30.108 +    id2 = GBA_BUS[0x100E];
  30.109  
  30.110      NDS_EZF_CloseNorWrite();
  30.111 -    
  30.112 if (id1 == 0x2218 && id2 == 0x2218) {
  30.113 -        
  30.114 return 1;
  30.115 +    if (id1 == 0x2218 && id2 == 0x2218) {
  30.116 +        return 1;
  30.117      }
  30.118 -    
  30.119 return 0;
  30.120 -
  30.121 }
  30.122 -
  30.123 void
  30.124 -NDS_EZF_SetShake(u8 pos) 
  30.125 +    return 0;
  30.126 +}
  30.127 +void
  30.128 +NDS_EZF_SetShake(u8 pos) 
  30.129  {
  30.130      u16 data = ((pos % 3) | 0x00F0);
  30.131 -    
  30.132 GBA_BUS[0x0FF0000] = 0xD200;
  30.133 -    
  30.134 GBA_BUS[0x0000000] = 0x1500;
  30.135 -    
  30.136 GBA_BUS[0x0010000] = 0xD200;
  30.137 -    
  30.138 GBA_BUS[0x0020000] = 0x1500;
  30.139 -    
  30.140 GBA_BUS[0x0F10000] = data;
  30.141 -    
  30.142 GBA_BUS[0x0FE0000] = 0x1500;
  30.143 +    GBA_BUS[0x0FF0000] = 0xD200;
  30.144 +    GBA_BUS[0x0000000] = 0x1500;
  30.145 +    GBA_BUS[0x0010000] = 0xD200;
  30.146 +    GBA_BUS[0x0020000] = 0x1500;
  30.147 +    GBA_BUS[0x0F10000] = data;
  30.148 +    GBA_BUS[0x0FE0000] = 0x1500;
  30.149  
  30.150      GBA_BUS[0] = 0x0000;        /* write any value for vibration. */
  30.151      GBA_BUS[0] = 0x0002;
  30.152 -
  30.153 }
  30.154 +}
  30.155  
  30.156  static int
  30.157  SDL_SYS_LogicError(void)
    31.1 --- a/src/joystick/nds/SDL_sysjoystick.c	Sun Aug 22 12:35:34 2010 -0700
    31.2 +++ b/src/joystick/nds/SDL_sysjoystick.c	Sun Aug 22 12:39:27 2010 -0700
    31.3 @@ -45,7 +45,7 @@
    31.4  SDL_SYS_JoystickInit(void)
    31.5  {
    31.6      SDL_numjoysticks = 1;
    31.7 -    
    31.8 return (1);
    31.9 +    return (1);
   31.10  }
   31.11  
   31.12  /* Function to get the device-dependent name of a joystick */
   31.13 @@ -73,7 +73,7 @@
   31.14      return 0;
   31.15  }
   31.16  
   31.17 -
   31.18 +
   31.19  /* Function to update the state of a joystick - called as a device poll.
   31.20   * This function shouldn't update the joystick structure directly,
   31.21   * but instead should call SDL_PrivateJoystick*() to deliver events
   31.22 @@ -84,8 +84,8 @@
   31.23  {
   31.24      u32 keysd, keysu;
   31.25      int magnitude = 16384;
   31.26 -    
   31.27 -        /*scanKeys(); - this is done in PumpEvents, because touch uses it too */ 
   31.28 +    
   31.29 +        /*scanKeys(); - this is done in PumpEvents, because touch uses it too */ 
   31.30          keysd = keysDown();
   31.31      keysu = keysUp();
   31.32  
   31.33 @@ -101,61 +101,61 @@
   31.34      if ((keysd & KEY_RIGHT)) {
   31.35          SDL_PrivateJoystickAxis(joystick, 0, magnitude);
   31.36      }
   31.37 -    
   31.38 if ((keysu & (KEY_UP | KEY_DOWN))) {
   31.39 +    if ((keysu & (KEY_UP | KEY_DOWN))) {
   31.40          SDL_PrivateJoystickAxis(joystick, 1, 0);
   31.41      }
   31.42 -    
   31.43 if ((keysu & (KEY_LEFT | KEY_RIGHT))) {
   31.44 +    if ((keysu & (KEY_LEFT | KEY_RIGHT))) {
   31.45          SDL_PrivateJoystickAxis(joystick, 0, 0);
   31.46      }
   31.47 -    
   31.48 if ((keysd & KEY_A)) {
   31.49 +    if ((keysd & KEY_A)) {
   31.50          SDL_PrivateJoystickButton(joystick, 0, SDL_PRESSED);
   31.51      }
   31.52 -    
   31.53 if ((keysd & KEY_B)) {
   31.54 +    if ((keysd & KEY_B)) {
   31.55          SDL_PrivateJoystickButton(joystick, 1, SDL_PRESSED);
   31.56      }
   31.57 -    
   31.58 if ((keysd & KEY_X)) {
   31.59 +    if ((keysd & KEY_X)) {
   31.60          SDL_PrivateJoystickButton(joystick, 2, SDL_PRESSED);
   31.61      }
   31.62 -    
   31.63 if ((keysd & KEY_Y)) {
   31.64 +    if ((keysd & KEY_Y)) {
   31.65          SDL_PrivateJoystickButton(joystick, 3, SDL_PRESSED);
   31.66      }
   31.67 -    
   31.68 if ((keysd & KEY_L)) {
   31.69 +    if ((keysd & KEY_L)) {
   31.70          SDL_PrivateJoystickButton(joystick, 4, SDL_PRESSED);
   31.71      }
   31.72 -    
   31.73 if ((keysd & KEY_R)) {
   31.74 +    if ((keysd & KEY_R)) {
   31.75          SDL_PrivateJoystickButton(joystick, 5, SDL_PRESSED);
   31.76      }
   31.77 -    
   31.78 if ((keysd & KEY_SELECT)) {
   31.79 +    if ((keysd & KEY_SELECT)) {
   31.80          SDL_PrivateJoystickButton(joystick, 6, SDL_PRESSED);
   31.81      }
   31.82 -    
   31.83 if ((keysd & KEY_START)) {
   31.84 +    if ((keysd & KEY_START)) {
   31.85          SDL_PrivateJoystickButton(joystick, 7, SDL_PRESSED);
   31.86      }
   31.87 -    
   31.88 if ((keysu & KEY_A)) {
   31.89 +    if ((keysu & KEY_A)) {
   31.90          SDL_PrivateJoystickButton(joystick, 0, SDL_RELEASED);
   31.91      }
   31.92 -    
   31.93 if ((keysu & KEY_B)) {
   31.94 +    if ((keysu & KEY_B)) {
   31.95          SDL_PrivateJoystickButton(joystick, 1, SDL_RELEASED);
   31.96      }
   31.97 -    
   31.98 if ((keysu & KEY_X)) {
   31.99 +    if ((keysu & KEY_X)) {
  31.100          SDL_PrivateJoystickButton(joystick, 2, SDL_RELEASED);
  31.101      }
  31.102 -    
  31.103 if ((keysu & KEY_Y)) {
  31.104 +    if ((keysu & KEY_Y)) {
  31.105          SDL_PrivateJoystickButton(joystick, 3, SDL_RELEASED);
  31.106      }
  31.107 -    
  31.108 if ((keysu & KEY_L)) {
  31.109 +    if ((keysu & KEY_L)) {
  31.110          SDL_PrivateJoystickButton(joystick, 4, SDL_RELEASED);
  31.111      }
  31.112 -    
  31.113 if ((keysu & KEY_R)) {
  31.114 +    if ((keysu & KEY_R)) {
  31.115          SDL_PrivateJoystickButton(joystick, 5, SDL_RELEASED);
  31.116      }
  31.117 -    
  31.118 if ((keysu & KEY_SELECT)) {
  31.119 +    if ((keysu & KEY_SELECT)) {
  31.120          SDL_PrivateJoystickButton(joystick, 6, SDL_RELEASED);
  31.121      }
  31.122 -    
  31.123 if ((keysu & KEY_START)) {
  31.124 +    if ((keysu & KEY_START)) {
  31.125          SDL_PrivateJoystickButton(joystick, 7, SDL_RELEASED);
  31.126      }
  31.127 -
  31.128 }
  31.129 +}
  31.130  
  31.131  /* Function to close a joystick after use */
  31.132  void
    32.1 --- a/src/stdlib/SDL_string.c	Sun Aug 22 12:35:34 2010 -0700
    32.2 +++ b/src/stdlib/SDL_string.c	Sun Aug 22 12:39:27 2010 -0700
    32.3 @@ -29,6 +29,21 @@
    32.4  #define SDL_isupperhex(X)   (((X) >= 'A') && ((X) <= 'F'))
    32.5  #define SDL_islowerhex(X)   (((X) >= 'a') && ((X) <= 'f'))
    32.6  
    32.7 +#define UTF8_IsLeadByte(c) ((c) >= 0xC0 && (c) <= 0xF4)
    32.8 +#define UTF8_IsTrailingByte(c) ((c) >= 0x80 && (c) <= 0xBF)
    32.9 +
   32.10 +int UTF8_TrailingBytes(unsigned char c)
   32.11 +{
   32.12 +    if (c >= 0xC0 && c<= 0xDF)
   32.13 +        return 1;
   32.14 +    else if (c >= 0xE0 && c <= 0xEF)
   32.15 +        return 2;
   32.16 +    else if (c >= 0xF0 && c <= 0xF4)
   32.17 +        return 3;
   32.18 +    else
   32.19 +        return 0;
   32.20 +}
   32.21 +
   32.22  #if !defined(HAVE_SSCANF) || !defined(HAVE_STRTOL)
   32.23  static size_t
   32.24  SDL_ScanLong(const char *text, int radix, long *valuep)
   32.25 @@ -348,6 +363,33 @@
   32.26  }
   32.27  #endif
   32.28  
   32.29 +#ifndef HAVE_WCSLCPY
   32.30 +size_t
   32.31 +SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen)
   32.32 +{
   32.33 +    size_t srclen = SDL_wcslen(src);
   32.34 +    if (maxlen > 0) {
   32.35 +        size_t len = SDL_min(srclen, maxlen - 1);
   32.36 +        SDL_memcpy(dst, src, len * sizeof(wchar_t));
   32.37 +        dst[len] = '\0';
   32.38 +    }
   32.39 +    return srclen;
   32.40 +}
   32.41 +#endif
   32.42 +
   32.43 +#ifndef HAVE_WCSLCAT
   32.44 +size_t
   32.45 +SDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen)
   32.46 +{
   32.47 +    size_t dstlen = SDL_wcslen(dst);
   32.48 +    size_t srclen = SDL_wcslen(src);
   32.49 +    if (dstlen < maxlen) {
   32.50 +        SDL_wcslcpy(dst + dstlen, src, maxlen - dstlen);
   32.51 +    }
   32.52 +    return dstlen + srclen;
   32.53 +}
   32.54 +#endif
   32.55 +
   32.56  #ifndef HAVE_STRLCPY
   32.57  size_t
   32.58  SDL_strlcpy(char *dst, const char *src, size_t maxlen)
   32.59 @@ -362,6 +404,38 @@
   32.60  }
   32.61  #endif
   32.62  
   32.63 +size_t SDL_utf8strlcpy(char *dst, const char *src, size_t dst_bytes)
   32.64 +{
   32.65 +    size_t src_bytes = SDL_strlen(src);
   32.66 +    size_t bytes = SDL_min(src_bytes, dst_bytes - 1);
   32.67 +    int i = 0;
   32.68 +    char trailing_bytes = 0;
   32.69 +    if (bytes)
   32.70 +    {
   32.71 +        unsigned char c = (unsigned char)src[bytes - 1];
   32.72 +        if (UTF8_IsLeadByte(c))
   32.73 +            --bytes;
   32.74 +        else if (UTF8_IsTrailingByte(c))
   32.75 +        {
   32.76 +            for (i = bytes - 1; i != 0; --i)
   32.77 +            {
   32.78 +                c = (unsigned char)src[i];
   32.79 +                trailing_bytes = UTF8_TrailingBytes(c);
   32.80 +                if (trailing_bytes)
   32.81 +                {
   32.82 +                    if (bytes - i != trailing_bytes + 1)
   32.83 +                        bytes = i;
   32.84 +
   32.85 +                    break;
   32.86 +                }
   32.87 +            }
   32.88 +        }
   32.89 +        SDL_memcpy(dst, src, bytes);
   32.90 +    }
   32.91 +    dst[bytes] = '\0';
   32.92 +    return bytes;
   32.93 +}
   32.94 +
   32.95  #ifndef HAVE_STRLCAT
   32.96  size_t
   32.97  SDL_strlcat(char *dst, const char *src, size_t maxlen)
    33.1 --- a/src/video/win32/SDL_win32events.c	Sun Aug 22 12:35:34 2010 -0700
    33.2 +++ b/src/video/win32/SDL_win32events.c	Sun Aug 22 12:39:27 2010 -0700
    33.3 @@ -139,6 +139,8 @@
    33.4      }
    33.5  
    33.6  #endif
    33.7 +    if (IME_HandleMessage(hwnd, msg, wParam, &lParam, data->videodata))
    33.8 +        return 0;
    33.9  
   33.10      switch (msg) {
   33.11  
   33.12 @@ -605,7 +607,7 @@
   33.13      class.hbrBackground = NULL;
   33.14      class.hInstance = SDL_Instance;
   33.15      class.style = SDL_Appstyle;
   33.16 -    class.lpfnWndProc = DefWindowProc;
   33.17 +    class.lpfnWndProc = WIN_WindowProc;
   33.18      class.cbWndExtra = 0;
   33.19      class.cbClsExtra = 0;
   33.20      if (!RegisterClass(&class)) {
    34.1 --- a/src/video/win32/SDL_win32keyboard.c	Sun Aug 22 12:35:34 2010 -0700
    34.2 +++ b/src/video/win32/SDL_win32keyboard.c	Sun Aug 22 12:39:27 2010 -0700
    34.3 @@ -26,6 +26,14 @@
    34.4  #include "../../events/SDL_keyboard_c.h"
    34.5  #include "../../events/scancodes_win32.h"
    34.6  
    34.7 +#include <imm.h>
    34.8 +#include <oleauto.h>
    34.9 +
   34.10 +static void IME_Init(SDL_VideoData *videodata, HWND hwnd);
   34.11 +static void IME_Enable(SDL_VideoData *videodata, HWND hwnd);
   34.12 +static void IME_Disable(SDL_VideoData *videodata, HWND hwnd);
   34.13 +static void IME_Quit(SDL_VideoData *videodata);
   34.14 +
   34.15  #ifndef MAPVK_VK_TO_VSC
   34.16  #define MAPVK_VK_TO_VSC     0
   34.17  #endif
   34.18 @@ -81,6 +89,34 @@
   34.19  
   34.20      data->key_layout = win32_scancode_table;
   34.21  
   34.22 +    data->ime_com_initialized = SDL_FALSE;
   34.23 +    data->ime_threadmgr = 0;
   34.24 +    data->ime_initialized = SDL_FALSE;
   34.25 +    data->ime_enabled = SDL_FALSE;
   34.26 +    data->ime_available = SDL_FALSE;
   34.27 +    data->ime_hwnd_main = 0;
   34.28 +    data->ime_hwnd_current = 0;
   34.29 +    data->ime_himc = 0;
   34.30 +    data->ime_composition[0] = 0;
   34.31 +    data->ime_readingstring[0] = 0;
   34.32 +    data->ime_cursor = 0;
   34.33 +    data->ime_hkl = 0;
   34.34 +    data->ime_himm32 = 0;
   34.35 +    data->GetReadingString = 0;
   34.36 +    data->ShowReadingWindow = 0;
   34.37 +    data->ImmLockIMC = 0;
   34.38 +    data->ImmUnlockIMC = 0;
   34.39 +    data->ImmLockIMCC = 0;
   34.40 +    data->ImmUnlockIMCC = 0;
   34.41 +    data->ime_uiless = SDL_FALSE;
   34.42 +    data->ime_threadmgrex = 0;
   34.43 +    data->ime_uielemsinkcookie = TF_INVALID_COOKIE;
   34.44 +    data->ime_alpnsinkcookie = TF_INVALID_COOKIE;
   34.45 +    data->ime_openmodesinkcookie = TF_INVALID_COOKIE;
   34.46 +    data->ime_convmodesinkcookie = TF_INVALID_COOKIE;
   34.47 +    data->ime_uielemsink = 0;
   34.48 +    data->ime_ippasink = 0;
   34.49 +
   34.50      WIN_UpdateKeymap();
   34.51  
   34.52      SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu");
   34.53 @@ -119,6 +155,851 @@
   34.54  void
   34.55  WIN_QuitKeyboard(_THIS)
   34.56  {
   34.57 +    IME_Quit((SDL_VideoData *)_this->driverdata);
   34.58 +}
   34.59 +
   34.60 +void
   34.61 +WIN_StartTextInput(_THIS)
   34.62 +{
   34.63 +    SDL_Window *window = SDL_GetKeyboardFocus();
   34.64 +    if (window) {
   34.65 +        HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
   34.66 +        SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
   34.67 +        IME_Init(videodata, hwnd);
   34.68 +        IME_Enable(videodata, hwnd);
   34.69 +    }
   34.70 +}
   34.71 +
   34.72 +void
   34.73 +WIN_StopTextInput(_THIS)
   34.74 +{
   34.75 +    SDL_Window *window = SDL_GetKeyboardFocus();
   34.76 +    if (window) {
   34.77 +        HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
   34.78 +        SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
   34.79 +        IME_Init(videodata, hwnd);
   34.80 +        IME_Disable(videodata, hwnd);
   34.81 +    }
   34.82 +}
   34.83 +
   34.84 +void
   34.85 +WIN_SetTextInputRect(_THIS, SDL_Rect *rect)
   34.86 +{
   34.87 +
   34.88 +}
   34.89 +
   34.90 +#define LANG_CHT MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)
   34.91 +#define LANG_CHS MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)
   34.92 +
   34.93 +#define MAKEIMEVERSION(major,minor) ((DWORD) (((BYTE)(major) << 24) | ((BYTE)(minor) << 16) ))
   34.94 +#define IMEID_VER(id) ((id) & 0xffff0000)
   34.95 +#define IMEID_LANG(id) ((id) & 0x0000ffff)
   34.96 +
   34.97 +#define CHT_HKL_DAYI            ((HKL)0xE0060404)
   34.98 +#define CHT_HKL_NEW_PHONETIC    ((HKL)0xE0080404)
   34.99 +#define CHT_HKL_NEW_CHANG_JIE   ((HKL)0xE0090404)
  34.100 +#define CHT_HKL_NEW_QUICK       ((HKL)0xE00A0404)
  34.101 +#define CHT_HKL_HK_CANTONESE    ((HKL)0xE00B0404)
  34.102 +#define CHT_IMEFILENAME1        "TINTLGNT.IME"
  34.103 +#define CHT_IMEFILENAME2        "CINTLGNT.IME"
  34.104 +#define CHT_IMEFILENAME3        "MSTCIPHA.IME"
  34.105 +#define IMEID_CHT_VER42         (LANG_CHT | MAKEIMEVERSION(4, 2))
  34.106 +#define IMEID_CHT_VER43         (LANG_CHT | MAKEIMEVERSION(4, 3))
  34.107 +#define IMEID_CHT_VER44         (LANG_CHT | MAKEIMEVERSION(4, 4))
  34.108 +#define IMEID_CHT_VER50         (LANG_CHT | MAKEIMEVERSION(5, 0))
  34.109 +#define IMEID_CHT_VER51         (LANG_CHT | MAKEIMEVERSION(5, 1))
  34.110 +#define IMEID_CHT_VER52         (LANG_CHT | MAKEIMEVERSION(5, 2))
  34.111 +#define IMEID_CHT_VER60         (LANG_CHT | MAKEIMEVERSION(6, 0))
  34.112 +#define IMEID_CHT_VER_VISTA     (LANG_CHT | MAKEIMEVERSION(7, 0))
  34.113 +
  34.114 +#define CHS_HKL                 ((HKL)0xE00E0804)
  34.115 +#define CHS_IMEFILENAME1        "PINTLGNT.IME"
  34.116 +#define CHS_IMEFILENAME2        "MSSCIPYA.IME"
  34.117 +#define IMEID_CHS_VER41         (LANG_CHS | MAKEIMEVERSION(4, 1))
  34.118 +#define IMEID_CHS_VER42         (LANG_CHS | MAKEIMEVERSION(4, 2))
  34.119 +#define IMEID_CHS_VER53         (LANG_CHS | MAKEIMEVERSION(5, 3))
  34.120 +
  34.121 +#define LANG() LOWORD((videodata->ime_hkl))
  34.122 +#define PRIMLANG() ((WORD)PRIMARYLANGID(LANG()))
  34.123 +#define SUBLANG() SUBLANGID(LANG())
  34.124 +
  34.125 +static void IME_UpdateInputLocale(SDL_VideoData *videodata);
  34.126 +static void IME_ClearComposition(SDL_VideoData *videodata);
  34.127 +static void IME_SetWindow(SDL_VideoData* videodata, HWND hwnd);
  34.128 +static void IME_SetupAPI(SDL_VideoData *videodata);
  34.129 +static DWORD IME_GetId(SDL_VideoData *videodata, UINT uIndex);
  34.130 +static void IME_SendEditingEvent(SDL_VideoData *videodata);
  34.131 +#define SDL_IsEqualIID(riid1, riid2) SDL_IsEqualGUID(riid1, riid2)
  34.132 +#define SDL_IsEqualGUID(rguid1, rguid2) (!SDL_memcmp(rguid1, rguid2, sizeof(GUID)))
  34.133 +
  34.134 +static SDL_bool UILess_SetupSinks(SDL_VideoData *videodata);
  34.135 +static void UILess_ReleaseSinks(SDL_VideoData *videodata);
  34.136 +static void UILess_EnableUIUpdates(SDL_VideoData *videodata);
  34.137 +static void UILess_DisableUIUpdates(SDL_VideoData *videodata);
  34.138 +
  34.139 +static void
  34.140 +IME_Init(SDL_VideoData *videodata, HWND hwnd)
  34.141 +{
  34.142 +    if (videodata->ime_initialized)
  34.143 +        return;
  34.144 +
  34.145 +    videodata->ime_hwnd_main = hwnd;
  34.146 +    if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))) {
  34.147 +        videodata->ime_com_initialized = SDL_TRUE;
  34.148 +        CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, &videodata->ime_threadmgr);
  34.149 +    }
  34.150 +    videodata->ime_initialized = SDL_TRUE;
  34.151 +    videodata->ime_himm32 = LoadLibraryA("imm32.dll");
  34.152 +    if (!videodata->ime_himm32) {
  34.153 +        videodata->ime_available = SDL_FALSE;
  34.154 +        return;
  34.155 +    }
  34.156 +    videodata->ImmLockIMC = (LPINPUTCONTEXT2 (WINAPI *)(HIMC))GetProcAddress(videodata->ime_himm32, "ImmLockIMC");
  34.157 +    videodata->ImmUnlockIMC = (BOOL (WINAPI *)(HIMC))GetProcAddress(videodata->ime_himm32, "ImmUnlockIMC");
  34.158 +    videodata->ImmLockIMCC = (LPVOID (WINAPI *)(HIMCC))GetProcAddress(videodata->ime_himm32, "ImmLockIMCC");
  34.159 +    videodata->ImmUnlockIMCC = (BOOL (WINAPI *)(HIMCC))GetProcAddress(videodata->ime_himm32, "ImmUnlockIMCC");
  34.160 +
  34.161 +    IME_SetWindow(videodata, hwnd);
  34.162 +    videodata->ime_himc = ImmGetContext(hwnd);
  34.163 +    ImmReleaseContext(hwnd, videodata->ime_himc);
  34.164 +    if (!videodata->ime_himc) {
  34.165 +        videodata->ime_available = SDL_FALSE;
  34.166 +        IME_Disable(videodata, hwnd);
  34.167 +        return;
  34.168 +    }
  34.169 +    videodata->ime_available = SDL_TRUE;
  34.170 +    IME_UpdateInputLocale(videodata);
  34.171 +    IME_SetupAPI(videodata);
  34.172 +    videodata->ime_uiless = UILess_SetupSinks(videodata);
  34.173 +    IME_UpdateInputLocale(videodata);
  34.174 +    IME_Disable(videodata, hwnd);
  34.175 +}
  34.176 +
  34.177 +static void
  34.178 +IME_Enable(SDL_VideoData *videodata, HWND hwnd)
  34.179 +{
  34.180 +    if (!videodata->ime_initialized || !videodata->ime_hwnd_current)
  34.181 +        return;
  34.182 +
  34.183 +    if (!videodata->ime_available) {
  34.184 +        IME_Disable(videodata, hwnd);
  34.185 +        return;
  34.186 +    }
  34.187 +    if (videodata->ime_hwnd_current == videodata->ime_hwnd_main)
  34.188 +        ImmAssociateContext(videodata->ime_hwnd_current, videodata->ime_himc);
  34.189 +
  34.190 +    videodata->ime_enabled = SDL_TRUE;
  34.191 +    IME_UpdateInputLocale(videodata);
  34.192 +    UILess_EnableUIUpdates(videodata);
  34.193 +}
  34.194 +
  34.195 +static void
  34.196 +IME_Disable(SDL_VideoData *videodata, HWND hwnd)
  34.197 +{
  34.198 +    if (!videodata->ime_initialized || !videodata->ime_hwnd_current)
  34.199 +        return;
  34.200 +
  34.201 +    IME_ClearComposition(videodata);
  34.202 +    if (videodata->ime_hwnd_current == videodata->ime_hwnd_main)
  34.203 +        ImmAssociateContext(videodata->ime_hwnd_current, NULL);
  34.204 +
  34.205 +    videodata->ime_enabled = SDL_FALSE;
  34.206 +    UILess_DisableUIUpdates(videodata);
  34.207 +}
  34.208 +
  34.209 +static void
  34.210 +IME_Quit(SDL_VideoData *videodata)
  34.211 +{
  34.212 +    if (!videodata->ime_initialized)
  34.213 +        return;
  34.214 +
  34.215 +    UILess_ReleaseSinks(videodata);
  34.216 +    if (videodata->ime_hwnd_main)
  34.217 +        ImmAssociateContext(videodata->ime_hwnd_main, videodata->ime_himc);
  34.218 +
  34.219 +    videodata->ime_hwnd_main = 0;
  34.220 +    videodata->ime_himc = 0;
  34.221 +    if (videodata->ime_himm32) {
  34.222 +        FreeLibrary(videodata->ime_himm32);
  34.223 +        videodata->ime_himm32 = 0;
  34.224 +    }
  34.225 +    if (videodata->ime_threadmgr) {
  34.226 +        videodata->ime_threadmgr->lpVtbl->Release(videodata->ime_threadmgr);
  34.227 +        videodata->ime_threadmgr = 0;
  34.228 +    }
  34.229 +    if (videodata->ime_com_initialized) {
  34.230 +        CoUninitialize();
  34.231 +        videodata->ime_com_initialized = SDL_FALSE;
  34.232 +    }
  34.233 +    videodata->ime_initialized = SDL_FALSE;
  34.234 +}
  34.235 +
  34.236 +static void
  34.237 +IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd)
  34.238 +{
  34.239 +    DWORD id = 0;
  34.240 +    HIMC himc = 0;
  34.241 +    WCHAR buffer[16];
  34.242 +    WCHAR *s = buffer;
  34.243 +    DWORD len = 0;
  34.244 +    DWORD err = 0;
  34.245 +    BOOL vertical = FALSE;
  34.246 +    UINT maxuilen = 0;
  34.247 +    static OSVERSIONINFOA osversion = {0};
  34.248 +    if (videodata->ime_uiless)
  34.249 +        return;
  34.250 +
  34.251 +    videodata->ime_readingstring[0] = 0;
  34.252 +    if (!osversion.dwOSVersionInfoSize) {
  34.253 +        osversion.dwOSVersionInfoSize = sizeof(osversion);
  34.254 +        GetVersionExA(&osversion);
  34.255 +    }
  34.256 +    id = IME_GetId(videodata, 0);
  34.257 +    if (!id)
  34.258 +        return;
  34.259 +
  34.260 +    himc = ImmGetContext(hwnd);
  34.261 +    if (!himc)
  34.262 +        return;
  34.263 +
  34.264 +    if (videodata->GetReadingString) {
  34.265 +        len = videodata->GetReadingString(himc, 0, 0, &err, &vertical, &maxuilen);
  34.266 +        if (len) {
  34.267 +            if (len > SDL_arraysize(buffer))
  34.268 +                len = SDL_arraysize(buffer);
  34.269 +
  34.270 +            len = videodata->GetReadingString(himc, len, s, &err, &vertical, &maxuilen);
  34.271 +        }
  34.272 +        SDL_wcslcpy(videodata->ime_readingstring, s, len);
  34.273 +    }
  34.274 +    else {
  34.275 +        LPINPUTCONTEXT2 lpimc = videodata->ImmLockIMC(himc);
  34.276 +        LPBYTE p = 0;
  34.277 +        s = 0;
  34.278 +        switch (id)
  34.279 +        {
  34.280 +        case IMEID_CHT_VER42:
  34.281 +        case IMEID_CHT_VER43:
  34.282 +        case IMEID_CHT_VER44:
  34.283 +            p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 24);
  34.284 +            if (!p)
  34.285 +                break;
  34.286 +
  34.287 +            len = *(DWORD *)(p + 7*4 + 32*4);
  34.288 +            s = (WCHAR *)(p + 56);
  34.289 +            break;
  34.290 +        case IMEID_CHT_VER51:
  34.291 +        case IMEID_CHT_VER52:
  34.292 +        case IMEID_CHS_VER53:
  34.293 +            p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 4);
  34.294 +            if (!p)
  34.295 +                break;
  34.296 +
  34.297 +            p = *(LPBYTE *)((LPBYTE)p + 1*4 + 5*4);
  34.298 +            if (!p)
  34.299 +                break;
  34.300 +
  34.301 +            len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2);
  34.302 +            s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4);
  34.303 +            break;
  34.304 +        case IMEID_CHS_VER41:
  34.305 +            {
  34.306 +                int offset = (IME_GetId(videodata, 1) >= 0x00000002) ? 8 : 7;
  34.307 +                p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + offset * 4);
  34.308 +                if (!p)
  34.309 +                    break;
  34.310 +
  34.311 +                len = *(DWORD *)(p + 7*4 + 16*2*4);
  34.312 +                s = (WCHAR *)(p + 6*4 + 16*2*1);
  34.313 +            }
  34.314 +            break;
  34.315 +        case IMEID_CHS_VER42:
  34.316 +            if (osversion.dwPlatformId != VER_PLATFORM_WIN32_NT)
  34.317 +                break;
  34.318 +
  34.319 +            p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 1*4 + 1*4 + 6*4);
  34.320 +            if (!p)
  34.321 +                break;
  34.322 +
  34.323 +            len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2);
  34.324 +            s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4);
  34.325 +            break;
  34.326 +        }
  34.327 +        if (s)
  34.328 +            SDL_wcslcpy(videodata->ime_readingstring, s, len + 1);
  34.329 +
  34.330 +        videodata->ImmUnlockIMCC(lpimc->hPrivate);
  34.331 +        videodata->ImmUnlockIMC(himc);
  34.332 +    }
  34.333 +    ImmReleaseContext(hwnd, himc);
  34.334 +    IME_SendEditingEvent(videodata);
  34.335 +}
  34.336 +
  34.337 +static void
  34.338 +IME_InputLangChanged(SDL_VideoData *videodata)
  34.339 +{
  34.340 +    UINT lang = PRIMLANG();
  34.341 +    HWND hwndime = 0;
  34.342 +    IME_UpdateInputLocale(videodata);
  34.343 +    IME_SetupAPI(videodata);
  34.344 +    if (lang != PRIMLANG()) {
  34.345 +        IME_ClearComposition(videodata);
  34.346 +    }
  34.347 +    hwndime = ImmGetDefaultIMEWnd(videodata->ime_hwnd_current);
  34.348 +    if (hwndime) {
  34.349 +        SendMessageA(hwndime, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0);
  34.350 +        SendMessageA(hwndime, WM_IME_CONTROL, IMC_CLOSESTATUSWINDOW, 0);
  34.351 +    }
  34.352 +}
  34.353 +
  34.354 +static DWORD
  34.355 +IME_GetId(SDL_VideoData *videodata, UINT uIndex)
  34.356 +{
  34.357 +    static HKL hklprev = 0;
  34.358 +    static DWORD dwRet[2] = {0};
  34.359 +    DWORD dwVerSize = 0;
  34.360 +    DWORD dwVerHandle = 0;
  34.361 +    LPVOID lpVerBuffer = 0;
  34.362 +    LPVOID lpVerData = 0;
  34.363 +    UINT cbVerData = 0;
  34.364 +    char szTemp[256];
  34.365 +    HKL hkl = 0;
  34.366 +    DWORD dwLang = 0;
  34.367 +    if (uIndex >= sizeof(dwRet) / sizeof(dwRet[0]))
  34.368 +        return 0;
  34.369 +
  34.370 +    hkl = videodata->ime_hkl;
  34.371 +    if (hklprev == hkl)
  34.372 +        return dwRet[uIndex];
  34.373 +
  34.374 +    hklprev = hkl;
  34.375 +    dwLang = ((DWORD)hkl & 0xffff);
  34.376 +    if (videodata->ime_uiless && LANG() == LANG_CHT) {
  34.377 +        dwRet[0] = IMEID_CHT_VER_VISTA;
  34.378 +        dwRet[1] = 0;
  34.379 +        return dwRet[0];
  34.380 +    }
  34.381 +    if (hkl != CHT_HKL_NEW_PHONETIC
  34.382 +        && hkl != CHT_HKL_NEW_CHANG_JIE
  34.383 +        && hkl != CHT_HKL_NEW_QUICK
  34.384 +        && hkl != CHT_HKL_HK_CANTONESE
  34.385 +        && hkl != CHS_HKL) {
  34.386 +        dwRet[0] = dwRet[1] = 0;
  34.387 +        return dwRet[uIndex];
  34.388 +    }
  34.389 +    if (ImmGetIMEFileNameA(hkl, szTemp, sizeof(szTemp) - 1) <= 0) {
  34.390 +        dwRet[0] = dwRet[1] = 0;
  34.391 +        return dwRet[uIndex];
  34.392 +    }
  34.393 +    if (!videodata->GetReadingString) {
  34.394 +        #define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
  34.395 +        if (CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME1, -1) != 2
  34.396 +            && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME2, -1) != 2
  34.397 +            && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME3, -1) != 2
  34.398 +            && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME1, -1) != 2
  34.399 +            && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME2, -1) != 2) {
  34.400 +            dwRet[0] = dwRet[1] = 0;
  34.401 +            return dwRet[uIndex];
  34.402 +        }
  34.403 +        #undef LCID_INVARIANT
  34.404 +        dwVerSize = GetFileVersionInfoSizeA(szTemp, &dwVerHandle);
  34.405 +        if (dwVerSize) {
  34.406 +            lpVerBuffer = SDL_malloc(dwVerSize);
  34.407 +            if (lpVerBuffer) {
  34.408 +                if (GetFileVersionInfoA(szTemp, dwVerHandle, dwVerSize, lpVerBuffer)) {
  34.409 +                    if (VerQueryValueA(lpVerBuffer, "\\", &lpVerData, &cbVerData)) {
  34.410 +                        #define pVerFixedInfo   ((VS_FIXEDFILEINFO FAR*)lpVerData)
  34.411 +                        DWORD dwVer = pVerFixedInfo->dwFileVersionMS;
  34.412 +                        dwVer = (dwVer & 0x00ff0000) << 8 | (dwVer & 0x000000ff) << 16;
  34.413 +                        if (videodata->GetReadingString ||
  34.414 +                            dwLang == LANG_CHT && (
  34.415 +                            dwVer == MAKEIMEVERSION(4, 2) ||
  34.416 +                            dwVer == MAKEIMEVERSION(4, 3) ||
  34.417 +                            dwVer == MAKEIMEVERSION(4, 4) ||
  34.418 +                            dwVer == MAKEIMEVERSION(5, 0) ||
  34.419 +                            dwVer == MAKEIMEVERSION(5, 1) ||
  34.420 +                            dwVer == MAKEIMEVERSION(5, 2) ||
  34.421 +                            dwVer == MAKEIMEVERSION(6, 0))
  34.422 +                            ||
  34.423 +                            dwLang == LANG_CHS && (
  34.424 +                            dwVer == MAKEIMEVERSION(4, 1) ||
  34.425 +                            dwVer == MAKEIMEVERSION(4, 2) ||
  34.426 +                            dwVer == MAKEIMEVERSION(5, 3))) {
  34.427 +                            dwRet[0] = dwVer | dwLang;
  34.428 +                            dwRet[1] = pVerFixedInfo->dwFileVersionLS;
  34.429 +                            SDL_free(lpVerBuffer);
  34.430 +                            return dwRet[0];
  34.431 +                        }
  34.432 +                        #undef pVerFixedInfo
  34.433 +                    }
  34.434 +                }
  34.435 +            }
  34.436 +            SDL_free(lpVerBuffer);
  34.437 +        }
  34.438 +    }
  34.439 +    dwRet[0] = dwRet[1] = 0;
  34.440 +    return dwRet[uIndex];
  34.441 +}
  34.442 +
  34.443 +static void
  34.444 +IME_SetupAPI(SDL_VideoData *videodata)
  34.445 +{
  34.446 +    char ime_file[MAX_PATH + 1];
  34.447 +    HMODULE hime = 0;
  34.448 +    HKL hkl = 0;
  34.449 +    videodata->GetReadingString = 0;
  34.450 +    videodata->ShowReadingWindow = 0;
  34.451 +    if (videodata->ime_uiless)
  34.452 +        return;
  34.453 +
  34.454 +    hkl = videodata->ime_hkl;
  34.455 +    if (ImmGetIMEFileNameA(hkl, ime_file, sizeof(ime_file) - 1) <= 0)
  34.456 +        return;
  34.457 +
  34.458 +    hime = LoadLibraryA(ime_file);
  34.459 +    if (!hime)
  34.460 +        return;
  34.461 +
  34.462 +    videodata->GetReadingString = (UINT (WINAPI *)(HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT))
  34.463 +        GetProcAddress(hime, "GetReadingString");
  34.464 +    videodata->ShowReadingWindow = (BOOL (WINAPI *)(HIMC, BOOL))
  34.465 +        GetProcAddress(hime, "ShowReadingWindow");
  34.466 +
  34.467 +    if (videodata->ShowReadingWindow) {
  34.468 +        HIMC himc = ImmGetContext(videodata->ime_hwnd_current);
  34.469 +        if (himc) {
  34.470 +            videodata->ShowReadingWindow(himc, FALSE);
  34.471 +            ImmReleaseContext(videodata->ime_hwnd_current, himc);
  34.472 +        }
  34.473 +    }
  34.474 +}
  34.475 +
  34.476 +static void
  34.477 +IME_SetWindow(SDL_VideoData* videodata, HWND hwnd)
  34.478 +{
  34.479 +    videodata->ime_hwnd_current = hwnd;
  34.480 +    if (videodata->ime_threadmgr) {
  34.481 +        struct ITfDocumentMgr *document_mgr = 0;
  34.482 +        if (SUCCEEDED(videodata->ime_threadmgr->lpVtbl->AssociateFocus(videodata->ime_threadmgr, hwnd, NULL, &document_mgr))) {
  34.483 +            if (document_mgr)
  34.484 +                document_mgr->lpVtbl->Release(document_mgr);
  34.485 +        }
  34.486 +    }
  34.487 +}
  34.488 +
  34.489 +static void
  34.490 +IME_UpdateInputLocale(SDL_VideoData *videodata)
  34.491 +{
  34.492 +    static HKL hklprev = 0;
  34.493 +    videodata->ime_hkl = GetKeyboardLayout(0);
  34.494 +    if (hklprev == videodata->ime_hkl)
  34.495 +        return;
  34.496 +
  34.497 +    hklprev = videodata->ime_hkl;
  34.498 +}
  34.499 +
  34.500 +static void
  34.501 +IME_ClearComposition(SDL_VideoData *videodata)
  34.502 +{
  34.503 +    HIMC himc = 0;
  34.504 +    if (!videodata->ime_initialized)
  34.505 +        return;
  34.506 +
  34.507 +    himc = ImmGetContext(videodata->ime_hwnd_current);
  34.508 +    if (!himc)
  34.509 +        return;
  34.510 +
  34.511 +    ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
  34.512 +    if (videodata->ime_uiless)
  34.513 +        ImmSetCompositionString(himc, SCS_SETSTR, TEXT(""), sizeof(TCHAR), TEXT(""), sizeof(TCHAR));
  34.514 +
  34.515 +    ImmNotifyIME(himc, NI_CLOSECANDIDATE, 0, 0);
  34.516 +    ImmReleaseContext(videodata->ime_hwnd_current, himc);
  34.517 +    SDL_SendEditingText("", 0, 0);
  34.518 +}
  34.519 +
  34.520 +static void
  34.521 +IME_ClearEditing(SDL_VideoData *videodata)
  34.522 +{
  34.523 +
  34.524 +}
  34.525 +
  34.526 +static void
  34.527 +IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, DWORD string)
  34.528 +{
  34.529 +    LONG length = ImmGetCompositionStringW(himc, string, videodata->ime_composition, sizeof(videodata->ime_composition));
  34.530 +    if (length < 0)
  34.531 +        length = 0;
  34.532 +
  34.533 +    length /= sizeof(videodata->ime_composition[0]);
  34.534 +    videodata->ime_cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0));
  34.535 +    if (videodata->ime_composition[videodata->ime_cursor] == 0x3000) {
  34.536 +        int i;
  34.537 +        for (i = videodata->ime_cursor + 1; i < length; ++i)
  34.538 +            videodata->ime_composition[i - 1] = videodata->ime_composition[i];
  34.539 +
  34.540 +        --length;
  34.541 +    }
  34.542 +    videodata->ime_composition[length] = 0;
  34.543 +}
  34.544 +
  34.545 +static void
  34.546 +IME_SendInputEvent(SDL_VideoData *videodata)
  34.547 +{
  34.548 +    char *s = 0;
  34.549 +    s = WIN_StringToUTF8(videodata->ime_composition);
  34.550 +    SDL_SendKeyboardText(s);
  34.551 +    SDL_free(s);
  34.552 +
  34.553 +    videodata->ime_composition[0] = 0;
  34.554 +    videodata->ime_readingstring[0] = 0;
  34.555 +    videodata->ime_cursor = 0;
  34.556 +}
  34.557 +
  34.558 +static void
  34.559 +IME_SendEditingEvent(SDL_VideoData *videodata)
  34.560 +{
  34.561 +    char *s = 0;
  34.562 +    WCHAR buffer[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
  34.563 +    buffer[0] = 0;
  34.564 +    if (videodata->ime_readingstring[0]) {
  34.565 +        size_t len = SDL_min(SDL_wcslen(videodata->ime_composition), (size_t)videodata->ime_cursor);
  34.566 +        SDL_wcslcpy(buffer, videodata->ime_composition, len + 1);
  34.567 +        SDL_wcslcat(buffer, videodata->ime_readingstring, sizeof(buffer));
  34.568 +        SDL_wcslcat(buffer, &videodata->ime_composition[len], sizeof(buffer) - len);
  34.569 +    }
  34.570 +    else {
  34.571 +        SDL_wcslcpy(buffer, videodata->ime_composition, sizeof(videodata->ime_composition));
  34.572 +    }
  34.573 +    s = WIN_StringToUTF8(buffer);
  34.574 +    SDL_SendEditingText(s, videodata->ime_cursor + SDL_wcslen(videodata->ime_readingstring), 0);
  34.575 +    SDL_free(s);
  34.576 +}
  34.577 +
  34.578 +SDL_bool
  34.579 +IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata)
  34.580 +{
  34.581 +    SDL_bool trap = SDL_FALSE;
  34.582 +    HIMC himc = 0;
  34.583 +    if (!videodata->ime_initialized || !videodata->ime_available || !videodata->ime_enabled)
  34.584 +        return SDL_FALSE;
  34.585 +
  34.586 +    switch (msg)
  34.587 +    {
  34.588 +    case WM_INPUTLANGCHANGE:
  34.589 +        //IME_InputLangChanged(videodata);
  34.590 +        break;
  34.591 +    case WM_IME_SETCONTEXT:
  34.592 +        *lParam = 0;
  34.593 +        break;
  34.594 +    case WM_IME_STARTCOMPOSITION:
  34.595 +        trap = SDL_TRUE;
  34.596 +        break;
  34.597 +    case WM_IME_COMPOSITION:
  34.598 +        trap = SDL_TRUE;
  34.599 +        himc = ImmGetContext(hwnd);
  34.600 +        if (*lParam & GCS_RESULTSTR) {
  34.601 +            IME_GetCompositionString(videodata, himc, GCS_RESULTSTR);
  34.602 +            IME_SendInputEvent(videodata);
  34.603 +        }
  34.604 +        if (*lParam & GCS_COMPSTR) {
  34.605 +            if (!videodata->ime_uiless)
  34.606 +                videodata->ime_readingstring[0] = 0;
  34.607 +
  34.608 +            IME_GetCompositionString(videodata, himc, GCS_COMPSTR);
  34.609 +            IME_SendEditingEvent(videodata);
  34.610 +        }
  34.611 +        ImmReleaseContext(hwnd, himc);
  34.612 +        break;
  34.613 +    case WM_IME_ENDCOMPOSITION:
  34.614 +        videodata->ime_composition[0] = 0;
  34.615 +        videodata->ime_readingstring[0] = 0;
  34.616 +        videodata->ime_cursor = 0;
  34.617 +        SDL_SendEditingText("", 0, 0);
  34.618 +        break;
  34.619 +    case WM_IME_NOTIFY:
  34.620 +        switch (wParam)
  34.621 +        {
  34.622 +        case IMN_SETCONVERSIONMODE:
  34.623 +        case IMN_SETOPENSTATUS:
  34.624 +            IME_UpdateInputLocale(videodata);
  34.625 +            break;
  34.626 +        case IMN_OPENCANDIDATE:
  34.627 +        case IMN_CHANGECANDIDATE:
  34.628 +            trap = SDL_TRUE;
  34.629 +            break;
  34.630 +        case IMN_CLOSECANDIDATE:
  34.631 +            trap = SDL_TRUE;
  34.632 +            break;
  34.633 +        case IMN_PRIVATE:
  34.634 +            {
  34.635 +                DWORD dwId = IME_GetId(videodata, 0);
  34.636 +                IME_GetReadingString(videodata, hwnd);
  34.637 +                switch (dwId)
  34.638 +                {
  34.639 +                case IMEID_CHT_VER42:
  34.640 +                case IMEID_CHT_VER43:
  34.641 +                case IMEID_CHT_VER44:
  34.642 +                case IMEID_CHS_VER41:
  34.643 +                case IMEID_CHS_VER42:
  34.644 +                    if (*lParam == 1 || *lParam == 2)
  34.645 +                        trap = SDL_TRUE;
  34.646 +
  34.647 +                    break;
  34.648 +                case IMEID_CHT_VER50:
  34.649 +                case IMEID_CHT_VER51:
  34.650 +                case IMEID_CHT_VER52:
  34.651 +                case IMEID_CHT_VER60:
  34.652 +                case IMEID_CHS_VER53:
  34.653 +                    if (*lParam == 16
  34.654 +                        || *lParam == 17
  34.655 +                        || *lParam == 26
  34.656 +                        || *lParam == 27
  34.657 +                        || *lParam == 28)
  34.658 +                        trap = SDL_TRUE;
  34.659 +                    break;
  34.660 +                }
  34.661 +            }
  34.662 +            break;
  34.663 +        default:
  34.664 +            trap = SDL_TRUE;
  34.665 +            break;
  34.666 +        }
  34.667 +        break;
  34.668 +    }
  34.669 +    return trap;
  34.670 +}
  34.671 +
  34.672 +STDMETHODIMP_(ULONG) TSFSink_AddRef(TSFSink *sink)
  34.673 +{
  34.674 +    return ++sink->refcount;
  34.675 +}
  34.676 +
  34.677 +STDMETHODIMP_(ULONG)TSFSink_Release(TSFSink *sink)
  34.678 +{
  34.679 +    --sink->refcount;
  34.680 +    if (sink->refcount == 0)
  34.681 +    {
  34.682 +        SDL_free(sink);
  34.683 +        return 0;
  34.684 +    }
  34.685 +    return sink->refcount;
  34.686 +}
  34.687 +
  34.688 +STDMETHODIMP UIElementSink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv)
  34.689 +{
  34.690 +    if (!ppv)
  34.691 +        return E_INVALIDARG;
  34.692 +
  34.693 +    *ppv = 0;
  34.694 +    if (SDL_IsEqualIID(riid, &IID_IUnknown))
  34.695 +        *ppv = (IUnknown *)sink;
  34.696 +    else if (SDL_IsEqualIID(riid, &IID_ITfUIElementSink))
  34.697 +        *ppv = (ITfUIElementSink *)sink;
  34.698 +
  34.699 +    if (*ppv) {
  34.700 +        TSFSink_AddRef(sink);
  34.701 +        return S_OK;
  34.702 +    }
  34.703 +    return E_NOINTERFACE;
  34.704 +}
  34.705 +
  34.706 +ITfUIElement *UILess_GetUIElement(SDL_VideoData *videodata, DWORD dwUIElementId)
  34.707 +{
  34.708 +    ITfUIElementMgr *puiem = 0;
  34.709 +    ITfUIElement *pelem = 0;
  34.710 +    ITfThreadMgrEx *threadmgrex = videodata->ime_threadmgrex;
  34.711 +
  34.712 +    if (SUCCEEDED(threadmgrex->lpVtbl->QueryInterface(threadmgrex, &IID_ITfUIElementMgr, (LPVOID *)&puiem))) {
  34.713 +        puiem->lpVtbl->GetUIElement(puiem, dwUIElementId, &pelem);
  34.714 +        puiem->lpVtbl->Release(puiem);
  34.715 +    }
  34.716 +    return pelem;
  34.717 +}
  34.718 +
  34.719 +STDMETHODIMP UIElementSink_BeginUIElement(TSFSink *sink, DWORD dwUIElementId, BOOL *pbShow)
  34.720 +{
  34.721 +    ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
  34.722 +    ITfReadingInformationUIElement *preading = 0;
  34.723 +    SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
  34.724 +    if (!element)
  34.725 +        return E_INVALIDARG;
  34.726 +
  34.727 +    *pbShow = FALSE;
  34.728 +    if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
  34.729 +        BSTR bstr;
  34.730 +        if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) {
  34.731 +            WCHAR *s = (WCHAR *)bstr;
  34.732 +            SysFreeString(bstr);
  34.733 +        }
  34.734 +        preading->lpVtbl->Release(preading);
  34.735 +    }
  34.736 +    return S_OK;
  34.737 +}
  34.738 +
  34.739 +STDMETHODIMP UIElementSink_UpdateUIElement(TSFSink *sink, DWORD dwUIElementId)
  34.740 +{
  34.741 +    ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
  34.742 +    ITfReadingInformationUIElement *preading = 0;
  34.743 +    SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
  34.744 +    if (!element)
  34.745 +        return E_INVALIDARG;
  34.746 +
  34.747 +    if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
  34.748 +        BSTR bstr;
  34.749 +        if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) {
  34.750 +            WCHAR *s = (WCHAR *)bstr;
  34.751 +            SDL_wcslcpy(videodata->ime_readingstring, s, sizeof(videodata->ime_readingstring));
  34.752 +            IME_SendEditingEvent(videodata);
  34.753 +            SysFreeString(bstr);
  34.754 +        }
  34.755 +        preading->lpVtbl->Release(preading);
  34.756 +    }
  34.757 +    return S_OK;
  34.758 +}
  34.759 +
  34.760 +STDMETHODIMP UIElementSink_EndUIElement(TSFSink *sink, DWORD dwUIElementId)
  34.761 +{
  34.762 +    ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
  34.763 +    ITfReadingInformationUIElement *preading = 0;
  34.764 +    SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
  34.765 +    if (!element)
  34.766 +        return E_INVALIDARG;
  34.767 +
  34.768 +    if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
  34.769 +        videodata->ime_readingstring[0] = 0;
  34.770 +        IME_SendEditingEvent(videodata);
  34.771 +        preading->lpVtbl->Release(preading);
  34.772 +    }
  34.773 +    return S_OK;
  34.774 +}
  34.775 +
  34.776 +STDMETHODIMP IPPASink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv)
  34.777 +{
  34.778 +    if (!ppv)
  34.779 +        return E_INVALIDARG;
  34.780 +
  34.781 +    *ppv = 0;
  34.782 +    if (SDL_IsEqualIID(riid, &IID_IUnknown))
  34.783 +        *ppv = (IUnknown *)sink;
  34.784 +    else if (SDL_IsEqualIID(riid, &IID_ITfInputProcessorProfileActivationSink))
  34.785 +        *ppv = (ITfInputProcessorProfileActivationSink *)sink;
  34.786 +
  34.787 +    if (*ppv) {
  34.788 +        TSFSink_AddRef(sink);
  34.789 +        return S_OK;
  34.790 +    }
  34.791 +    return E_NOINTERFACE;
  34.792 +}
  34.793 +
  34.794 +STDMETHODIMP IPPASink_OnActivated(TSFSink *sink, DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, REFGUID guidProfile, HKL hkl, DWORD dwFlags)
  34.795 +{
  34.796 +    if (SDL_IsEqualIID(catid, &GUID_TFCAT_TIP_KEYBOARD) && (dwFlags & TF_IPSINK_FLAG_ACTIVE))
  34.797 +        IME_InputLangChanged((SDL_VideoData *)sink->data);
  34.798 +
  34.799 +    return S_OK;
  34.800 +}
  34.801 +
  34.802 +static void *vtUIElementSink[] = {
  34.803 +    (void *)(UIElementSink_QueryInterface),
  34.804 +    (void *)(TSFSink_AddRef),
  34.805 +    (void *)(TSFSink_Release),
  34.806 +    (void *)(UIElementSink_BeginUIElement),
  34.807 +    (void *)(UIElementSink_UpdateUIElement),
  34.808 +    (void *)(UIElementSink_EndUIElement)
  34.809 +};
  34.810 +
  34.811 +static void *vtIPPASink[] = {
  34.812 +    (void *)(IPPASink_QueryInterface),
  34.813 +    (void *)(TSFSink_AddRef),
  34.814 +    (void *)(TSFSink_Release),
  34.815 +    (void *)(IPPASink_OnActivated)
  34.816 +};
  34.817 +
  34.818 +static void
  34.819 +UILess_EnableUIUpdates(SDL_VideoData *videodata)
  34.820 +{
  34.821 +    ITfSource *source = 0;
  34.822 +    if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie != TF_INVALID_COOKIE)
  34.823 +        return;
  34.824 +
  34.825 +    if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
  34.826 +        source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie);
  34.827 +        source->lpVtbl->Release(source);
  34.828 +    }
  34.829 +}
  34.830 +
  34.831 +static void
  34.832 +UILess_DisableUIUpdates(SDL_VideoData *videodata)
  34.833 +{
  34.834 +    ITfSource *source = 0;
  34.835 +    if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie == TF_INVALID_COOKIE)
  34.836 +        return;
  34.837 +
  34.838 +    if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
  34.839 +        source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie);
  34.840 +        videodata->ime_uielemsinkcookie = TF_INVALID_COOKIE;
  34.841 +        source->lpVtbl->Release(source);
  34.842 +    }
  34.843 +}
  34.844 +
  34.845 +static SDL_bool
  34.846 +UILess_SetupSinks(SDL_VideoData *videodata)
  34.847 +{
  34.848 +    TfClientId clientid = 0;
  34.849 +    SDL_bool result = SDL_FALSE;
  34.850 +    ITfSource *source = 0;
  34.851 +    if (FAILED(CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgrEx, &videodata->ime_threadmgrex)))
  34.852 +        return SDL_FALSE;
  34.853 +
  34.854 +    if (FAILED(videodata->ime_threadmgrex->lpVtbl->ActivateEx(videodata->ime_threadmgrex, &clientid, TF_TMAE_UIELEMENTENABLEDONLY)))
  34.855 +        return SDL_FALSE;
  34.856 +
  34.857 +    videodata->ime_uielemsink = SDL_malloc(sizeof(TSFSink));
  34.858 +    videodata->ime_ippasink = SDL_malloc(sizeof(TSFSink));
  34.859 +
  34.860 +    videodata->ime_uielemsink->lpVtbl = vtUIElementSink;
  34.861 +    videodata->ime_uielemsink->refcount = 1;
  34.862 +    videodata->ime_uielemsink->data = videodata;
  34.863 +
  34.864 +    videodata->ime_ippasink->lpVtbl = vtIPPASink;
  34.865 +    videodata->ime_ippasink->refcount = 1;
  34.866 +    videodata->ime_ippasink->data = videodata;
  34.867 +
  34.868 +    if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
  34.869 +        if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie))) {
  34.870 +            if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfInputProcessorProfileActivationSink, (IUnknown *)videodata->ime_ippasink, &videodata->ime_alpnsinkcookie))) {
  34.871 +                result = SDL_TRUE;
  34.872 +            }
  34.873 +        }
  34.874 +        source->lpVtbl->Release(source);
  34.875 +    }
  34.876 +    return result;
  34.877 +}
  34.878 +
  34.879 +#define SAFE_RELEASE(p)                             \
  34.880 +{                                                   \
  34.881 +    if (p) {                                        \
  34.882 +        (p)->lpVtbl->Release((p));                  \
  34.883 +        (p) = 0;                                    \
  34.884 +    }                                               \
  34.885 +}
  34.886 +
  34.887 +static void
  34.888 +UILess_ReleaseSinks(SDL_VideoData *videodata)
  34.889 +{
  34.890 +    ITfSource *source = 0;
  34.891 +    if (videodata->ime_threadmgrex && SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, &source))) {
  34.892 +        source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie);
  34.893 +        source->lpVtbl->UnadviseSink(source, videodata->ime_alpnsinkcookie);
  34.894 +        SAFE_RELEASE(source);
  34.895 +        videodata->ime_threadmgrex->lpVtbl->Deactivate(videodata->ime_threadmgrex);
  34.896 +        SAFE_RELEASE(videodata->ime_threadmgrex);
  34.897 +        TSFSink_Release(videodata->ime_uielemsink);
  34.898 +        videodata->ime_uielemsink = 0;
  34.899 +        TSFSink_Release(videodata->ime_ippasink);
  34.900 +        videodata->ime_ippasink = 0;
  34.901 +    }
  34.902  }
  34.903  
  34.904  /* vi: set ts=4 sw=4 expandtab: */
    35.1 --- a/src/video/win32/SDL_win32keyboard.h	Sun Aug 22 12:35:34 2010 -0700
    35.2 +++ b/src/video/win32/SDL_win32keyboard.h	Sun Aug 22 12:39:27 2010 -0700
    35.3 @@ -31,6 +31,12 @@
    35.4  extern void WIN_UpdateKeymap(void);
    35.5  extern void WIN_QuitKeyboard(_THIS);
    35.6  
    35.7 +extern void WIN_StartTextInput(_THIS);
    35.8 +extern void WIN_StopTextInput(_THIS);
    35.9 +extern void WIN_SetTextInputRect(_THIS, SDL_Rect *rect);
   35.10 +
   35.11 +extern SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata);
   35.12 +
   35.13  #endif /* _SDL_win32keyboard_h */
   35.14  
   35.15  /* vi: set ts=4 sw=4 expandtab: */
    36.1 --- a/src/video/win32/SDL_win32video.c	Sun Aug 22 12:35:34 2010 -0700
    36.2 +++ b/src/video/win32/SDL_win32video.c	Sun Aug 22 12:39:27 2010 -0700
    36.3 @@ -191,6 +191,9 @@
    36.4      device->GL_SwapWindow = WIN_GL_SwapWindow;
    36.5      device->GL_DeleteContext = WIN_GL_DeleteContext;
    36.6  #endif
    36.7 +    device->StartTextInput = WIN_StartTextInput;
    36.8 +    device->StopTextInput = WIN_StopTextInput;
    36.9 +    device->SetTextInputRect = WIN_SetTextInputRect;
   36.10  
   36.11      device->SetClipboardText = WIN_SetClipboardText;
   36.12      device->GetClipboardText = WIN_GetClipboardText;
    37.1 --- a/src/video/win32/SDL_win32video.h	Sun Aug 22 12:35:34 2010 -0700
    37.2 +++ b/src/video/win32/SDL_win32video.h	Sun Aug 22 12:39:27 2010 -0700
    37.3 @@ -42,6 +42,8 @@
    37.4  
    37.5  #include <windows.h>
    37.6  
    37.7 +#include <msctf.h>
    37.8 +
    37.9  #if SDL_VIDEO_RENDER_D3D
   37.10  //#include <d3d9.h>
   37.11  #define D3D_DEBUG_INFO
   37.12 @@ -62,6 +64,7 @@
   37.13  #include "SDL_win32mouse.h"
   37.14  #include "SDL_win32opengl.h"
   37.15  #include "SDL_win32window.h"
   37.16 +#include "SDL_events.h"
   37.17  
   37.18  #ifdef UNICODE
   37.19  #define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "UCS-2", (char *)S, (SDL_wcslen(S)+1)*sizeof(WCHAR))
   37.20 @@ -77,6 +80,37 @@
   37.21  typedef BOOL  (*PFNSHFullScreen)(HWND, DWORD);
   37.22  typedef void  (*PFCoordTransform)(SDL_Window*, POINT*);
   37.23  
   37.24 +typedef struct  
   37.25 +{
   37.26 +    void **lpVtbl;
   37.27 +    int refcount;
   37.28 +    void *data;
   37.29 +} TSFSink;
   37.30 +
   37.31 +// Definition from Win98DDK version of IMM.H
   37.32 +typedef struct tagINPUTCONTEXT2 {
   37.33 +    HWND                hWnd;                           
   37.34 +    BOOL                fOpen;                          
   37.35 +    POINT               ptStatusWndPos;                 
   37.36 +    POINT               ptSoftKbdPos;                   
   37.37 +    DWORD               fdwConversion;                  
   37.38 +    DWORD               fdwSentence;                    
   37.39 +    union   {                                           
   37.40 +        LOGFONTA        A;                              
   37.41 +        LOGFONTW        W;                              
   37.42 +    } lfFont;                                           
   37.43 +    COMPOSITIONFORM     cfCompForm;                     
   37.44 +    CANDIDATEFORM       cfCandForm[4];                  
   37.45 +    HIMCC               hCompStr;                       
   37.46 +    HIMCC               hCandInfo;                      
   37.47 +    HIMCC               hGuideLine;                     
   37.48 +    HIMCC               hPrivate;                       
   37.49 +    DWORD               dwNumMsgBuf;                    
   37.50 +    HIMCC               hMsgBuf;                        
   37.51 +    DWORD               fdwInit;                        
   37.52 +    DWORD               dwReserve[3];                   
   37.53 +} INPUTCONTEXT2, *PINPUTCONTEXT2, NEAR *NPINPUTCONTEXT2, FAR *LPINPUTCONTEXT2;  
   37.54 +
   37.55  /* Private display data */
   37.56  
   37.57  typedef struct SDL_VideoData
   37.58 @@ -97,9 +131,39 @@
   37.59      PFCoordTransform CoordTransform;
   37.60  #endif
   37.61  
   37.62 +    const SDL_scancode *key_layout;
   37.63      DWORD clipboard_count;
   37.64  
   37.65 -    const SDL_scancode *key_layout;
   37.66 +    SDL_bool ime_com_initialized;
   37.67 +    struct ITfThreadMgr *ime_threadmgr;
   37.68 +    SDL_bool ime_initialized;
   37.69 +    SDL_bool ime_enabled;
   37.70 +    SDL_bool ime_available;
   37.71 +    HWND ime_hwnd_main;
   37.72 +    HWND ime_hwnd_current;
   37.73 +    HIMC ime_himc;
   37.74 +
   37.75 +    WCHAR ime_composition[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
   37.76 +    WCHAR ime_readingstring[16];
   37.77 +    int ime_cursor;
   37.78 +
   37.79 +    HKL ime_hkl;
   37.80 +    HMODULE ime_himm32;
   37.81 +    UINT (WINAPI *GetReadingString)(HIMC himc, UINT uReadingBufLen, LPWSTR lpwReadingBuf, PINT pnErrorIndex, BOOL *pfIsVertical, PUINT puMaxReadingLen);
   37.82 +    BOOL (WINAPI *ShowReadingWindow)(HIMC himc, BOOL bShow);
   37.83 +    LPINPUTCONTEXT2 (WINAPI *ImmLockIMC)(HIMC himc);
   37.84 +    BOOL (WINAPI *ImmUnlockIMC)(HIMC himc);
   37.85 +    LPVOID (WINAPI *ImmLockIMCC)(HIMCC himcc);
   37.86 +    BOOL (WINAPI *ImmUnlockIMCC)(HIMCC himcc);
   37.87 +
   37.88 +    SDL_bool ime_uiless;
   37.89 +    struct ITfThreadMgrEx *ime_threadmgrex;
   37.90 +    DWORD ime_uielemsinkcookie;
   37.91 +    DWORD ime_alpnsinkcookie;
   37.92 +    DWORD ime_openmodesinkcookie;
   37.93 +    DWORD ime_convmodesinkcookie;
   37.94 +    TSFSink *ime_uielemsink;
   37.95 +    TSFSink *ime_ippasink;
   37.96  } SDL_VideoData;
   37.97  
   37.98  #endif /* _SDL_win32video_h */
    38.1 --- a/src/video/win32/SDL_win32window.c	Sun Aug 22 12:35:34 2010 -0700
    38.2 +++ b/src/video/win32/SDL_win32window.c	Sun Aug 22 12:39:27 2010 -0700
    38.3 @@ -77,10 +77,12 @@
    38.4  
    38.5      /* Set up the window proc function */
    38.6      data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
    38.7 -    if (data->wndproc == DefWindowProc) {
    38.8 +    if (data->wndproc == WIN_WindowProc) {
    38.9          data->wndproc = NULL;
   38.10      }
   38.11 -    SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc);
   38.12 +    else {
   38.13 +        SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc);
   38.14 +    }
   38.15  
   38.16      /* Fill in the SDL window with the window data */
   38.17      {
    39.1 --- a/test/testime.c	Sun Aug 22 12:35:34 2010 -0700
    39.2 +++ b/test/testime.c	Sun Aug 22 12:39:27 2010 -0700
    39.3 @@ -25,7 +25,49 @@
    39.4  SDL_Rect textRect, markedRect;
    39.5  Uint32 lineColor, backColor;
    39.6  SDL_Color textColor = { 0, 0, 0 };
    39.7 -char text[MAX_TEXT_LENGTH], *markedText;
    39.8 +char text[MAX_TEXT_LENGTH], markedText[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
    39.9 +int cursor = 0;
   39.10 +
   39.11 +size_t utf8_length(unsigned char c)
   39.12 +{
   39.13 +    c = (unsigned char)(0xff & c);
   39.14 +    if (c < 0x80)
   39.15 +        return 1;
   39.16 +    else if ((c >> 5) ==0x6)
   39.17 +        return 2;
   39.18 +    else if ((c >> 4) == 0xe)
   39.19 +        return 3;
   39.20 +    else if ((c >> 3) == 0x1e)
   39.21 +        return 4;
   39.22 +    else
   39.23 +        return 0;
   39.24 +}
   39.25 +
   39.26 +char *utf8_next(char *p)
   39.27 +{
   39.28 +    size_t len = utf8_length(*p);
   39.29 +    size_t i = 0;
   39.30 +    if (!len)
   39.31 +        return 0;
   39.32 +
   39.33 +    for (; i < len; ++i)
   39.34 +    {
   39.35 +        ++p;
   39.36 +        if (!*p)
   39.37 +            return 0;
   39.38 +    }
   39.39 +    return p;
   39.40 +}
   39.41 +
   39.42 +char *utf8_advance(char *p, size_t distance)
   39.43 +{
   39.44 +    size_t i = 0;
   39.45 +    for (; i < distance && p; ++i)
   39.46 +    {
   39.47 +        p = utf8_next(p);
   39.48 +    }
   39.49 +    return p;
   39.50 +}
   39.51  
   39.52  void usage()
   39.53  {
   39.54 @@ -124,7 +166,7 @@
   39.55  
   39.56      text[0] = 0;
   39.57      markedRect = textRect;
   39.58 -    markedText = NULL;
   39.59 +    markedText[0] = 0;
   39.60  
   39.61      SDL_StartTextInput();
   39.62  }
   39.63 @@ -180,9 +222,22 @@
   39.64      cursorRect.h = h;
   39.65  
   39.66      SDL_FillRect(screen, &markedRect, backColor);
   39.67 -    if (markedText)
   39.68 +    if (markedText[0])
   39.69      {
   39.70  #ifdef HAVE_SDL_TTF
   39.71 +        if (cursor)
   39.72 +        {
   39.73 +            char *p = utf8_advance(markedText, cursor);
   39.74 +            char c = 0;
   39.75 +            if (!p)
   39.76 +                p = &markedText[strlen(markedText)];
   39.77 +
   39.78 +            c = *p;
   39.79 +            *p = 0;
   39.80 +            TTF_SizeUTF8(font, markedText, &w, 0);
   39.81 +            cursorRect.x += w;
   39.82 +            *p = c;
   39.83 +        }
   39.84          RenderText(screen, font, markedText, markedRect.x, markedRect.y, textColor);
   39.85          TTF_SizeUTF8(font, markedText, &w, &h);
   39.86  #endif
   39.87 @@ -192,8 +247,6 @@
   39.88          underlineRect.h = 2;
   39.89          underlineRect.w = w;
   39.90  
   39.91 -        cursorRect.x += w + 1;
   39.92 -
   39.93          SDL_FillRect(screen, &underlineRect, lineColor);
   39.94      }
   39.95  
   39.96 @@ -295,13 +348,13 @@
   39.97              fprintf(stderr, "Keyboard: text input \"%s\"\n", event.text.text);
   39.98  
   39.99              if (SDL_strlen(text) + SDL_strlen(event.text.text) < sizeof(text))
  39.100 -                SDL_strlcpy(text + SDL_strlen(text), event.text.text, sizeof(text));
  39.101 +                SDL_strlcat(text, event.text.text, sizeof(text));
  39.102  
  39.103              fprintf(stderr, "text inputed: %s\n", text);
  39.104  
  39.105              // After text inputed, we can clear up markedText because it
  39.106              // is committed
  39.107 -            markedText = NULL;
  39.108 +            markedText[0] = 0;
  39.109              Redraw();
  39.110              break;
  39.111  
  39.112 @@ -309,7 +362,8 @@
  39.113              fprintf(stderr, "text editing \"%s\", selected range (%d, %d)\n",
  39.114                      event.edit.text, event.edit.start, event.edit.length);
  39.115  
  39.116 -            markedText = event.edit.text;
  39.117 +            strcpy(markedText, event.edit.text);
  39.118 +            cursor = event.edit.start;
  39.119              Redraw();
  39.120              break;
  39.121