Added GLIMM (using IMM instead of TSF)
authordewyatt
Wed, 30 Jun 2010 17:29:20 -0400
changeset 4741 bb189d44af16
parent 4740 abf528de6d2e
child 4742 59b0750575b1
Added GLIMM (using IMM instead of TSF) Uses small bit of TSF to fully disable cicero (TSF for non-TSF enabled apps)
EXCLUDE/GLIMM/GLIMM.sln
EXCLUDE/GLIMM/GLIMM.vcproj
EXCLUDE/GLIMM/include/App.hpp
EXCLUDE/GLIMM/include/IMM.hpp
EXCLUDE/GLIMM/include/Video_Mode.hpp
EXCLUDE/GLIMM/include/Window.hpp
EXCLUDE/GLIMM/include/Window_Listener.hpp
EXCLUDE/GLIMM/src/App.cpp
EXCLUDE/GLIMM/src/IMM.cpp
EXCLUDE/GLIMM/src/Main.cpp
EXCLUDE/GLIMM/src/Video_Mode.cpp
EXCLUDE/GLIMM/src/Window.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EXCLUDE/GLIMM/GLIMM.sln	Wed Jun 30 17:29:20 2010 -0400
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GLIMM", "GLIMM.vcproj", "{F21B830F-20A9-4473-B67A-21D1743C6E19}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{F21B830F-20A9-4473-B67A-21D1743C6E19}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F21B830F-20A9-4473-B67A-21D1743C6E19}.Debug|Win32.Build.0 = Debug|Win32
+		{F21B830F-20A9-4473-B67A-21D1743C6E19}.Release|Win32.ActiveCfg = Release|Win32
+		{F21B830F-20A9-4473-B67A-21D1743C6E19}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EXCLUDE/GLIMM/GLIMM.vcproj	Wed Jun 30 17:29:20 2010 -0400
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="GLIMM"
+	ProjectGUID="{F21B830F-20A9-4473-B67A-21D1743C6E19}"
+	RootNamespace="GLIMM"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)bin"
+			IntermediateDirectory="obj\$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="imm32.lib"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)bin"
+			IntermediateDirectory="obj\$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories="include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="imm32.lib"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\src\App.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\IMM.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\Main.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\Video_Mode.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\Window.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\include\App.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\include\IMM.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\include\Video_Mode.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\include\Window.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\include\Window_Listener.hpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EXCLUDE/GLIMM/include/App.hpp	Wed Jun 30 17:29:20 2010 -0400
@@ -0,0 +1,36 @@
+#ifndef APP_HPP
+#define APP_HPP
+
+#include "Window.hpp"
+
+class App : public Window_Listener
+{
+public:
+	App();
+	virtual ~App();
+
+	void Initialize();
+	void Finalize();
+
+	void Run();
+
+	virtual void On_Close();
+	virtual void On_Key_Down(int Key);
+	virtual void On_Key_Up(int Key);
+	virtual void On_Char(unsigned int Char);
+	virtual void On_Resized(unsigned int Width, unsigned int Height);
+
+private:
+	void Update();
+	void Draw();
+
+	static const int Width = 800;
+	static const int Height = 600;
+	static const int Bits_Per_Pixel = 32;
+	static const bool Fullscreen = false;
+
+	Window my_Window;
+	bool my_Done;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EXCLUDE/GLIMM/include/IMM.hpp	Wed Jun 30 17:29:20 2010 -0400
@@ -0,0 +1,30 @@
+#ifndef IMM_HPP
+#define IMM_HPP
+
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#include <msctf.h>
+
+class IMM
+{
+public:
+	IMM();
+	~IMM();
+
+	void Initialize(HWND Window);
+	void Finalize();
+
+	LRESULT Handle_Message(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam, bool &Ate);
+
+private:
+	void Update_Input_Locale();
+
+	bool my_COM_Initialized;
+	ITfThreadMgr *my_Thread_Manager;
+	HWND my_Window;
+	HIMC my_Context;
+	HKL my_HKL;
+	bool my_Vertical_Candidates;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EXCLUDE/GLIMM/include/Video_Mode.hpp	Wed Jun 30 17:29:20 2010 -0400
@@ -0,0 +1,30 @@
+#ifndef VIDEO_MODE_HPP
+#define VIDEO_MODE_HPP
+
+#include <cstddef>
+
+class Video_Mode
+{
+public:
+	Video_Mode();
+	Video_Mode(unsigned int The_Width, unsigned int The_Height, unsigned int The_Bits_Per_Pixel);
+
+	static Video_Mode Get_Desktop_Mode();
+
+	static std::size_t Get_Mode_Count();
+	static Video_Mode Get_Mode(std::size_t Index);
+
+	bool Is_Valid() const;
+
+	bool operator==(const Video_Mode &Mode) const;
+	bool operator!=(const Video_Mode &Mode) const;
+
+	unsigned int Width;
+	unsigned int Height;
+	unsigned int Bits_Per_Pixel;
+
+private:
+	static void Initialize_Modes();
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EXCLUDE/GLIMM/include/Window.hpp	Wed Jun 30 17:29:20 2010 -0400
@@ -0,0 +1,62 @@
+#ifndef WINDOW_HPP
+#define WINDOW_HPP
+
+#include <string>
+
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+
+#include "Video_Mode.hpp"
+#include "Window_Listener.hpp"
+#include "IMM.hpp"
+
+class Window
+{
+public:
+	Window();
+	~Window();
+
+	void Initialize(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen);
+	void Finalize();
+
+	void Set_Listener(Window_Listener *Listener);
+
+	void Show();
+	void Hide();
+
+	void Handle_Events();
+	void Display();
+
+	void Show_Cursor();
+	void Hide_Cursor();
+
+	HWND Get_Handle();
+
+private:
+	static const wchar_t *Window_Class_Name;
+
+	void Register_Class();
+	void Unregister_Class();
+
+	void Create_Window(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen);
+	void Destroy_Window();
+
+	void Create_Context(const Video_Mode &Mode);
+	void Destroy_Context();
+
+	void Switch_To_Fullscreen(const Video_Mode &Mode);
+
+	LRESULT Handle_Message(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam);
+	static LRESULT CALLBACK Window_Procedure(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam);
+
+	HWND my_Handle;
+	Video_Mode my_Video_Mode;
+	bool my_Fullscreen;
+	HDC my_Device_Context;
+	HGLRC my_GL_Context;
+	bool my_Class_Registered;
+	Window_Listener *my_Listener;
+	IMM my_IMM;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EXCLUDE/GLIMM/include/Window_Listener.hpp	Wed Jun 30 17:29:20 2010 -0400
@@ -0,0 +1,14 @@
+#ifndef WINDOW_LISTENER_HPP
+#define WINDOW_LISTENER_HPP
+
+class Window_Listener
+{
+public:
+	virtual void On_Close(){}
+	virtual void On_Key_Down(int Key){}
+	virtual void On_Key_Up(int Key){}
+	virtual void On_Char(unsigned int Char){}
+	virtual void On_Resized(unsigned int Width, unsigned int Height){}
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EXCLUDE/GLIMM/src/App.cpp	Wed Jun 30 17:29:20 2010 -0400
@@ -0,0 +1,103 @@
+#include "App.hpp"
+#include <GL/gl.h>
+#include <GL/glu.h>
+
+#pragma comment(lib, "glu32.lib")
+
+GLfloat Rotation = 0.0f;
+
+App::App() : my_Done(false)
+{
+
+}
+
+App::~App()
+{
+	Finalize();
+}
+
+void App::Initialize()
+{
+	Finalize();
+
+	my_Window.Initialize(L"GLTSF", Video_Mode(Width, Height, Bits_Per_Pixel), Fullscreen);
+	my_Window.Set_Listener(this);
+	my_Window.Show();
+	my_Window.Hide_Cursor();
+}
+
+void App::Finalize()
+{
+	my_Window.Finalize();
+}
+
+void App::Run()
+{
+	Initialize();
+	while (!my_Done)
+	{
+		my_Window.Handle_Events();
+
+		Update();
+		Draw();
+		my_Window.Display();
+	}
+}
+
+void App::On_Close()
+{
+	my_Done = true;
+	my_Window.Hide();
+}
+
+void App::On_Key_Down(int Key)
+{
+	switch (Key)
+	{
+	case VK_ESCAPE:
+		On_Close();
+		break;
+	}
+}
+
+void App::On_Key_Up(int Key)
+{
+
+}
+
+void App::On_Char(unsigned int Char)
+{
+	printf("Char: U+%04X\n", Char);
+}
+
+void App::On_Resized(unsigned int Width, unsigned int Height)
+{
+	glViewport(0, 0, Width, Height);
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+}
+
+void App::Update()
+{
+	Rotation += 0.2f;
+}
+
+void App::Draw()
+{
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	glLoadIdentity();
+	glRotatef(Rotation, 0.0f, 0.0f, -1.0f);
+
+	glBegin(GL_TRIANGLES);
+		glColor3f(0.7f, 0.0f, 0.0f);
+		glVertex3f(0.0f, 0.5f, 0.0f);
+		glColor3f(0.0f, 0.7f, 0.0f);
+		glVertex3f(-0.5f, -0.5f, 0.0f);
+		glColor3f(0.0f, 0.0f, 0.7f);
+		glVertex3f(0.5f, -0.5f, 0.0f);
+	glEnd();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EXCLUDE/GLIMM/src/IMM.cpp	Wed Jun 30 17:29:20 2010 -0400
@@ -0,0 +1,165 @@
+#include "IMM.hpp"
+#include <stdexcept>
+
+IMM::IMM() : my_COM_Initialized(false),
+			 my_Thread_Manager(0),
+			 my_Window(0),
+			 my_Context(0),
+			 my_HKL(0),
+			 my_Vertical_Candidates(false)
+{
+
+}
+
+IMM::~IMM()
+{
+	Finalize();
+}
+
+void IMM::Initialize(HWND Window)
+{
+	Finalize();
+
+	my_Window = Window;
+
+	if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
+	{
+		my_COM_Initialized = true;
+		if (SUCCEEDED(CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, reinterpret_cast<LPVOID *>(&my_Thread_Manager))))
+		{
+			ITfDocumentMgr *Document_Manager = 0;
+			if (FAILED(my_Thread_Manager->AssociateFocus(Window, NULL, &Document_Manager)))
+				printf("Warning: ITfThreadMgr->AssociateFocus failed\n");
+
+			if (Document_Manager)
+				Document_Manager->Release();
+		}
+		else
+			printf("Warning: Failed to create ITfThreadMgr instance\n");
+	}
+	else
+		printf("Warning: Failed to initialize COM\n");
+
+	ImmDisableTextFrameService(-1);
+
+	my_Context = ImmGetContext(my_Window);
+	if (!ImmReleaseContext(my_Window, my_Context))
+		throw std::runtime_error("Error releasing context");
+
+	if (!my_Context)
+		throw std::runtime_error("No context");
+
+	Update_Input_Locale();
+}
+
+void IMM::Finalize()
+{
+	if (my_Thread_Manager)
+	{
+		my_Thread_Manager->Release();
+		my_Thread_Manager = 0;
+	}
+	if (my_COM_Initialized)
+	{
+		CoUninitialize();
+		my_COM_Initialized = false;
+	}
+}
+
+#define GET_LANG(hkl) LOWORD((hkl))
+#define GET_PRIMLANG(hkl) ((WORD)PRIMARYLANGID(GET_LANG((hkl))))
+#define GET_SUBLANG(hkl) SUBLANGID(GET_LANG((hkl)))
+
+void IMM::Update_Input_Locale()
+{
+	static HKL Previous_HKL = 0;
+	my_HKL = GetKeyboardLayout(0);
+	if (Previous_HKL == my_HKL)
+		return;
+
+	Previous_HKL = my_HKL;
+	my_Vertical_Candidates = false;
+	switch (GET_PRIMLANG(my_HKL))
+	{
+	case LANG_CHINESE:
+		my_Vertical_Candidates = true;
+		switch (GET_SUBLANG(my_HKL))
+		{
+		case SUBLANG_CHINESE_SIMPLIFIED:
+			my_Vertical_Candidates = false;
+			break;
+		}
+		break;
+	case LANG_JAPANESE:
+		my_Vertical_Candidates = true;
+		break;
+	}
+}
+
+LRESULT IMM::Handle_Message(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam, bool &Ate)
+{
+	Ate = false;
+	switch (Message)
+	{
+	case WM_INPUTLANGCHANGE:
+		Update_Input_Locale();
+		break;
+	case WM_IME_SETCONTEXT:
+		lParam = 0;
+		return DefWindowProcW(my_Window, Message, wParam, lParam);
+		break;
+	case WM_IME_STARTCOMPOSITION:
+		Ate = true;
+		break;
+	case WM_IME_COMPOSITION:
+		{
+			Ate = true;
+			HIMC Context = ImmGetContext(Window);
+			if (!Context)
+				break;
+
+			if (lParam & GCS_RESULTSTR)
+			{
+				LONG Length = ImmGetCompositionStringW(Context, GCS_RESULTSTR, 0, 0);
+				std::wstring Composition(Length / sizeof(wchar_t), 0);
+				Length = ImmGetCompositionStringW(Context, GCS_RESULTSTR, &Composition[0], Composition.size() * sizeof(Composition[0]));
+				printf("GCS_RESULTSTR: ");
+				for (LONG i = 0; i < Length / sizeof(wchar_t); ++i)
+					printf("U+%04X ", Composition[i]);
+
+				printf("\n");
+			}
+			if (lParam & GCS_COMPSTR)
+			{
+				LONG Length = ImmGetCompositionStringW(Context, GCS_COMPSTR, 0, 0);
+				std::wstring Composition(Length / sizeof(wchar_t), 0);
+				Length = ImmGetCompositionStringW(Context, GCS_COMPSTR, &Composition[0], Composition.size() * sizeof(Composition[0]));
+				printf("GCS_COMPSTR: ");
+				for (LONG i = 0; i < Length / sizeof(wchar_t); ++i)
+					printf("U+%04X ", Composition[i]);
+
+				printf("\n");
+			}
+			ImmReleaseContext(Window, Context);
+		}
+		break;
+	case WM_IME_ENDCOMPOSITION:
+		break;
+	case WM_IME_NOTIFY:
+		switch (wParam)
+		{
+		case IMN_SETCONVERSIONMODE:
+
+			break;
+		case IMN_SETOPENSTATUS:
+			Update_Input_Locale();
+			break;
+		case IMN_OPENCANDIDATE:
+		case IMN_CHANGECANDIDATE:
+			Ate = true;
+			break;
+		}
+		break;
+	}
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EXCLUDE/GLIMM/src/Main.cpp	Wed Jun 30 17:29:20 2010 -0400
@@ -0,0 +1,24 @@
+#include "App.hpp"
+#include <stdexcept>
+
+int main(int argc, char *argv[])
+{
+	int Result = EXIT_SUCCESS;
+	try
+	{
+		App theApp;
+		theApp.Run();
+	}
+	catch (const std::exception& e)
+	{
+		printf("Error: %s\n", e.what());
+		Result = EXIT_FAILURE;
+	}
+	catch (...)
+	{
+		printf("Unhandled exception\n");
+		Result = EXIT_FAILURE;
+	}
+	system("PAUSE");
+	return Result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EXCLUDE/GLIMM/src/Video_Mode.cpp	Wed Jun 30 17:29:20 2010 -0400
@@ -0,0 +1,100 @@
+#include "Video_Mode.hpp"
+#include <vector>
+#include <algorithm>
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+
+namespace
+{
+
+	typedef std::vector<Video_Mode> Video_Mode_List;
+	Video_Mode_List Supported_Modes;
+
+	struct Compare_Modes
+	{
+		bool operator()(const Video_Mode &Mode_1, const Video_Mode &Mode_2) const
+		{
+			if (Mode_1.Bits_Per_Pixel > Mode_2.Bits_Per_Pixel)
+				return true;
+			else if (Mode_1.Bits_Per_Pixel < Mode_2.Bits_Per_Pixel)
+				return false;
+			else if (Mode_1.Width > Mode_2.Width)
+				return true;
+			else if (Mode_1.Width < Mode_2.Width)
+				return false;
+			else
+				return Mode_1.Height > Mode_2.Height;
+		}
+	};
+
+}
+
+Video_Mode::Video_Mode() : Width(0),
+						   Height(0),
+						   Bits_Per_Pixel(0)
+{
+
+}
+
+Video_Mode::Video_Mode(unsigned int The_Width, unsigned int The_Height, unsigned int The_Bits_Per_Pixel)
+	: Width(The_Width),
+	  Height(The_Height),
+	  Bits_Per_Pixel(The_Bits_Per_Pixel)
+{
+
+}
+
+Video_Mode Video_Mode::Get_Desktop_Mode()
+{
+	DEVMODE Device_Mode = {0};
+	Device_Mode.dmSize = sizeof(Device_Mode);
+	EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &Device_Mode);
+	return Video_Mode(Device_Mode.dmPelsWidth, Device_Mode.dmPelsHeight, Device_Mode.dmBitsPerPel);
+}
+
+std::size_t Video_Mode::Get_Mode_Count()
+{
+	Initialize_Modes();
+	return Supported_Modes.size();
+}
+
+Video_Mode Video_Mode::Get_Mode(std::size_t Index)
+{
+	Initialize_Modes();
+	return Supported_Modes[Index];
+}
+
+bool Video_Mode::Is_Valid() const
+{
+	Initialize_Modes();
+	return Supported_Modes.end() != std::find(Supported_Modes.begin(), Supported_Modes.end(), *this);
+}
+
+bool Video_Mode::operator==(const Video_Mode &Mode) const
+{
+	return (Width == Mode.Width
+		&&  Height == Mode.Height
+		&&  Bits_Per_Pixel == Mode.Bits_Per_Pixel);
+}
+
+bool Video_Mode::operator!=(const Video_Mode &Mode) const
+{
+	return !(*this == Mode);
+}
+
+void Video_Mode::Initialize_Modes()
+{
+	static bool Initialized = false;
+	if (!Initialized)
+	{
+		DEVMODE Device_Mode = {0};
+		Device_Mode.dmSize = sizeof(Device_Mode);
+		for (std::size_t i = 0; 0 != EnumDisplaySettings(NULL, i, &Device_Mode); ++i)
+		{
+			Video_Mode Mode(Device_Mode.dmPelsWidth, Device_Mode.dmPelsHeight, Device_Mode.dmBitsPerPel);
+			if (Supported_Modes.end() == std::find(Supported_Modes.begin(), Supported_Modes.end(), Mode))
+				Supported_Modes.push_back(Mode);
+		}
+		std::sort(Supported_Modes.begin(), Supported_Modes.end(), Compare_Modes());
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EXCLUDE/GLIMM/src/Window.cpp	Wed Jun 30 17:29:20 2010 -0400
@@ -0,0 +1,293 @@
+#include "Window.hpp"
+#include <gl/GL.h>
+
+#pragma comment(lib, "opengl32.lib")
+
+const wchar_t *Window::Window_Class_Name = L"GLTSF";
+
+Window::Window() : my_Handle(0),
+				   my_Device_Context(0),
+				   my_GL_Context(0),
+				   my_Class_Registered(false),
+				   my_Listener(0)
+{
+
+}
+
+Window::~Window()
+{
+	Finalize();
+	Show_Cursor();
+}
+
+void Window::Initialize(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen)
+{
+	Finalize();
+
+	my_Video_Mode = Mode;
+	if (!my_Video_Mode.Is_Valid())
+		throw std::runtime_error("Invalid video mode");
+
+	my_Fullscreen = Fullscreen;
+	Register_Class();
+	Create_Window(Title, Mode, Fullscreen);
+	my_IMM.Initialize(my_Handle);
+}
+
+void Window::Finalize()
+{
+	my_IMM.Finalize();
+	Destroy_Window();
+	Unregister_Class();
+}
+
+void Window::Set_Listener(Window_Listener *Listener)
+{
+	my_Listener = Listener;
+}
+
+void Window::Show()
+{
+	if (my_Handle)
+		ShowWindow(my_Handle, SW_SHOW);
+}
+
+void Window::Hide()
+{
+	if (my_Handle)
+		ShowWindow(my_Handle, SW_HIDE);
+}
+
+void Window::Handle_Events()
+{
+	MSG Message = {0};
+	while (PeekMessageW(&Message, NULL, 0, 0, PM_REMOVE))
+	{
+		TranslateMessage(&Message);
+		DispatchMessageW(&Message);
+	}
+}
+
+void Window::Display()
+{
+	if (my_Device_Context && my_GL_Context)
+		SwapBuffers(my_Device_Context);
+}
+
+void Window::Show_Cursor()
+{
+	ShowCursor(TRUE);
+}
+
+void Window::Hide_Cursor()
+{
+	ShowCursor(FALSE);
+}
+
+HWND Window::Get_Handle()
+{
+	return my_Handle;
+}
+
+void Window::Register_Class()
+{
+	WNDCLASSEXW Window_Class = {0};
+	Window_Class.cbSize = sizeof(Window_Class);
+	Window_Class.style = 0;
+	Window_Class.lpfnWndProc = &Window::Window_Procedure;
+	Window_Class.cbClsExtra = 0;
+	Window_Class.cbWndExtra = 0;
+	Window_Class.hInstance = GetModuleHandle(NULL);
+	Window_Class.hIcon = NULL;
+	Window_Class.hCursor = NULL;
+	Window_Class.hbrBackground = NULL;
+	Window_Class.lpszMenuName = NULL;
+	Window_Class.lpszClassName = Window_Class_Name;
+	Window_Class.hIconSm = NULL;
+	if (0 == RegisterClassExW(&Window_Class))
+		throw std::runtime_error("Failed to register window class");
+
+	my_Class_Registered = true;
+}
+
+void Window::Unregister_Class()
+{
+	if (my_Class_Registered)
+	{
+		if (0 == UnregisterClassW(Window_Class_Name, GetModuleHandle(NULL)))
+			printf("Warning: Failed to unregister window class\n");
+
+		my_Class_Registered = false;
+	}
+}
+
+void Window::Create_Window(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen)
+{
+	HDC Screen_DC = GetDC(NULL);
+	int Left = (GetDeviceCaps(Screen_DC, HORZRES) - my_Video_Mode.Width) / 2;
+	int Top = (GetDeviceCaps(Screen_DC, VERTRES) - my_Video_Mode.Height) / 2;
+	int Width = my_Video_Mode.Width;
+	int Height = my_Video_Mode.Height;
+	ReleaseDC(NULL, Screen_DC);
+
+	DWORD Style = WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU;
+	if (!my_Fullscreen)
+	{
+		RECT Rect = {0, 0, Width, Height};
+		AdjustWindowRect(&Rect, Style, false);
+		Width = Rect.right - Rect.left;
+		Height = Rect.bottom - Rect.top;
+	}
+	my_Handle = CreateWindowW(Window_Class_Name, Title.c_str(), Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
+	if (!my_Handle)
+		throw std::runtime_error("Failed to create window");
+
+	if (Fullscreen)
+		Switch_To_Fullscreen(Mode);
+
+	Create_Context(Mode);
+
+	RECT Rect = {0};
+	GetClientRect(my_Handle, &Rect);
+	//TODO: ...
+}
+
+void Window::Destroy_Window()
+{
+	Destroy_Context();
+	if (my_Handle)
+	{
+		DestroyWindow(my_Handle);
+		my_Handle = 0;
+
+		if (my_Fullscreen)
+			ChangeDisplaySettings(NULL, 0);
+	}
+}
+
+void Window::Create_Context(const Video_Mode &Mode)
+{
+	my_Device_Context = GetDC(my_Handle);
+	if (!my_Device_Context)
+		throw std::runtime_error("Failed to get device context");
+
+	PIXELFORMATDESCRIPTOR Pixel_Descriptor = {0};
+	Pixel_Descriptor.nSize = sizeof(Pixel_Descriptor);
+	Pixel_Descriptor.nVersion = 1;
+	Pixel_Descriptor.iLayerType = PFD_MAIN_PLANE;
+	Pixel_Descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+	Pixel_Descriptor.iPixelType = PFD_TYPE_RGBA;
+	Pixel_Descriptor.cColorBits = static_cast<BYTE>(Mode.Bits_Per_Pixel);
+	Pixel_Descriptor.cDepthBits = 24;
+	Pixel_Descriptor.cStencilBits = 8;
+	Pixel_Descriptor.cAlphaBits = Mode.Bits_Per_Pixel == 32 ? 8 : 0;
+
+	int Best_Format = ChoosePixelFormat(my_Device_Context, &Pixel_Descriptor);
+	if (0 == Best_Format)
+		throw std::runtime_error("Failed to find suitable pixel format");
+
+	PIXELFORMATDESCRIPTOR Actual_Format = {0};
+	Actual_Format.nSize = sizeof(Actual_Format);
+	Actual_Format.nVersion = 1;
+	DescribePixelFormat(my_Device_Context, Best_Format, sizeof(Actual_Format), &Actual_Format);
+	if (!SetPixelFormat(my_Device_Context, Best_Format, &Actual_Format))
+		throw std::runtime_error("Failed to set device pixel format");
+
+	my_GL_Context = wglCreateContext(my_Device_Context);
+	if (!my_GL_Context)
+		throw std::runtime_error("Failed to create OpenGL context");
+
+	wglMakeCurrent(my_Device_Context, my_GL_Context);
+}
+
+void Window::Destroy_Context()
+{
+	if (my_GL_Context)
+	{
+		wglDeleteContext(my_GL_Context);
+		my_GL_Context = 0;
+	}
+	if (my_Device_Context)
+	{
+		ReleaseDC(my_Handle, my_Device_Context);
+		my_Device_Context = 0;
+	}
+}
+
+void Window::Switch_To_Fullscreen(const Video_Mode &Mode)
+{
+	DEVMODE Device_Mode = {0};
+	Device_Mode.dmSize = sizeof(Device_Mode);
+	Device_Mode.dmPelsWidth = Mode.Width;
+	Device_Mode.dmPelsHeight = Mode.Height;
+	Device_Mode.dmBitsPerPel = Mode.Bits_Per_Pixel;
+	Device_Mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
+
+	if (DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettings(&Device_Mode, CDS_FULLSCREEN))
+		throw std::runtime_error("Failed to change to fullscreen mode");
+
+	SetWindowLong(my_Handle, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+	SetWindowLong(my_Handle, GWL_EXSTYLE, WS_EX_APPWINDOW);
+
+	SetWindowPos(my_Handle, HWND_TOP, 0, 0, Mode.Width, Mode.Height, SWP_FRAMECHANGED);
+}
+
+LRESULT CALLBACK Window::Window_Procedure(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam)
+{
+	switch (Message)
+	{
+	case WM_CREATE:
+		{
+			LONG This = reinterpret_cast<LONG>(reinterpret_cast<CREATESTRUCT *>(lParam)->lpCreateParams);
+			SetWindowLongPtr(Handle, GWLP_USERDATA, This);
+			return 0;
+		}
+		break;
+	case WM_DESTROY:
+		PostQuitMessage(0);
+		return 0;
+		break;
+	default:
+		{
+			Window* Win = reinterpret_cast<Window *>(GetWindowLongPtr(Handle, GWLP_USERDATA));
+			if (Win)
+				return Win->Handle_Message(Handle, Message, wParam, lParam);
+		}
+		break;
+	}
+	return DefWindowProcW(Handle, Message, wParam, lParam);
+}
+
+#define Call_Listener(x)\
+	if (my_Listener) my_Listener->x
+
+LRESULT Window::Handle_Message(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam)
+{
+	bool IMM_Message = false;
+	LRESULT Result = my_IMM.Handle_Message(Handle, Message, wParam, lParam, IMM_Message);
+	if (IMM_Message)
+		return Result;
+
+	switch (Message)
+	{
+	case WM_SIZE:
+		Call_Listener(On_Resized(LOWORD(lParam), HIWORD(lParam)));
+		break;
+	case WM_CLOSE:
+		Call_Listener(On_Close());
+		break;
+	case WM_KEYDOWN:
+		Call_Listener(On_Key_Down(wParam));
+		break;
+	case WM_KEYUP:
+		Call_Listener(On_Key_Up(wParam));
+		break;
+	case WM_CHAR:
+		Call_Listener(On_Char(wParam));
+		break;
+	default:
+		return DefWindowProcW(Handle, Message, wParam, lParam);
+		break;
+	}
+	return 0;
+}