Merged Daniel's Google Summer of Code work from SDL-gsoc2010_IME
This commit is contained in:
commit
1f8dacabd7
60 changed files with 3930 additions and 77 deletions
20
EXCLUDE/GLIMM/GLIMM.sln
Normal file
20
EXCLUDE/GLIMM/GLIMM.sln
Normal file
|
@ -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
|
233
EXCLUDE/GLIMM/GLIMM.vcproj
Normal file
233
EXCLUDE/GLIMM/GLIMM.vcproj
Normal file
|
@ -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>
|
37
EXCLUDE/GLIMM/include/App.hpp
Normal file
37
EXCLUDE/GLIMM/include/App.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#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);
|
||||
virtual void On_Mouse_Button_Down(Mouse_Button Button);
|
||||
|
||||
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 = true;
|
||||
|
||||
Window my_Window;
|
||||
bool my_Done;
|
||||
};
|
||||
|
||||
#endif
|
41
EXCLUDE/GLIMM/include/IMM.hpp
Normal file
41
EXCLUDE/GLIMM/include/IMM.hpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#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);
|
||||
|
||||
void Enable();
|
||||
void Disable();
|
||||
bool Is_Enabled();
|
||||
void Toggle();
|
||||
|
||||
void Focus_Gained();
|
||||
void Focus_Lost();
|
||||
|
||||
private:
|
||||
void Update_Input_Locale();
|
||||
void Cancel_Composition();
|
||||
void Input_Language_Changed();
|
||||
|
||||
bool my_COM_Initialized;
|
||||
ITfThreadMgr *my_Thread_Manager;
|
||||
HWND my_Window;
|
||||
HIMC my_Context;
|
||||
HKL my_HKL;
|
||||
bool my_Vertical_Candidates;
|
||||
bool my_Enabled;
|
||||
};
|
||||
|
||||
#endif
|
30
EXCLUDE/GLIMM/include/Video_Mode.hpp
Normal file
30
EXCLUDE/GLIMM/include/Video_Mode.hpp
Normal file
|
@ -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
|
63
EXCLUDE/GLIMM/include/Window.hpp
Normal file
63
EXCLUDE/GLIMM/include/Window.hpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
#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();
|
||||
IMM &Get_IMM();
|
||||
|
||||
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
|
23
EXCLUDE/GLIMM/include/Window_Listener.hpp
Normal file
23
EXCLUDE/GLIMM/include/Window_Listener.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef WINDOW_LISTENER_HPP
|
||||
#define WINDOW_LISTENER_HPP
|
||||
|
||||
enum Mouse_Button
|
||||
{
|
||||
Mouse_Button_Left,
|
||||
Mouse_Button_Right
|
||||
};
|
||||
|
||||
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){}
|
||||
virtual void On_Mouse_Button_Down(Mouse_Button Button){}
|
||||
virtual void On_Mouse_Button_Up(Mouse_Button Button){}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
113
EXCLUDE/GLIMM/src/App.cpp
Normal file
113
EXCLUDE/GLIMM/src/App.cpp
Normal file
|
@ -0,0 +1,113 @@
|
|||
#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"GLIMM", 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::On_Mouse_Button_Down(Mouse_Button Button)
|
||||
{
|
||||
switch (Button)
|
||||
{
|
||||
case Mouse_Button_Left:
|
||||
my_Window.Get_IMM().Toggle();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
237
EXCLUDE/GLIMM/src/IMM.cpp
Normal file
237
EXCLUDE/GLIMM/src/IMM.cpp
Normal file
|
@ -0,0 +1,237 @@
|
|||
#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),
|
||||
my_Enabled(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 (SUCCEEDED(my_Thread_Manager->AssociateFocus(Window, NULL, &Document_Manager)))
|
||||
{
|
||||
if (Document_Manager)
|
||||
Document_Manager->Release();
|
||||
}
|
||||
else
|
||||
printf("Warning: ITfThreadMgr->AssociateFocus failed\n");
|
||||
}
|
||||
else
|
||||
printf("Warning: Failed to create ITfThreadMgr instance\n");
|
||||
}
|
||||
else
|
||||
printf("Warning: Failed to initialize COM\n");
|
||||
|
||||
ImmDisableTextFrameService((DWORD)-1);
|
||||
|
||||
my_Context = ImmGetContext(my_Window);
|
||||
ImmReleaseContext(my_Window, my_Context);
|
||||
if (!my_Context)
|
||||
throw std::runtime_error("No context (No IME installed?)");
|
||||
|
||||
Update_Input_Locale();
|
||||
Cancel_Composition();
|
||||
Disable();
|
||||
}
|
||||
|
||||
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:
|
||||
Input_Language_Changed();
|
||||
break;
|
||||
case WM_IME_SETCONTEXT:
|
||||
lParam = 0;
|
||||
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;
|
||||
case IMN_CLOSECANDIDATE:
|
||||
Ate = true;
|
||||
break;
|
||||
default:
|
||||
Ate = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void IMM::Enable()
|
||||
{
|
||||
ImmAssociateContext(my_Window, my_Context);
|
||||
Update_Input_Locale();
|
||||
my_Enabled = true;
|
||||
printf("* Enabled\n");
|
||||
}
|
||||
|
||||
void IMM::Disable()
|
||||
{
|
||||
ImmAssociateContext(my_Window, 0);
|
||||
my_Enabled = false;
|
||||
printf("* Disabled\n");
|
||||
}
|
||||
|
||||
bool IMM::Is_Enabled()
|
||||
{
|
||||
return my_Enabled;
|
||||
}
|
||||
|
||||
void IMM::Toggle()
|
||||
{
|
||||
if (my_Enabled)
|
||||
Disable();
|
||||
else
|
||||
Enable();
|
||||
}
|
||||
|
||||
void IMM::Focus_Gained()
|
||||
{
|
||||
if (my_Enabled)
|
||||
Enable();
|
||||
}
|
||||
|
||||
void IMM::Focus_Lost()
|
||||
{
|
||||
bool Enabled = my_Enabled;
|
||||
Cancel_Composition();
|
||||
Disable();
|
||||
my_Enabled = Enabled;
|
||||
}
|
||||
|
||||
void IMM::Cancel_Composition()
|
||||
{
|
||||
HIMC hIMC = ImmGetContext(my_Window);
|
||||
if (!hIMC)
|
||||
return;
|
||||
|
||||
ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
|
||||
ImmNotifyIME(hIMC, NI_CLOSECANDIDATE, 0, 0);
|
||||
ImmReleaseContext(my_Window, hIMC);
|
||||
}
|
||||
|
||||
void IMM::Input_Language_Changed()
|
||||
{
|
||||
Update_Input_Locale();
|
||||
HWND hwndImeDef = ImmGetDefaultIMEWnd(my_Window);
|
||||
if (hwndImeDef)
|
||||
{
|
||||
SendMessageA(hwndImeDef, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0);
|
||||
SendMessageA(hwndImeDef, WM_IME_CONTROL, IMC_CLOSESTATUSWINDOW, 0);
|
||||
}
|
||||
}
|
24
EXCLUDE/GLIMM/src/Main.cpp
Normal file
24
EXCLUDE/GLIMM/src/Main.cpp
Normal file
|
@ -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;
|
||||
}
|
100
EXCLUDE/GLIMM/src/Video_Mode.cpp
Normal file
100
EXCLUDE/GLIMM/src/Video_Mode.cpp
Normal file
|
@ -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());
|
||||
}
|
||||
}
|
317
EXCLUDE/GLIMM/src/Window.cpp
Normal file
317
EXCLUDE/GLIMM/src/Window.cpp
Normal file
|
@ -0,0 +1,317 @@
|
|||
#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);
|
||||
Show();
|
||||
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;
|
||||
}
|
||||
|
||||
IMM & Window::Get_IMM()
|
||||
{
|
||||
return my_IMM;
|
||||
}
|
||||
|
||||
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;
|
||||
case WM_SETFOCUS:
|
||||
my_IMM.Focus_Gained();
|
||||
break;
|
||||
case WM_KILLFOCUS:
|
||||
my_IMM.Focus_Lost();
|
||||
break;
|
||||
case WM_LBUTTONDOWN:
|
||||
Call_Listener(On_Mouse_Button_Down(Mouse_Button_Left));
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
Call_Listener(On_Mouse_Button_Up(Mouse_Button_Left));
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
Call_Listener(On_Mouse_Button_Down(Mouse_Button_Right));
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
Call_Listener(On_Mouse_Button_Up(Mouse_Button_Right));
|
||||
break;
|
||||
default:
|
||||
return DefWindowProcW(Handle, Message, wParam, lParam);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
20
EXCLUDE/GLTSF/GLTSF.sln
Normal file
20
EXCLUDE/GLTSF/GLTSF.sln
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GLTSF", "GLTSF.vcxproj", "{790D58BA-E5F6-4286-A9C6-0DC28779789D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{790D58BA-E5F6-4286-A9C6-0DC28779789D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{790D58BA-E5F6-4286-A9C6-0DC28779789D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{790D58BA-E5F6-4286-A9C6-0DC28779789D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{790D58BA-E5F6-4286-A9C6-0DC28779789D}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
231
EXCLUDE/GLTSF/GLTSF.vcproj
Normal file
231
EXCLUDE/GLTSF/GLTSF.vcproj
Normal file
|
@ -0,0 +1,231 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="GLTSF"
|
||||
ProjectGUID="{FC8A9A48-6667-4BDE-8E9B-5859408AEE83}"
|
||||
RootNamespace="GLTSF"
|
||||
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"
|
||||
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"
|
||||
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\Main.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\TSF.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\TSF.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>
|
99
EXCLUDE/GLTSF/GLTSF.vcxproj
Normal file
99
EXCLUDE/GLTSF/GLTSF.vcxproj
Normal file
|
@ -0,0 +1,99 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{790D58BA-E5F6-4286-A9C6-0DC28779789D}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>GLTSF</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\</OutDir>
|
||||
<IntDir>obj\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\</OutDir>
|
||||
<IntDir>obj\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\App.hpp" />
|
||||
<ClInclude Include="include\TSF.hpp" />
|
||||
<ClInclude Include="include\Video_Mode.hpp" />
|
||||
<ClInclude Include="include\Window.hpp" />
|
||||
<ClInclude Include="include\Window_Listener.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\App.cpp" />
|
||||
<ClCompile Include="src\Main.cpp" />
|
||||
<ClCompile Include="src\TSF.cpp" />
|
||||
<ClCompile Include="src\Video_Mode.cpp" />
|
||||
<ClCompile Include="src\Window.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
51
EXCLUDE/GLTSF/GLTSF.vcxproj.filters
Normal file
51
EXCLUDE/GLTSF/GLTSF.vcxproj.filters
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\App.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Video_Mode.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Window.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Window_Listener.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\TSF.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\App.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Video_Mode.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Window.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\TSF.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
20
EXCLUDE/GLTSF/GLTSF_vs2008.sln
Normal file
20
EXCLUDE/GLTSF/GLTSF_vs2008.sln
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GLTSF", "GLTSF.vcproj", "{FC8A9A48-6667-4BDE-8E9B-5859408AEE83}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{FC8A9A48-6667-4BDE-8E9B-5859408AEE83}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{FC8A9A48-6667-4BDE-8E9B-5859408AEE83}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{FC8A9A48-6667-4BDE-8E9B-5859408AEE83}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{FC8A9A48-6667-4BDE-8E9B-5859408AEE83}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
36
EXCLUDE/GLTSF/include/App.hpp
Normal file
36
EXCLUDE/GLTSF/include/App.hpp
Normal file
|
@ -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 = true;
|
||||
|
||||
Window my_Window;
|
||||
bool my_Done;
|
||||
};
|
||||
|
||||
#endif
|
83
EXCLUDE/GLTSF/include/TSF.hpp
Normal file
83
EXCLUDE/GLTSF/include/TSF.hpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
#ifndef TSF_HPP
|
||||
#define TSF_HPP
|
||||
|
||||
#include <msctf.h>
|
||||
#include <atlbase.h>
|
||||
|
||||
class TSF
|
||||
{
|
||||
public:
|
||||
static void Initialize();
|
||||
static void Finalize();
|
||||
|
||||
private:
|
||||
class TSF_Text_Store : public ITextStoreACP, public ITfContextOwnerCompositionSink
|
||||
{
|
||||
public:
|
||||
//IUnknown
|
||||
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject);
|
||||
STDMETHODIMP_(ULONG) AddRef();
|
||||
STDMETHODIMP_(ULONG) Release();
|
||||
|
||||
//ITextStoreACP
|
||||
STDMETHODIMP AdviseSink(REFIID riid, IUnknown *punk, DWORD dwMask);
|
||||
STDMETHODIMP UnadviseSink(IUnknown *punk);
|
||||
STDMETHODIMP RequestLock(DWORD dwLockFlags, HRESULT *phrSession);
|
||||
STDMETHODIMP GetStatus(TS_STATUS *pdcs);
|
||||
STDMETHODIMP QueryInsert(LONG acpTestStart, LONG acpTestEnd, ULONG cch, LONG *pacpResultStart, LONG *pacpResultEnd);
|
||||
STDMETHODIMP GetSelection(ULONG ulIndex, ULONG ulCount, TS_SELECTION_ACP *pSelection, ULONG *pcFetched);
|
||||
STDMETHODIMP SetSelection(ULONG ulCount, const TS_SELECTION_ACP *pSelection);
|
||||
STDMETHODIMP GetText(LONG acpStart, LONG acpEnd, WCHAR *pchPlain, ULONG cchPlainReq, ULONG *pcchPlainRet, TS_RUNINFO *prgRunInfo, ULONG cRunInfoReq, ULONG *pcRunInfoRet, LONG *pacpNext);
|
||||
STDMETHODIMP SetText(DWORD dwFlags, LONG acpStart, LONG acpEnd, const WCHAR *pchText, ULONG cch, TS_TEXTCHANGE *pChange);
|
||||
STDMETHODIMP GetFormattedText(LONG acpStart, LONG acpEnd, IDataObject **ppDataObject);
|
||||
STDMETHODIMP GetEmbedded(LONG acpPos, REFGUID rguidService, REFIID riid, IUnknown **ppunk);
|
||||
STDMETHODIMP QueryInsertEmbedded(const GUID *pguidService, const FORMATETC *pFormatEtc, BOOL *pfInsertable);
|
||||
STDMETHODIMP InsertEmbedded(DWORD dwFlags, LONG acpStart, LONG acpEnd, IDataObject *pDataObject, TS_TEXTCHANGE *pChange);
|
||||
STDMETHODIMP InsertTextAtSelection(DWORD dwFlags, const WCHAR *pchText, ULONG cch, LONG *pacpStart, LONG *pacpEnd, TS_TEXTCHANGE *pChange);
|
||||
STDMETHODIMP InsertEmbeddedAtSelection(DWORD dwFlags, IDataObject *pDataObject, LONG *pacpStart, LONG *pacpEnd, TS_TEXTCHANGE *pChange);
|
||||
STDMETHODIMP RequestSupportedAttrs(DWORD dwFlags, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs);
|
||||
STDMETHODIMP RequestAttrsAtPosition(LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags);
|
||||
STDMETHODIMP RequestAttrsTransitioningAtPosition(LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags);
|
||||
STDMETHODIMP FindNextAttrTransition(LONG acpStart, LONG acpHalt, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags, LONG *pacpNext, BOOL *pfFound, LONG *plFoundOffset);
|
||||
STDMETHODIMP RetrieveRequestedAttrs(ULONG ulCount, TS_ATTRVAL *paAttrVals, ULONG *pcFetched);
|
||||
STDMETHODIMP GetEndACP(LONG *pacp);
|
||||
STDMETHODIMP GetActiveView(TsViewCookie *pvcView);
|
||||
STDMETHODIMP GetACPFromPoint(TsViewCookie vcView, const POINT *ptScreen, DWORD dwFlags, LONG *pacp);
|
||||
STDMETHODIMP GetTextExt(TsViewCookie vcView, LONG acpStart, LONG acpEnd, RECT *prc, BOOL *pfClipped);
|
||||
STDMETHODIMP GetScreenExt(TsViewCookie vcView, RECT *prc);
|
||||
STDMETHODIMP GetWnd(TsViewCookie vcView, HWND *phwnd);
|
||||
|
||||
//ITfOwnerCompositionSink
|
||||
STDMETHODIMP OnStartComposition(ITfCompositionView *pComposition, BOOL *pfOk);
|
||||
STDMETHODIMP OnUpdateComposition(ITfCompositionView *pComposition, ITfRange *pRangeNew);
|
||||
STDMETHODIMP OnEndComposition(ITfCompositionView *pComposition);
|
||||
|
||||
void Initialize();
|
||||
void Finalize();
|
||||
|
||||
TSF_Text_Store();
|
||||
~TSF_Text_Store();
|
||||
|
||||
private:
|
||||
ULONG my_Reference_Count;
|
||||
CComPtr<ITfDocumentMgr> my_Document_Manager;
|
||||
CComPtr<ITfContext> my_Context;
|
||||
DWORD my_Edit_Cookie;
|
||||
CComPtr<ITextStoreACPSink> my_Sink;
|
||||
DWORD my_Sink_Mask;
|
||||
DWORD my_Lock;
|
||||
DWORD my_Lock_Queued;
|
||||
CComPtr<ITfCompositionView> my_Composition_View;
|
||||
TS_SELECTION_ACP my_Composition_Selection;
|
||||
};
|
||||
|
||||
TSF();
|
||||
|
||||
static bool COM_Initialized;
|
||||
|
||||
static CComPtr<ITfThreadMgr> Thread_Manager;
|
||||
static TfClientId Client_Id;
|
||||
static TSF_Text_Store *Text_Store;
|
||||
};
|
||||
|
||||
#endif
|
30
EXCLUDE/GLTSF/include/Video_Mode.hpp
Normal file
30
EXCLUDE/GLTSF/include/Video_Mode.hpp
Normal file
|
@ -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
|
59
EXCLUDE/GLTSF/include/Window.hpp
Normal file
59
EXCLUDE/GLTSF/include/Window.hpp
Normal file
|
@ -0,0 +1,59 @@
|
|||
#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 "TSF.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();
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#endif
|
14
EXCLUDE/GLTSF/include/Window_Listener.hpp
Normal file
14
EXCLUDE/GLTSF/include/Window_Listener.hpp
Normal file
|
@ -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
|
105
EXCLUDE/GLTSF/src/App.cpp
Normal file
105
EXCLUDE/GLTSF/src/App.cpp
Normal file
|
@ -0,0 +1,105 @@
|
|||
#include "App.hpp"
|
||||
#include "TSF.hpp"
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
|
||||
#pragma comment(lib, "glu32.lib")
|
||||
|
||||
GLfloat Rotation = 0.0f;
|
||||
|
||||
App::App() : my_Done(false)
|
||||
{
|
||||
TSF::Initialize();
|
||||
}
|
||||
|
||||
App::~App()
|
||||
{
|
||||
Finalize();
|
||||
TSF::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();
|
||||
}
|
24
EXCLUDE/GLTSF/src/Main.cpp
Normal file
24
EXCLUDE/GLTSF/src/Main.cpp
Normal file
|
@ -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;
|
||||
}
|
360
EXCLUDE/GLTSF/src/TSF.cpp
Normal file
360
EXCLUDE/GLTSF/src/TSF.cpp
Normal file
|
@ -0,0 +1,360 @@
|
|||
#include "TSF.hpp"
|
||||
#include <stdexcept>
|
||||
|
||||
bool TSF::COM_Initialized = false;
|
||||
CComPtr<ITfThreadMgr> TSF::Thread_Manager;
|
||||
TfClientId TSF::Client_Id;
|
||||
TSF::TSF_Text_Store *TSF::Text_Store = NULL;
|
||||
|
||||
void TSF::Initialize()
|
||||
{
|
||||
if (!COM_Initialized)
|
||||
{
|
||||
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
if (S_OK != hr && S_FALSE != hr)
|
||||
throw std::runtime_error("Failed to initialize COM");
|
||||
|
||||
COM_Initialized = true;
|
||||
}
|
||||
if (!Thread_Manager)
|
||||
{
|
||||
if (FAILED(CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, reinterpret_cast<void **>(&Thread_Manager))))
|
||||
throw std::runtime_error("Failed to create ITfThreadMgr instance");
|
||||
|
||||
if (FAILED(Thread_Manager->Activate(&Client_Id)))
|
||||
throw std::runtime_error("ITfThreadMgr::Activate failed");
|
||||
|
||||
Text_Store = new TSF_Text_Store;
|
||||
Text_Store->Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
void TSF::Finalize()
|
||||
{
|
||||
if (Thread_Manager)
|
||||
{
|
||||
Thread_Manager->Deactivate();
|
||||
Thread_Manager = NULL;
|
||||
}
|
||||
if (COM_Initialized)
|
||||
{
|
||||
CoUninitialize();
|
||||
COM_Initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
*ppvObject = NULL;
|
||||
if (IID_IUnknown == riid || IID_ITextStoreACP == riid)
|
||||
*ppvObject = static_cast<ITextStoreACP *>(this);
|
||||
else if (IID_ITfContextOwnerCompositionSink == riid)
|
||||
*ppvObject = static_cast<ITfContextOwnerCompositionSink *>(this);
|
||||
|
||||
if (*ppvObject)
|
||||
{
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) TSF::TSF_Text_Store::AddRef()
|
||||
{
|
||||
return ++my_Reference_Count;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) TSF::TSF_Text_Store::Release()
|
||||
{
|
||||
--my_Reference_Count;
|
||||
if (0 != my_Reference_Count)
|
||||
return my_Reference_Count;
|
||||
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CHECK_CONDITION(condition, retval, function, line) \
|
||||
if (!condition) \
|
||||
{ \
|
||||
printf("%s:%d: Condition failure: %s\n", function, line, #condition); \
|
||||
}
|
||||
|
||||
#define ENSURE(condition, retval) CHECK_CONDITION(condition, retval, __FUNCTION__, __LINE__)
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::AdviseSink(REFIID riid, IUnknown *punk, DWORD dwMask)
|
||||
{
|
||||
ENSURE(punk && IID_ITextStoreACP == riid, E_INVALIDARG);
|
||||
|
||||
if (!my_Sink)
|
||||
{
|
||||
HRESULT hr = punk->QueryInterface(&my_Sink);
|
||||
ENSURE(SUCCEEDED(hr) && my_Sink, E_UNEXPECTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
CComPtr<IUnknown> Unknown_1, Unknown_2;
|
||||
punk->QueryInterface(&Unknown_1);
|
||||
my_Sink->QueryInterface(&Unknown_2);
|
||||
if (Unknown_1 != Unknown_2)
|
||||
return CONNECT_E_ADVISELIMIT;
|
||||
}
|
||||
my_Sink_Mask = dwMask;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::UnadviseSink(IUnknown *punk)
|
||||
{
|
||||
ENSURE(punk, E_INVALIDARG);
|
||||
ENSURE(my_Sink, CONNECT_E_NOCONNECTION);
|
||||
|
||||
CComPtr<IUnknown> Unknown_1, Unknown_2;
|
||||
punk->QueryInterface(&Unknown_1);
|
||||
my_Sink->QueryInterface(&Unknown_2);
|
||||
|
||||
if (Unknown_1 != Unknown_2)
|
||||
return CONNECT_E_NOCONNECTION;
|
||||
|
||||
my_Sink = NULL;
|
||||
my_Sink_Mask = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::RequestLock(DWORD dwLockFlags, HRESULT *phrSession)
|
||||
{
|
||||
ENSURE(my_Sink, E_FAIL);
|
||||
ENSURE(phrSession, E_INVALIDARG);
|
||||
if (my_Lock)
|
||||
{
|
||||
if (TS_LF_READ == (my_Lock & TS_LF_READWRITE)
|
||||
&& TS_LF_READWRITE == (dwLockFlags & TS_LF_READWRITE)
|
||||
&& !(dwLockFlags & TS_LF_SYNC))
|
||||
{
|
||||
*phrSession = TS_S_ASYNC;
|
||||
my_Lock_Queued = dwLockFlags & (~TS_LF_SYNC);
|
||||
}
|
||||
else
|
||||
{
|
||||
*phrSession = TS_E_SYNCHRONOUS;
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
my_Lock = dwLockFlags & (~TS_LF_SYNC);
|
||||
*phrSession = my_Sink->OnLockGranted(my_Lock);
|
||||
while (my_Lock_Queued)
|
||||
{
|
||||
my_Lock = my_Lock_Queued;
|
||||
my_Lock_Queued = 0;
|
||||
my_Sink->OnLockGranted(my_Lock);
|
||||
}
|
||||
my_Lock = 0;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::GetStatus(TS_STATUS *pdcs)
|
||||
{
|
||||
ENSURE(pdcs, E_INVALIDARG);
|
||||
pdcs->dwDynamicFlags = 0;
|
||||
pdcs->dwStaticFlags = TS_SS_NOHIDDENTEXT;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::QueryInsert(LONG acpTestStart, LONG acpTestEnd, ULONG cch, LONG *pacpResultStart, LONG *pacpResultEnd)
|
||||
{
|
||||
ENSURE(0 <= acpTestStart && acpTestStart <= acpTestEnd && pacpResultStart && pacpResultEnd, E_INVALIDARG);
|
||||
|
||||
*pacpResultStart = acpTestStart;
|
||||
*pacpResultEnd = acpTestStart + cch;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::GetSelection(ULONG ulIndex, ULONG ulCount, TS_SELECTION_ACP *pSelection, ULONG *pcFetched)
|
||||
{
|
||||
ENSURE(TS_LF_READ == (my_Lock && TS_LF_READ), TS_E_NOLOCK);
|
||||
ENSURE(ulCount && pSelection && pcFetched, E_INVALIDARG);
|
||||
|
||||
*pcFetched = 0;
|
||||
ENSURE(TS_DEFAULT_SELECTION == ulIndex || 0 == ulIndex, TS_E_NOSELECTION);
|
||||
if (my_Composition_View)
|
||||
{
|
||||
*pSelection = my_Composition_Selection;
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
*pcFetched = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::SetSelection(ULONG ulCount, const TS_SELECTION_ACP *pSelection)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ENSURE(TS_LF_READ == (my_Lock & TS_LF_READ), TS_E_NOLOCK);
|
||||
ENSURE(pcchPlainRet && (pchPlain || prgRunInfo)
|
||||
&& (!cchPlainReq == !pchPlain)
|
||||
&& (!cRunInfoReq == !prgRunInfo), E_INVALIDARG);
|
||||
ENSURE(0 <= acpStart && -1 <= acpEnd
|
||||
&& (-1 == acpEnd || acpStart <= acpEnd), TS_E_INVALIDPOS);
|
||||
|
||||
*pcchPlainRet = 0;
|
||||
if (pchPlain && cchPlainReq) *pchPlain = 0;
|
||||
if (pcRunInfoRet) *pcRunInfoRet = 0;
|
||||
//TODO
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::SetText(DWORD dwFlags, LONG acpStart, LONG acpEnd, const WCHAR *pchText, ULONG cch, TS_TEXTCHANGE *pChange)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::GetFormattedText(LONG acpStart, LONG acpEnd, IDataObject **ppDataObject)
|
||||
{
|
||||
//not needed
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::GetEmbedded(LONG acpPos, REFGUID rguidService, REFIID riid, IUnknown **ppunk)
|
||||
{
|
||||
//not needed
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::QueryInsertEmbedded(const GUID *pguidService, const FORMATETC *pFormatEtc, BOOL *pfInsertable)
|
||||
{
|
||||
if (!pfInsertable)
|
||||
return E_INVALIDARG;
|
||||
|
||||
//Not supported
|
||||
*pfInsertable = FALSE;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::InsertEmbedded(DWORD dwFlags, LONG acpStart, LONG acpEnd, IDataObject *pDataObject, TS_TEXTCHANGE *pChange)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::InsertTextAtSelection(DWORD dwFlags, const WCHAR *pchText, ULONG cch, LONG *pacpStart, LONG *pacpEnd, TS_TEXTCHANGE *pChange)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::InsertEmbeddedAtSelection(DWORD dwFlags, IDataObject *pDataObject, LONG *pacpStart, LONG *pacpEnd, TS_TEXTCHANGE *pChange)
|
||||
{
|
||||
//not needed
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::RequestSupportedAttrs(DWORD dwFlags, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs)
|
||||
{
|
||||
//not needed
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::RequestAttrsAtPosition(LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags)
|
||||
{
|
||||
//not needed
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::RequestAttrsTransitioningAtPosition(LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags)
|
||||
{
|
||||
//not needed
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::FindNextAttrTransition(LONG acpStart, LONG acpHalt, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags, LONG *pacpNext, BOOL *pfFound, LONG *plFoundOffset)
|
||||
{
|
||||
//not needed
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::RetrieveRequestedAttrs(ULONG ulCount, TS_ATTRVAL *paAttrVals, ULONG *pcFetched)
|
||||
{
|
||||
//not needed
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::GetEndACP(LONG *pacp)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::GetActiveView(TsViewCookie *pvcView)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::GetACPFromPoint(TsViewCookie vcView, const POINT *ptScreen, DWORD dwFlags, LONG *pacp)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::GetTextExt(TsViewCookie vcView, LONG acpStart, LONG acpEnd, RECT *prc, BOOL *pfClipped)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::GetScreenExt(TsViewCookie vcView, RECT *prc)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::GetWnd(TsViewCookie vcView, HWND *phwnd)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::OnStartComposition(ITfCompositionView *pComposition, BOOL *pfOk)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::OnUpdateComposition(ITfCompositionView *pComposition, ITfRange *pRangeNew)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP TSF::TSF_Text_Store::OnEndComposition(ITfCompositionView *pComposition)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
TSF::TSF_Text_Store::TSF_Text_Store() : my_Reference_Count(1),
|
||||
my_Edit_Cookie(0),
|
||||
my_Lock(0),
|
||||
my_Lock_Queued(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TSF::TSF_Text_Store::~TSF_Text_Store()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TSF::TSF_Text_Store::Initialize()
|
||||
{
|
||||
if (FAILED(Thread_Manager->CreateDocumentMgr(&my_Document_Manager)))
|
||||
throw std::runtime_error("Failed to create document manager");
|
||||
|
||||
if (FAILED(my_Document_Manager->CreateContext(Client_Id, 0, static_cast<ITextStoreACP *>(this), &my_Context, &my_Edit_Cookie)))
|
||||
throw std::runtime_error("Failed to create document context");
|
||||
|
||||
if (FAILED(my_Document_Manager->Push(my_Context)))
|
||||
throw std::runtime_error("Failed to push context");
|
||||
}
|
||||
|
||||
void TSF::TSF_Text_Store::Finalize()
|
||||
{
|
||||
|
||||
}
|
100
EXCLUDE/GLTSF/src/Video_Mode.cpp
Normal file
100
EXCLUDE/GLTSF/src/Video_Mode.cpp
Normal file
|
@ -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());
|
||||
}
|
||||
}
|
281
EXCLUDE/GLTSF/src/Window.cpp
Normal file
281
EXCLUDE/GLTSF/src/Window.cpp
Normal file
|
@ -0,0 +1,281 @@
|
|||
#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);
|
||||
}
|
||||
|
||||
void Window::Finalize()
|
||||
{
|
||||
Destroy_Window();
|
||||
Unregister_Class();
|
||||
}
|
||||
|
||||
void Window::Set_Listener(Window_Listener *Listener)
|
||||
{
|
||||
my_Listener = Listener;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
0
VisualC/tests/automated/automated_VS2008.vcproj
Executable file → Normal file
0
VisualC/tests/automated/automated_VS2008.vcproj
Executable file → Normal file
0
VisualC/tests/checkkeys/checkkeys_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/checkkeys/checkkeys_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/graywin/graywin_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/graywin/graywin_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/loopwave/loopwave_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/loopwave/loopwave_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testalpha/testalpha_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testalpha/testalpha_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testdraw2/testdraw2_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testdraw2/testdraw2_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testfile/testfile_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testfile/testfile_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testgamma/testgamma_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testgamma/testgamma_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testgl/testgl_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testgl/testgl_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testgl2/testgl2_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testgl2/testgl2_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testjoystick/testjoystick_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testjoystick/testjoystick_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testoverlay/testoverlay_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testoverlay/testoverlay_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testoverlay2/testoverlay2_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testoverlay2/testoverlay2_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testpalette/testpalette_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testpalette/testpalette_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testplatform/testplatform_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testplatform/testplatform_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testpower/testpower_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testpower/testpower_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testsprite/testsprite_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testsprite/testsprite_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testsprite2/testsprite2_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testsprite2/testsprite2_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testvidinfo/testvidinfo_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testvidinfo/testvidinfo_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testwin/testwin_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testwin/testwin_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testwm/testwm_VS2005.vcproj
Executable file → Normal file
0
VisualC/tests/testwm/testwm_VS2005.vcproj
Executable file → Normal file
|
@ -472,6 +472,19 @@ extern DECLSPEC size_t SDLCALL SDL_strlen(const char *string);
|
|||
extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t * string);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WCSLCPY
|
||||
#define SDL_wcslcpy wcslcpy
|
||||
#else
|
||||
extern DECLSPEC size_t SDLCALL SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WCSLCAT
|
||||
#define SDL_wcslcat wcslcat
|
||||
#else
|
||||
extern DECLSPEC size_t SDLCALL SDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_STRLCPY
|
||||
#define SDL_strlcpy strlcpy
|
||||
#else
|
||||
|
@ -479,6 +492,9 @@ extern DECLSPEC size_t SDLCALL SDL_strlcpy(char *dst, const char *src,
|
|||
size_t maxlen);
|
||||
#endif
|
||||
|
||||
extern DECLSPEC size_t SDLCALL SDL_utf8strlcpy(char *dst, const char *src,
|
||||
size_t dst_bytes);
|
||||
|
||||
#ifdef HAVE_STRLCAT
|
||||
#define SDL_strlcat strlcat
|
||||
#else
|
||||
|
|
|
@ -778,7 +778,7 @@ SDL_SendKeyboardText(const char *text)
|
|||
SDL_Event event;
|
||||
event.text.type = SDL_TEXTINPUT;
|
||||
event.text.windowID = keyboard->focus ? keyboard->focus->id : 0;
|
||||
SDL_strlcpy(event.text.text, text, SDL_arraysize(event.text.text));
|
||||
SDL_utf8strlcpy(event.text.text, text, SDL_arraysize(event.text.text));
|
||||
event.text.windowID = keyboard->focus ? keyboard->focus->id : 0;
|
||||
posted = (SDL_PushEvent(&event) > 0);
|
||||
}
|
||||
|
@ -799,7 +799,7 @@ SDL_SendEditingText(const char *text, int start, int length)
|
|||
event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0;
|
||||
event.edit.start = start;
|
||||
event.edit.length = length;
|
||||
SDL_strlcpy(event.edit.text, text, SDL_arraysize(event.edit.text));
|
||||
SDL_utf8strlcpy(event.edit.text, text, SDL_arraysize(event.edit.text));
|
||||
posted = (SDL_PushEvent(&event) > 0);
|
||||
}
|
||||
return (posted);
|
||||
|
|
|
@ -29,6 +29,21 @@
|
|||
#define SDL_isupperhex(X) (((X) >= 'A') && ((X) <= 'F'))
|
||||
#define SDL_islowerhex(X) (((X) >= 'a') && ((X) <= 'f'))
|
||||
|
||||
#define UTF8_IsLeadByte(c) ((c) >= 0xC0 && (c) <= 0xF4)
|
||||
#define UTF8_IsTrailingByte(c) ((c) >= 0x80 && (c) <= 0xBF)
|
||||
|
||||
int UTF8_TrailingBytes(unsigned char c)
|
||||
{
|
||||
if (c >= 0xC0 && c<= 0xDF)
|
||||
return 1;
|
||||
else if (c >= 0xE0 && c <= 0xEF)
|
||||
return 2;
|
||||
else if (c >= 0xF0 && c <= 0xF4)
|
||||
return 3;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(HAVE_SSCANF) || !defined(HAVE_STRTOL)
|
||||
static size_t
|
||||
SDL_ScanLong(const char *text, int radix, long *valuep)
|
||||
|
@ -348,6 +363,33 @@ SDL_wcslen(const wchar_t * string)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSLCPY
|
||||
size_t
|
||||
SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen)
|
||||
{
|
||||
size_t srclen = SDL_wcslen(src);
|
||||
if (maxlen > 0) {
|
||||
size_t len = SDL_min(srclen, maxlen - 1);
|
||||
SDL_memcpy(dst, src, len * sizeof(wchar_t));
|
||||
dst[len] = '\0';
|
||||
}
|
||||
return srclen;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WCSLCAT
|
||||
size_t
|
||||
SDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen)
|
||||
{
|
||||
size_t dstlen = SDL_wcslen(dst);
|
||||
size_t srclen = SDL_wcslen(src);
|
||||
if (dstlen < maxlen) {
|
||||
SDL_wcslcpy(dst + dstlen, src, maxlen - dstlen);
|
||||
}
|
||||
return dstlen + srclen;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
size_t
|
||||
SDL_strlcpy(char *dst, const char *src, size_t maxlen)
|
||||
|
@ -362,6 +404,38 @@ SDL_strlcpy(char *dst, const char *src, size_t maxlen)
|
|||
}
|
||||
#endif
|
||||
|
||||
size_t SDL_utf8strlcpy(char *dst, const char *src, size_t dst_bytes)
|
||||
{
|
||||
size_t src_bytes = SDL_strlen(src);
|
||||
size_t bytes = SDL_min(src_bytes, dst_bytes - 1);
|
||||
int i = 0;
|
||||
char trailing_bytes = 0;
|
||||
if (bytes)
|
||||
{
|
||||
unsigned char c = (unsigned char)src[bytes - 1];
|
||||
if (UTF8_IsLeadByte(c))
|
||||
--bytes;
|
||||
else if (UTF8_IsTrailingByte(c))
|
||||
{
|
||||
for (i = bytes - 1; i != 0; --i)
|
||||
{
|
||||
c = (unsigned char)src[i];
|
||||
trailing_bytes = UTF8_TrailingBytes(c);
|
||||
if (trailing_bytes)
|
||||
{
|
||||
if (bytes - i != trailing_bytes + 1)
|
||||
bytes = i;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SDL_memcpy(dst, src, bytes);
|
||||
}
|
||||
dst[bytes] = '\0';
|
||||
return bytes;
|
||||
}
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
size_t
|
||||
SDL_strlcat(char *dst, const char *src, size_t maxlen)
|
||||
|
|
4
src/video/win32/SDL_win32events.c
Executable file → Normal file
4
src/video/win32/SDL_win32events.c
Executable file → Normal file
|
@ -139,6 +139,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
|
||||
#endif
|
||||
if (IME_HandleMessage(hwnd, msg, wParam, &lParam, data->videodata))
|
||||
return 0;
|
||||
|
||||
switch (msg) {
|
||||
|
||||
|
@ -605,7 +607,7 @@ SDL_RegisterApp(char *name, Uint32 style, void *hInst)
|
|||
class.hbrBackground = NULL;
|
||||
class.hInstance = SDL_Instance;
|
||||
class.style = SDL_Appstyle;
|
||||
class.lpfnWndProc = DefWindowProc;
|
||||
class.lpfnWndProc = WIN_WindowProc;
|
||||
class.cbWndExtra = 0;
|
||||
class.cbClsExtra = 0;
|
||||
if (!RegisterClass(&class)) {
|
||||
|
|
|
@ -26,6 +26,14 @@
|
|||
#include "../../events/SDL_keyboard_c.h"
|
||||
#include "../../events/scancodes_win32.h"
|
||||
|
||||
#include <imm.h>
|
||||
#include <oleauto.h>
|
||||
|
||||
static void IME_Init(SDL_VideoData *videodata, HWND hwnd);
|
||||
static void IME_Enable(SDL_VideoData *videodata, HWND hwnd);
|
||||
static void IME_Disable(SDL_VideoData *videodata, HWND hwnd);
|
||||
static void IME_Quit(SDL_VideoData *videodata);
|
||||
|
||||
#ifndef MAPVK_VK_TO_VSC
|
||||
#define MAPVK_VK_TO_VSC 0
|
||||
#endif
|
||||
|
@ -81,6 +89,34 @@ WIN_InitKeyboard(_THIS)
|
|||
|
||||
data->key_layout = win32_scancode_table;
|
||||
|
||||
data->ime_com_initialized = SDL_FALSE;
|
||||
data->ime_threadmgr = 0;
|
||||
data->ime_initialized = SDL_FALSE;
|
||||
data->ime_enabled = SDL_FALSE;
|
||||
data->ime_available = SDL_FALSE;
|
||||
data->ime_hwnd_main = 0;
|
||||
data->ime_hwnd_current = 0;
|
||||
data->ime_himc = 0;
|
||||
data->ime_composition[0] = 0;
|
||||
data->ime_readingstring[0] = 0;
|
||||
data->ime_cursor = 0;
|
||||
data->ime_hkl = 0;
|
||||
data->ime_himm32 = 0;
|
||||
data->GetReadingString = 0;
|
||||
data->ShowReadingWindow = 0;
|
||||
data->ImmLockIMC = 0;
|
||||
data->ImmUnlockIMC = 0;
|
||||
data->ImmLockIMCC = 0;
|
||||
data->ImmUnlockIMCC = 0;
|
||||
data->ime_uiless = SDL_FALSE;
|
||||
data->ime_threadmgrex = 0;
|
||||
data->ime_uielemsinkcookie = TF_INVALID_COOKIE;
|
||||
data->ime_alpnsinkcookie = TF_INVALID_COOKIE;
|
||||
data->ime_openmodesinkcookie = TF_INVALID_COOKIE;
|
||||
data->ime_convmodesinkcookie = TF_INVALID_COOKIE;
|
||||
data->ime_uielemsink = 0;
|
||||
data->ime_ippasink = 0;
|
||||
|
||||
WIN_UpdateKeymap();
|
||||
|
||||
SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu");
|
||||
|
@ -119,6 +155,851 @@ WIN_UpdateKeymap()
|
|||
void
|
||||
WIN_QuitKeyboard(_THIS)
|
||||
{
|
||||
IME_Quit((SDL_VideoData *)_this->driverdata);
|
||||
}
|
||||
|
||||
void
|
||||
WIN_StartTextInput(_THIS)
|
||||
{
|
||||
SDL_Window *window = SDL_GetKeyboardFocus();
|
||||
if (window) {
|
||||
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
|
||||
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
|
||||
IME_Init(videodata, hwnd);
|
||||
IME_Enable(videodata, hwnd);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WIN_StopTextInput(_THIS)
|
||||
{
|
||||
SDL_Window *window = SDL_GetKeyboardFocus();
|
||||
if (window) {
|
||||
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
|
||||
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
|
||||
IME_Init(videodata, hwnd);
|
||||
IME_Disable(videodata, hwnd);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WIN_SetTextInputRect(_THIS, SDL_Rect *rect)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#define LANG_CHT MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)
|
||||
#define LANG_CHS MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)
|
||||
|
||||
#define MAKEIMEVERSION(major,minor) ((DWORD) (((BYTE)(major) << 24) | ((BYTE)(minor) << 16) ))
|
||||
#define IMEID_VER(id) ((id) & 0xffff0000)
|
||||
#define IMEID_LANG(id) ((id) & 0x0000ffff)
|
||||
|
||||
#define CHT_HKL_DAYI ((HKL)0xE0060404)
|
||||
#define CHT_HKL_NEW_PHONETIC ((HKL)0xE0080404)
|
||||
#define CHT_HKL_NEW_CHANG_JIE ((HKL)0xE0090404)
|
||||
#define CHT_HKL_NEW_QUICK ((HKL)0xE00A0404)
|
||||
#define CHT_HKL_HK_CANTONESE ((HKL)0xE00B0404)
|
||||
#define CHT_IMEFILENAME1 "TINTLGNT.IME"
|
||||
#define CHT_IMEFILENAME2 "CINTLGNT.IME"
|
||||
#define CHT_IMEFILENAME3 "MSTCIPHA.IME"
|
||||
#define IMEID_CHT_VER42 (LANG_CHT | MAKEIMEVERSION(4, 2))
|
||||
#define IMEID_CHT_VER43 (LANG_CHT | MAKEIMEVERSION(4, 3))
|
||||
#define IMEID_CHT_VER44 (LANG_CHT | MAKEIMEVERSION(4, 4))
|
||||
#define IMEID_CHT_VER50 (LANG_CHT | MAKEIMEVERSION(5, 0))
|
||||
#define IMEID_CHT_VER51 (LANG_CHT | MAKEIMEVERSION(5, 1))
|
||||
#define IMEID_CHT_VER52 (LANG_CHT | MAKEIMEVERSION(5, 2))
|
||||
#define IMEID_CHT_VER60 (LANG_CHT | MAKEIMEVERSION(6, 0))
|
||||
#define IMEID_CHT_VER_VISTA (LANG_CHT | MAKEIMEVERSION(7, 0))
|
||||
|
||||
#define CHS_HKL ((HKL)0xE00E0804)
|
||||
#define CHS_IMEFILENAME1 "PINTLGNT.IME"
|
||||
#define CHS_IMEFILENAME2 "MSSCIPYA.IME"
|
||||
#define IMEID_CHS_VER41 (LANG_CHS | MAKEIMEVERSION(4, 1))
|
||||
#define IMEID_CHS_VER42 (LANG_CHS | MAKEIMEVERSION(4, 2))
|
||||
#define IMEID_CHS_VER53 (LANG_CHS | MAKEIMEVERSION(5, 3))
|
||||
|
||||
#define LANG() LOWORD((videodata->ime_hkl))
|
||||
#define PRIMLANG() ((WORD)PRIMARYLANGID(LANG()))
|
||||
#define SUBLANG() SUBLANGID(LANG())
|
||||
|
||||
static void IME_UpdateInputLocale(SDL_VideoData *videodata);
|
||||
static void IME_ClearComposition(SDL_VideoData *videodata);
|
||||
static void IME_SetWindow(SDL_VideoData* videodata, HWND hwnd);
|
||||
static void IME_SetupAPI(SDL_VideoData *videodata);
|
||||
static DWORD IME_GetId(SDL_VideoData *videodata, UINT uIndex);
|
||||
static void IME_SendEditingEvent(SDL_VideoData *videodata);
|
||||
#define SDL_IsEqualIID(riid1, riid2) SDL_IsEqualGUID(riid1, riid2)
|
||||
#define SDL_IsEqualGUID(rguid1, rguid2) (!SDL_memcmp(rguid1, rguid2, sizeof(GUID)))
|
||||
|
||||
static SDL_bool UILess_SetupSinks(SDL_VideoData *videodata);
|
||||
static void UILess_ReleaseSinks(SDL_VideoData *videodata);
|
||||
static void UILess_EnableUIUpdates(SDL_VideoData *videodata);
|
||||
static void UILess_DisableUIUpdates(SDL_VideoData *videodata);
|
||||
|
||||
static void
|
||||
IME_Init(SDL_VideoData *videodata, HWND hwnd)
|
||||
{
|
||||
if (videodata->ime_initialized)
|
||||
return;
|
||||
|
||||
videodata->ime_hwnd_main = hwnd;
|
||||
if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))) {
|
||||
videodata->ime_com_initialized = SDL_TRUE;
|
||||
CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, &videodata->ime_threadmgr);
|
||||
}
|
||||
videodata->ime_initialized = SDL_TRUE;
|
||||
videodata->ime_himm32 = LoadLibraryA("imm32.dll");
|
||||
if (!videodata->ime_himm32) {
|
||||
videodata->ime_available = SDL_FALSE;
|
||||
return;
|
||||
}
|
||||
videodata->ImmLockIMC = (LPINPUTCONTEXT2 (WINAPI *)(HIMC))GetProcAddress(videodata->ime_himm32, "ImmLockIMC");
|
||||
videodata->ImmUnlockIMC = (BOOL (WINAPI *)(HIMC))GetProcAddress(videodata->ime_himm32, "ImmUnlockIMC");
|
||||
videodata->ImmLockIMCC = (LPVOID (WINAPI *)(HIMCC))GetProcAddress(videodata->ime_himm32, "ImmLockIMCC");
|
||||
videodata->ImmUnlockIMCC = (BOOL (WINAPI *)(HIMCC))GetProcAddress(videodata->ime_himm32, "ImmUnlockIMCC");
|
||||
|
||||
IME_SetWindow(videodata, hwnd);
|
||||
videodata->ime_himc = ImmGetContext(hwnd);
|
||||
ImmReleaseContext(hwnd, videodata->ime_himc);
|
||||
if (!videodata->ime_himc) {
|
||||
videodata->ime_available = SDL_FALSE;
|
||||
IME_Disable(videodata, hwnd);
|
||||
return;
|
||||
}
|
||||
videodata->ime_available = SDL_TRUE;
|
||||
IME_UpdateInputLocale(videodata);
|
||||
IME_SetupAPI(videodata);
|
||||
videodata->ime_uiless = UILess_SetupSinks(videodata);
|
||||
IME_UpdateInputLocale(videodata);
|
||||
IME_Disable(videodata, hwnd);
|
||||
}
|
||||
|
||||
static void
|
||||
IME_Enable(SDL_VideoData *videodata, HWND hwnd)
|
||||
{
|
||||
if (!videodata->ime_initialized || !videodata->ime_hwnd_current)
|
||||
return;
|
||||
|
||||
if (!videodata->ime_available) {
|
||||
IME_Disable(videodata, hwnd);
|
||||
return;
|
||||
}
|
||||
if (videodata->ime_hwnd_current == videodata->ime_hwnd_main)
|
||||
ImmAssociateContext(videodata->ime_hwnd_current, videodata->ime_himc);
|
||||
|
||||
videodata->ime_enabled = SDL_TRUE;
|
||||
IME_UpdateInputLocale(videodata);
|
||||
UILess_EnableUIUpdates(videodata);
|
||||
}
|
||||
|
||||
static void
|
||||
IME_Disable(SDL_VideoData *videodata, HWND hwnd)
|
||||
{
|
||||
if (!videodata->ime_initialized || !videodata->ime_hwnd_current)
|
||||
return;
|
||||
|
||||
IME_ClearComposition(videodata);
|
||||
if (videodata->ime_hwnd_current == videodata->ime_hwnd_main)
|
||||
ImmAssociateContext(videodata->ime_hwnd_current, NULL);
|
||||
|
||||
videodata->ime_enabled = SDL_FALSE;
|
||||
UILess_DisableUIUpdates(videodata);
|
||||
}
|
||||
|
||||
static void
|
||||
IME_Quit(SDL_VideoData *videodata)
|
||||
{
|
||||
if (!videodata->ime_initialized)
|
||||
return;
|
||||
|
||||
UILess_ReleaseSinks(videodata);
|
||||
if (videodata->ime_hwnd_main)
|
||||
ImmAssociateContext(videodata->ime_hwnd_main, videodata->ime_himc);
|
||||
|
||||
videodata->ime_hwnd_main = 0;
|
||||
videodata->ime_himc = 0;
|
||||
if (videodata->ime_himm32) {
|
||||
FreeLibrary(videodata->ime_himm32);
|
||||
videodata->ime_himm32 = 0;
|
||||
}
|
||||
if (videodata->ime_threadmgr) {
|
||||
videodata->ime_threadmgr->lpVtbl->Release(videodata->ime_threadmgr);
|
||||
videodata->ime_threadmgr = 0;
|
||||
}
|
||||
if (videodata->ime_com_initialized) {
|
||||
CoUninitialize();
|
||||
videodata->ime_com_initialized = SDL_FALSE;
|
||||
}
|
||||
videodata->ime_initialized = SDL_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd)
|
||||
{
|
||||
DWORD id = 0;
|
||||
HIMC himc = 0;
|
||||
WCHAR buffer[16];
|
||||
WCHAR *s = buffer;
|
||||
DWORD len = 0;
|
||||
DWORD err = 0;
|
||||
BOOL vertical = FALSE;
|
||||
UINT maxuilen = 0;
|
||||
static OSVERSIONINFOA osversion = {0};
|
||||
if (videodata->ime_uiless)
|
||||
return;
|
||||
|
||||
videodata->ime_readingstring[0] = 0;
|
||||
if (!osversion.dwOSVersionInfoSize) {
|
||||
osversion.dwOSVersionInfoSize = sizeof(osversion);
|
||||
GetVersionExA(&osversion);
|
||||
}
|
||||
id = IME_GetId(videodata, 0);
|
||||
if (!id)
|
||||
return;
|
||||
|
||||
himc = ImmGetContext(hwnd);
|
||||
if (!himc)
|
||||
return;
|
||||
|
||||
if (videodata->GetReadingString) {
|
||||
len = videodata->GetReadingString(himc, 0, 0, &err, &vertical, &maxuilen);
|
||||
if (len) {
|
||||
if (len > SDL_arraysize(buffer))
|
||||
len = SDL_arraysize(buffer);
|
||||
|
||||
len = videodata->GetReadingString(himc, len, s, &err, &vertical, &maxuilen);
|
||||
}
|
||||
SDL_wcslcpy(videodata->ime_readingstring, s, len);
|
||||
}
|
||||
else {
|
||||
LPINPUTCONTEXT2 lpimc = videodata->ImmLockIMC(himc);
|
||||
LPBYTE p = 0;
|
||||
s = 0;
|
||||
switch (id)
|
||||
{
|
||||
case IMEID_CHT_VER42:
|
||||
case IMEID_CHT_VER43:
|
||||
case IMEID_CHT_VER44:
|
||||
p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 24);
|
||||
if (!p)
|
||||
break;
|
||||
|
||||
len = *(DWORD *)(p + 7*4 + 32*4);
|
||||
s = (WCHAR *)(p + 56);
|
||||
break;
|
||||
case IMEID_CHT_VER51:
|
||||
case IMEID_CHT_VER52:
|
||||
case IMEID_CHS_VER53:
|
||||
p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 4);
|
||||
if (!p)
|
||||
break;
|
||||
|
||||
p = *(LPBYTE *)((LPBYTE)p + 1*4 + 5*4);
|
||||
if (!p)
|
||||
break;
|
||||
|
||||
len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2);
|
||||
s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4);
|
||||
break;
|
||||
case IMEID_CHS_VER41:
|
||||
{
|
||||
int offset = (IME_GetId(videodata, 1) >= 0x00000002) ? 8 : 7;
|
||||
p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + offset * 4);
|
||||
if (!p)
|
||||
break;
|
||||
|
||||
len = *(DWORD *)(p + 7*4 + 16*2*4);
|
||||
s = (WCHAR *)(p + 6*4 + 16*2*1);
|
||||
}
|
||||
break;
|
||||
case IMEID_CHS_VER42:
|
||||
if (osversion.dwPlatformId != VER_PLATFORM_WIN32_NT)
|
||||
break;
|
||||
|
||||
p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 1*4 + 1*4 + 6*4);
|
||||
if (!p)
|
||||
break;
|
||||
|
||||
len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2);
|
||||
s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4);
|
||||
break;
|
||||
}
|
||||
if (s)
|
||||
SDL_wcslcpy(videodata->ime_readingstring, s, len + 1);
|
||||
|
||||
videodata->ImmUnlockIMCC(lpimc->hPrivate);
|
||||
videodata->ImmUnlockIMC(himc);
|
||||
}
|
||||
ImmReleaseContext(hwnd, himc);
|
||||
IME_SendEditingEvent(videodata);
|
||||
}
|
||||
|
||||
static void
|
||||
IME_InputLangChanged(SDL_VideoData *videodata)
|
||||
{
|
||||
UINT lang = PRIMLANG();
|
||||
HWND hwndime = 0;
|
||||
IME_UpdateInputLocale(videodata);
|
||||
IME_SetupAPI(videodata);
|
||||
if (lang != PRIMLANG()) {
|
||||
IME_ClearComposition(videodata);
|
||||
}
|
||||
hwndime = ImmGetDefaultIMEWnd(videodata->ime_hwnd_current);
|
||||
if (hwndime) {
|
||||
SendMessageA(hwndime, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0);
|
||||
SendMessageA(hwndime, WM_IME_CONTROL, IMC_CLOSESTATUSWINDOW, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD
|
||||
IME_GetId(SDL_VideoData *videodata, UINT uIndex)
|
||||
{
|
||||
static HKL hklprev = 0;
|
||||
static DWORD dwRet[2] = {0};
|
||||
DWORD dwVerSize = 0;
|
||||
DWORD dwVerHandle = 0;
|
||||
LPVOID lpVerBuffer = 0;
|
||||
LPVOID lpVerData = 0;
|
||||
UINT cbVerData = 0;
|
||||
char szTemp[256];
|
||||
HKL hkl = 0;
|
||||
DWORD dwLang = 0;
|
||||
if (uIndex >= sizeof(dwRet) / sizeof(dwRet[0]))
|
||||
return 0;
|
||||
|
||||
hkl = videodata->ime_hkl;
|
||||
if (hklprev == hkl)
|
||||
return dwRet[uIndex];
|
||||
|
||||
hklprev = hkl;
|
||||
dwLang = ((DWORD)hkl & 0xffff);
|
||||
if (videodata->ime_uiless && LANG() == LANG_CHT) {
|
||||
dwRet[0] = IMEID_CHT_VER_VISTA;
|
||||
dwRet[1] = 0;
|
||||
return dwRet[0];
|
||||
}
|
||||
if (hkl != CHT_HKL_NEW_PHONETIC
|
||||
&& hkl != CHT_HKL_NEW_CHANG_JIE
|
||||
&& hkl != CHT_HKL_NEW_QUICK
|
||||
&& hkl != CHT_HKL_HK_CANTONESE
|
||||
&& hkl != CHS_HKL) {
|
||||
dwRet[0] = dwRet[1] = 0;
|
||||
return dwRet[uIndex];
|
||||
}
|
||||
if (ImmGetIMEFileNameA(hkl, szTemp, sizeof(szTemp) - 1) <= 0) {
|
||||
dwRet[0] = dwRet[1] = 0;
|
||||
return dwRet[uIndex];
|
||||
}
|
||||
if (!videodata->GetReadingString) {
|
||||
#define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
|
||||
if (CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME1, -1) != 2
|
||||
&& CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME2, -1) != 2
|
||||
&& CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME3, -1) != 2
|
||||
&& CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME1, -1) != 2
|
||||
&& CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME2, -1) != 2) {
|
||||
dwRet[0] = dwRet[1] = 0;
|
||||
return dwRet[uIndex];
|
||||
}
|
||||
#undef LCID_INVARIANT
|
||||
dwVerSize = GetFileVersionInfoSizeA(szTemp, &dwVerHandle);
|
||||
if (dwVerSize) {
|
||||
lpVerBuffer = SDL_malloc(dwVerSize);
|
||||
if (lpVerBuffer) {
|
||||
if (GetFileVersionInfoA(szTemp, dwVerHandle, dwVerSize, lpVerBuffer)) {
|
||||
if (VerQueryValueA(lpVerBuffer, "\\", &lpVerData, &cbVerData)) {
|
||||
#define pVerFixedInfo ((VS_FIXEDFILEINFO FAR*)lpVerData)
|
||||
DWORD dwVer = pVerFixedInfo->dwFileVersionMS;
|
||||
dwVer = (dwVer & 0x00ff0000) << 8 | (dwVer & 0x000000ff) << 16;
|
||||
if (videodata->GetReadingString ||
|
||||
dwLang == LANG_CHT && (
|
||||
dwVer == MAKEIMEVERSION(4, 2) ||
|
||||
dwVer == MAKEIMEVERSION(4, 3) ||
|
||||
dwVer == MAKEIMEVERSION(4, 4) ||
|
||||
dwVer == MAKEIMEVERSION(5, 0) ||
|
||||
dwVer == MAKEIMEVERSION(5, 1) ||
|
||||
dwVer == MAKEIMEVERSION(5, 2) ||
|
||||
dwVer == MAKEIMEVERSION(6, 0))
|
||||
||
|
||||
dwLang == LANG_CHS && (
|
||||
dwVer == MAKEIMEVERSION(4, 1) ||
|
||||
dwVer == MAKEIMEVERSION(4, 2) ||
|
||||
dwVer == MAKEIMEVERSION(5, 3))) {
|
||||
dwRet[0] = dwVer | dwLang;
|
||||
dwRet[1] = pVerFixedInfo->dwFileVersionLS;
|
||||
SDL_free(lpVerBuffer);
|
||||
return dwRet[0];
|
||||
}
|
||||
#undef pVerFixedInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
SDL_free(lpVerBuffer);
|
||||
}
|
||||
}
|
||||
dwRet[0] = dwRet[1] = 0;
|
||||
return dwRet[uIndex];
|
||||
}
|
||||
|
||||
static void
|
||||
IME_SetupAPI(SDL_VideoData *videodata)
|
||||
{
|
||||
char ime_file[MAX_PATH + 1];
|
||||
HMODULE hime = 0;
|
||||
HKL hkl = 0;
|
||||
videodata->GetReadingString = 0;
|
||||
videodata->ShowReadingWindow = 0;
|
||||
if (videodata->ime_uiless)
|
||||
return;
|
||||
|
||||
hkl = videodata->ime_hkl;
|
||||
if (ImmGetIMEFileNameA(hkl, ime_file, sizeof(ime_file) - 1) <= 0)
|
||||
return;
|
||||
|
||||
hime = LoadLibraryA(ime_file);
|
||||
if (!hime)
|
||||
return;
|
||||
|
||||
videodata->GetReadingString = (UINT (WINAPI *)(HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT))
|
||||
GetProcAddress(hime, "GetReadingString");
|
||||
videodata->ShowReadingWindow = (BOOL (WINAPI *)(HIMC, BOOL))
|
||||
GetProcAddress(hime, "ShowReadingWindow");
|
||||
|
||||
if (videodata->ShowReadingWindow) {
|
||||
HIMC himc = ImmGetContext(videodata->ime_hwnd_current);
|
||||
if (himc) {
|
||||
videodata->ShowReadingWindow(himc, FALSE);
|
||||
ImmReleaseContext(videodata->ime_hwnd_current, himc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
IME_SetWindow(SDL_VideoData* videodata, HWND hwnd)
|
||||
{
|
||||
videodata->ime_hwnd_current = hwnd;
|
||||
if (videodata->ime_threadmgr) {
|
||||
struct ITfDocumentMgr *document_mgr = 0;
|
||||
if (SUCCEEDED(videodata->ime_threadmgr->lpVtbl->AssociateFocus(videodata->ime_threadmgr, hwnd, NULL, &document_mgr))) {
|
||||
if (document_mgr)
|
||||
document_mgr->lpVtbl->Release(document_mgr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
IME_UpdateInputLocale(SDL_VideoData *videodata)
|
||||
{
|
||||
static HKL hklprev = 0;
|
||||
videodata->ime_hkl = GetKeyboardLayout(0);
|
||||
if (hklprev == videodata->ime_hkl)
|
||||
return;
|
||||
|
||||
hklprev = videodata->ime_hkl;
|
||||
}
|
||||
|
||||
static void
|
||||
IME_ClearComposition(SDL_VideoData *videodata)
|
||||
{
|
||||
HIMC himc = 0;
|
||||
if (!videodata->ime_initialized)
|
||||
return;
|
||||
|
||||
himc = ImmGetContext(videodata->ime_hwnd_current);
|
||||
if (!himc)
|
||||
return;
|
||||
|
||||
ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
|
||||
if (videodata->ime_uiless)
|
||||
ImmSetCompositionString(himc, SCS_SETSTR, TEXT(""), sizeof(TCHAR), TEXT(""), sizeof(TCHAR));
|
||||
|
||||
ImmNotifyIME(himc, NI_CLOSECANDIDATE, 0, 0);
|
||||
ImmReleaseContext(videodata->ime_hwnd_current, himc);
|
||||
SDL_SendEditingText("", 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
IME_ClearEditing(SDL_VideoData *videodata)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, DWORD string)
|
||||
{
|
||||
LONG length = ImmGetCompositionStringW(himc, string, videodata->ime_composition, sizeof(videodata->ime_composition));
|
||||
if (length < 0)
|
||||
length = 0;
|
||||
|
||||
length /= sizeof(videodata->ime_composition[0]);
|
||||
videodata->ime_cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0));
|
||||
if (videodata->ime_composition[videodata->ime_cursor] == 0x3000) {
|
||||
int i;
|
||||
for (i = videodata->ime_cursor + 1; i < length; ++i)
|
||||
videodata->ime_composition[i - 1] = videodata->ime_composition[i];
|
||||
|
||||
--length;
|
||||
}
|
||||
videodata->ime_composition[length] = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
IME_SendInputEvent(SDL_VideoData *videodata)
|
||||
{
|
||||
char *s = 0;
|
||||
s = WIN_StringToUTF8(videodata->ime_composition);
|
||||
SDL_SendKeyboardText(s);
|
||||
SDL_free(s);
|
||||
|
||||
videodata->ime_composition[0] = 0;
|
||||
videodata->ime_readingstring[0] = 0;
|
||||
videodata->ime_cursor = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
IME_SendEditingEvent(SDL_VideoData *videodata)
|
||||
{
|
||||
char *s = 0;
|
||||
WCHAR buffer[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
|
||||
buffer[0] = 0;
|
||||
if (videodata->ime_readingstring[0]) {
|
||||
size_t len = SDL_min(SDL_wcslen(videodata->ime_composition), (size_t)videodata->ime_cursor);
|
||||
SDL_wcslcpy(buffer, videodata->ime_composition, len + 1);
|
||||
SDL_wcslcat(buffer, videodata->ime_readingstring, sizeof(buffer));
|
||||
SDL_wcslcat(buffer, &videodata->ime_composition[len], sizeof(buffer) - len);
|
||||
}
|
||||
else {
|
||||
SDL_wcslcpy(buffer, videodata->ime_composition, sizeof(videodata->ime_composition));
|
||||
}
|
||||
s = WIN_StringToUTF8(buffer);
|
||||
SDL_SendEditingText(s, videodata->ime_cursor + SDL_wcslen(videodata->ime_readingstring), 0);
|
||||
SDL_free(s);
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata)
|
||||
{
|
||||
SDL_bool trap = SDL_FALSE;
|
||||
HIMC himc = 0;
|
||||
if (!videodata->ime_initialized || !videodata->ime_available || !videodata->ime_enabled)
|
||||
return SDL_FALSE;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INPUTLANGCHANGE:
|
||||
//IME_InputLangChanged(videodata);
|
||||
break;
|
||||
case WM_IME_SETCONTEXT:
|
||||
*lParam = 0;
|
||||
break;
|
||||
case WM_IME_STARTCOMPOSITION:
|
||||
trap = SDL_TRUE;
|
||||
break;
|
||||
case WM_IME_COMPOSITION:
|
||||
trap = SDL_TRUE;
|
||||
himc = ImmGetContext(hwnd);
|
||||
if (*lParam & GCS_RESULTSTR) {
|
||||
IME_GetCompositionString(videodata, himc, GCS_RESULTSTR);
|
||||
IME_SendInputEvent(videodata);
|
||||
}
|
||||
if (*lParam & GCS_COMPSTR) {
|
||||
if (!videodata->ime_uiless)
|
||||
videodata->ime_readingstring[0] = 0;
|
||||
|
||||
IME_GetCompositionString(videodata, himc, GCS_COMPSTR);
|
||||
IME_SendEditingEvent(videodata);
|
||||
}
|
||||
ImmReleaseContext(hwnd, himc);
|
||||
break;
|
||||
case WM_IME_ENDCOMPOSITION:
|
||||
videodata->ime_composition[0] = 0;
|
||||
videodata->ime_readingstring[0] = 0;
|
||||
videodata->ime_cursor = 0;
|
||||
SDL_SendEditingText("", 0, 0);
|
||||
break;
|
||||
case WM_IME_NOTIFY:
|
||||
switch (wParam)
|
||||
{
|
||||
case IMN_SETCONVERSIONMODE:
|
||||
case IMN_SETOPENSTATUS:
|
||||
IME_UpdateInputLocale(videodata);
|
||||
break;
|
||||
case IMN_OPENCANDIDATE:
|
||||
case IMN_CHANGECANDIDATE:
|
||||
trap = SDL_TRUE;
|
||||
break;
|
||||
case IMN_CLOSECANDIDATE:
|
||||
trap = SDL_TRUE;
|
||||
break;
|
||||
case IMN_PRIVATE:
|
||||
{
|
||||
DWORD dwId = IME_GetId(videodata, 0);
|
||||
IME_GetReadingString(videodata, hwnd);
|
||||
switch (dwId)
|
||||
{
|
||||
case IMEID_CHT_VER42:
|
||||
case IMEID_CHT_VER43:
|
||||
case IMEID_CHT_VER44:
|
||||
case IMEID_CHS_VER41:
|
||||
case IMEID_CHS_VER42:
|
||||
if (*lParam == 1 || *lParam == 2)
|
||||
trap = SDL_TRUE;
|
||||
|
||||
break;
|
||||
case IMEID_CHT_VER50:
|
||||
case IMEID_CHT_VER51:
|
||||
case IMEID_CHT_VER52:
|
||||
case IMEID_CHT_VER60:
|
||||
case IMEID_CHS_VER53:
|
||||
if (*lParam == 16
|
||||
|| *lParam == 17
|
||||
|| *lParam == 26
|
||||
|| *lParam == 27
|
||||
|| *lParam == 28)
|
||||
trap = SDL_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
trap = SDL_TRUE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return trap;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) TSFSink_AddRef(TSFSink *sink)
|
||||
{
|
||||
return ++sink->refcount;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG)TSFSink_Release(TSFSink *sink)
|
||||
{
|
||||
--sink->refcount;
|
||||
if (sink->refcount == 0)
|
||||
{
|
||||
SDL_free(sink);
|
||||
return 0;
|
||||
}
|
||||
return sink->refcount;
|
||||
}
|
||||
|
||||
STDMETHODIMP UIElementSink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv)
|
||||
{
|
||||
if (!ppv)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*ppv = 0;
|
||||
if (SDL_IsEqualIID(riid, &IID_IUnknown))
|
||||
*ppv = (IUnknown *)sink;
|
||||
else if (SDL_IsEqualIID(riid, &IID_ITfUIElementSink))
|
||||
*ppv = (ITfUIElementSink *)sink;
|
||||
|
||||
if (*ppv) {
|
||||
TSFSink_AddRef(sink);
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ITfUIElement *UILess_GetUIElement(SDL_VideoData *videodata, DWORD dwUIElementId)
|
||||
{
|
||||
ITfUIElementMgr *puiem = 0;
|
||||
ITfUIElement *pelem = 0;
|
||||
ITfThreadMgrEx *threadmgrex = videodata->ime_threadmgrex;
|
||||
|
||||
if (SUCCEEDED(threadmgrex->lpVtbl->QueryInterface(threadmgrex, &IID_ITfUIElementMgr, (LPVOID *)&puiem))) {
|
||||
puiem->lpVtbl->GetUIElement(puiem, dwUIElementId, &pelem);
|
||||
puiem->lpVtbl->Release(puiem);
|
||||
}
|
||||
return pelem;
|
||||
}
|
||||
|
||||
STDMETHODIMP UIElementSink_BeginUIElement(TSFSink *sink, DWORD dwUIElementId, BOOL *pbShow)
|
||||
{
|
||||
ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
|
||||
ITfReadingInformationUIElement *preading = 0;
|
||||
SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
|
||||
if (!element)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*pbShow = FALSE;
|
||||
if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
|
||||
BSTR bstr;
|
||||
if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) {
|
||||
WCHAR *s = (WCHAR *)bstr;
|
||||
SysFreeString(bstr);
|
||||
}
|
||||
preading->lpVtbl->Release(preading);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP UIElementSink_UpdateUIElement(TSFSink *sink, DWORD dwUIElementId)
|
||||
{
|
||||
ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
|
||||
ITfReadingInformationUIElement *preading = 0;
|
||||
SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
|
||||
if (!element)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
|
||||
BSTR bstr;
|
||||
if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) {
|
||||
WCHAR *s = (WCHAR *)bstr;
|
||||
SDL_wcslcpy(videodata->ime_readingstring, s, sizeof(videodata->ime_readingstring));
|
||||
IME_SendEditingEvent(videodata);
|
||||
SysFreeString(bstr);
|
||||
}
|
||||
preading->lpVtbl->Release(preading);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP UIElementSink_EndUIElement(TSFSink *sink, DWORD dwUIElementId)
|
||||
{
|
||||
ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
|
||||
ITfReadingInformationUIElement *preading = 0;
|
||||
SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
|
||||
if (!element)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
|
||||
videodata->ime_readingstring[0] = 0;
|
||||
IME_SendEditingEvent(videodata);
|
||||
preading->lpVtbl->Release(preading);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP IPPASink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv)
|
||||
{
|
||||
if (!ppv)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*ppv = 0;
|
||||
if (SDL_IsEqualIID(riid, &IID_IUnknown))
|
||||
*ppv = (IUnknown *)sink;
|
||||
else if (SDL_IsEqualIID(riid, &IID_ITfInputProcessorProfileActivationSink))
|
||||
*ppv = (ITfInputProcessorProfileActivationSink *)sink;
|
||||
|
||||
if (*ppv) {
|
||||
TSFSink_AddRef(sink);
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
STDMETHODIMP IPPASink_OnActivated(TSFSink *sink, DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, REFGUID guidProfile, HKL hkl, DWORD dwFlags)
|
||||
{
|
||||
if (SDL_IsEqualIID(catid, &GUID_TFCAT_TIP_KEYBOARD) && (dwFlags & TF_IPSINK_FLAG_ACTIVE))
|
||||
IME_InputLangChanged((SDL_VideoData *)sink->data);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void *vtUIElementSink[] = {
|
||||
(void *)(UIElementSink_QueryInterface),
|
||||
(void *)(TSFSink_AddRef),
|
||||
(void *)(TSFSink_Release),
|
||||
(void *)(UIElementSink_BeginUIElement),
|
||||
(void *)(UIElementSink_UpdateUIElement),
|
||||
(void *)(UIElementSink_EndUIElement)
|
||||
};
|
||||
|
||||
static void *vtIPPASink[] = {
|
||||
(void *)(IPPASink_QueryInterface),
|
||||
(void *)(TSFSink_AddRef),
|
||||
(void *)(TSFSink_Release),
|
||||
(void *)(IPPASink_OnActivated)
|
||||
};
|
||||
|
||||
static void
|
||||
UILess_EnableUIUpdates(SDL_VideoData *videodata)
|
||||
{
|
||||
ITfSource *source = 0;
|
||||
if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie != TF_INVALID_COOKIE)
|
||||
return;
|
||||
|
||||
if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
|
||||
source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie);
|
||||
source->lpVtbl->Release(source);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
UILess_DisableUIUpdates(SDL_VideoData *videodata)
|
||||
{
|
||||
ITfSource *source = 0;
|
||||
if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie == TF_INVALID_COOKIE)
|
||||
return;
|
||||
|
||||
if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
|
||||
source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie);
|
||||
videodata->ime_uielemsinkcookie = TF_INVALID_COOKIE;
|
||||
source->lpVtbl->Release(source);
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
UILess_SetupSinks(SDL_VideoData *videodata)
|
||||
{
|
||||
TfClientId clientid = 0;
|
||||
SDL_bool result = SDL_FALSE;
|
||||
ITfSource *source = 0;
|
||||
if (FAILED(CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgrEx, &videodata->ime_threadmgrex)))
|
||||
return SDL_FALSE;
|
||||
|
||||
if (FAILED(videodata->ime_threadmgrex->lpVtbl->ActivateEx(videodata->ime_threadmgrex, &clientid, TF_TMAE_UIELEMENTENABLEDONLY)))
|
||||
return SDL_FALSE;
|
||||
|
||||
videodata->ime_uielemsink = SDL_malloc(sizeof(TSFSink));
|
||||
videodata->ime_ippasink = SDL_malloc(sizeof(TSFSink));
|
||||
|
||||
videodata->ime_uielemsink->lpVtbl = vtUIElementSink;
|
||||
videodata->ime_uielemsink->refcount = 1;
|
||||
videodata->ime_uielemsink->data = videodata;
|
||||
|
||||
videodata->ime_ippasink->lpVtbl = vtIPPASink;
|
||||
videodata->ime_ippasink->refcount = 1;
|
||||
videodata->ime_ippasink->data = videodata;
|
||||
|
||||
if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
|
||||
if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie))) {
|
||||
if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfInputProcessorProfileActivationSink, (IUnknown *)videodata->ime_ippasink, &videodata->ime_alpnsinkcookie))) {
|
||||
result = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
source->lpVtbl->Release(source);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#define SAFE_RELEASE(p) \
|
||||
{ \
|
||||
if (p) { \
|
||||
(p)->lpVtbl->Release((p)); \
|
||||
(p) = 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
static void
|
||||
UILess_ReleaseSinks(SDL_VideoData *videodata)
|
||||
{
|
||||
ITfSource *source = 0;
|
||||
if (videodata->ime_threadmgrex && SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, &source))) {
|
||||
source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie);
|
||||
source->lpVtbl->UnadviseSink(source, videodata->ime_alpnsinkcookie);
|
||||
SAFE_RELEASE(source);
|
||||
videodata->ime_threadmgrex->lpVtbl->Deactivate(videodata->ime_threadmgrex);
|
||||
SAFE_RELEASE(videodata->ime_threadmgrex);
|
||||
TSFSink_Release(videodata->ime_uielemsink);
|
||||
videodata->ime_uielemsink = 0;
|
||||
TSFSink_Release(videodata->ime_ippasink);
|
||||
videodata->ime_ippasink = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -31,6 +31,12 @@ extern void WIN_InitKeyboard(_THIS);
|
|||
extern void WIN_UpdateKeymap(void);
|
||||
extern void WIN_QuitKeyboard(_THIS);
|
||||
|
||||
extern void WIN_StartTextInput(_THIS);
|
||||
extern void WIN_StopTextInput(_THIS);
|
||||
extern void WIN_SetTextInputRect(_THIS, SDL_Rect *rect);
|
||||
|
||||
extern SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata);
|
||||
|
||||
#endif /* _SDL_win32keyboard_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -191,6 +191,9 @@ WIN_CreateDevice(int devindex)
|
|||
device->GL_SwapWindow = WIN_GL_SwapWindow;
|
||||
device->GL_DeleteContext = WIN_GL_DeleteContext;
|
||||
#endif
|
||||
device->StartTextInput = WIN_StartTextInput;
|
||||
device->StopTextInput = WIN_StopTextInput;
|
||||
device->SetTextInputRect = WIN_SetTextInputRect;
|
||||
|
||||
device->SetClipboardText = WIN_SetClipboardText;
|
||||
device->GetClipboardText = WIN_GetClipboardText;
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
|
||||
#include <windows.h>
|
||||
|
||||
#include <msctf.h>
|
||||
|
||||
#if SDL_VIDEO_RENDER_D3D
|
||||
//#include <d3d9.h>
|
||||
#define D3D_DEBUG_INFO
|
||||
|
@ -62,6 +64,7 @@
|
|||
#include "SDL_win32mouse.h"
|
||||
#include "SDL_win32opengl.h"
|
||||
#include "SDL_win32window.h"
|
||||
#include "SDL_events.h"
|
||||
|
||||
#ifdef UNICODE
|
||||
#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "UCS-2", (char *)S, (SDL_wcslen(S)+1)*sizeof(WCHAR))
|
||||
|
@ -77,6 +80,37 @@ enum { RENDER_NONE, RENDER_D3D, RENDER_DDRAW, RENDER_GDI, RENDER_GAPI, RENDER_RA
|
|||
typedef BOOL (*PFNSHFullScreen)(HWND, DWORD);
|
||||
typedef void (*PFCoordTransform)(SDL_Window*, POINT*);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void **lpVtbl;
|
||||
int refcount;
|
||||
void *data;
|
||||
} TSFSink;
|
||||
|
||||
// Definition from Win98DDK version of IMM.H
|
||||
typedef struct tagINPUTCONTEXT2 {
|
||||
HWND hWnd;
|
||||
BOOL fOpen;
|
||||
POINT ptStatusWndPos;
|
||||
POINT ptSoftKbdPos;
|
||||
DWORD fdwConversion;
|
||||
DWORD fdwSentence;
|
||||
union {
|
||||
LOGFONTA A;
|
||||
LOGFONTW W;
|
||||
} lfFont;
|
||||
COMPOSITIONFORM cfCompForm;
|
||||
CANDIDATEFORM cfCandForm[4];
|
||||
HIMCC hCompStr;
|
||||
HIMCC hCandInfo;
|
||||
HIMCC hGuideLine;
|
||||
HIMCC hPrivate;
|
||||
DWORD dwNumMsgBuf;
|
||||
HIMCC hMsgBuf;
|
||||
DWORD fdwInit;
|
||||
DWORD dwReserve[3];
|
||||
} INPUTCONTEXT2, *PINPUTCONTEXT2, NEAR *NPINPUTCONTEXT2, FAR *LPINPUTCONTEXT2;
|
||||
|
||||
/* Private display data */
|
||||
|
||||
typedef struct SDL_VideoData
|
||||
|
@ -97,9 +131,39 @@ typedef struct SDL_VideoData
|
|||
PFCoordTransform CoordTransform;
|
||||
#endif
|
||||
|
||||
const SDL_scancode *key_layout;
|
||||
DWORD clipboard_count;
|
||||
|
||||
const SDL_scancode *key_layout;
|
||||
SDL_bool ime_com_initialized;
|
||||
struct ITfThreadMgr *ime_threadmgr;
|
||||
SDL_bool ime_initialized;
|
||||
SDL_bool ime_enabled;
|
||||
SDL_bool ime_available;
|
||||
HWND ime_hwnd_main;
|
||||
HWND ime_hwnd_current;
|
||||
HIMC ime_himc;
|
||||
|
||||
WCHAR ime_composition[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
|
||||
WCHAR ime_readingstring[16];
|
||||
int ime_cursor;
|
||||
|
||||
HKL ime_hkl;
|
||||
HMODULE ime_himm32;
|
||||
UINT (WINAPI *GetReadingString)(HIMC himc, UINT uReadingBufLen, LPWSTR lpwReadingBuf, PINT pnErrorIndex, BOOL *pfIsVertical, PUINT puMaxReadingLen);
|
||||
BOOL (WINAPI *ShowReadingWindow)(HIMC himc, BOOL bShow);
|
||||
LPINPUTCONTEXT2 (WINAPI *ImmLockIMC)(HIMC himc);
|
||||
BOOL (WINAPI *ImmUnlockIMC)(HIMC himc);
|
||||
LPVOID (WINAPI *ImmLockIMCC)(HIMCC himcc);
|
||||
BOOL (WINAPI *ImmUnlockIMCC)(HIMCC himcc);
|
||||
|
||||
SDL_bool ime_uiless;
|
||||
struct ITfThreadMgrEx *ime_threadmgrex;
|
||||
DWORD ime_uielemsinkcookie;
|
||||
DWORD ime_alpnsinkcookie;
|
||||
DWORD ime_openmodesinkcookie;
|
||||
DWORD ime_convmodesinkcookie;
|
||||
TSFSink *ime_uielemsink;
|
||||
TSFSink *ime_ippasink;
|
||||
} SDL_VideoData;
|
||||
|
||||
#endif /* _SDL_win32video_h */
|
||||
|
|
|
@ -77,10 +77,12 @@ SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created)
|
|||
|
||||
/* Set up the window proc function */
|
||||
data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
|
||||
if (data->wndproc == DefWindowProc) {
|
||||
if (data->wndproc == WIN_WindowProc) {
|
||||
data->wndproc = NULL;
|
||||
}
|
||||
else {
|
||||
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc);
|
||||
}
|
||||
|
||||
/* Fill in the SDL window with the window data */
|
||||
{
|
||||
|
|
|
@ -25,7 +25,49 @@ TTF_Font *font;
|
|||
SDL_Rect textRect, markedRect;
|
||||
Uint32 lineColor, backColor;
|
||||
SDL_Color textColor = { 0, 0, 0 };
|
||||
char text[MAX_TEXT_LENGTH], *markedText;
|
||||
char text[MAX_TEXT_LENGTH], markedText[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
|
||||
int cursor = 0;
|
||||
|
||||
size_t utf8_length(unsigned char c)
|
||||
{
|
||||
c = (unsigned char)(0xff & c);
|
||||
if (c < 0x80)
|
||||
return 1;
|
||||
else if ((c >> 5) ==0x6)
|
||||
return 2;
|
||||
else if ((c >> 4) == 0xe)
|
||||
return 3;
|
||||
else if ((c >> 3) == 0x1e)
|
||||
return 4;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *utf8_next(char *p)
|
||||
{
|
||||
size_t len = utf8_length(*p);
|
||||
size_t i = 0;
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
for (; i < len; ++i)
|
||||
{
|
||||
++p;
|
||||
if (!*p)
|
||||
return 0;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
char *utf8_advance(char *p, size_t distance)
|
||||
{
|
||||
size_t i = 0;
|
||||
for (; i < distance && p; ++i)
|
||||
{
|
||||
p = utf8_next(p);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void usage()
|
||||
{
|
||||
|
@ -124,7 +166,7 @@ void InitInput()
|
|||
|
||||
text[0] = 0;
|
||||
markedRect = textRect;
|
||||
markedText = NULL;
|
||||
markedText[0] = 0;
|
||||
|
||||
SDL_StartTextInput();
|
||||
}
|
||||
|
@ -180,9 +222,22 @@ void Redraw()
|
|||
cursorRect.h = h;
|
||||
|
||||
SDL_FillRect(screen, &markedRect, backColor);
|
||||
if (markedText)
|
||||
if (markedText[0])
|
||||
{
|
||||
#ifdef HAVE_SDL_TTF
|
||||
if (cursor)
|
||||
{
|
||||
char *p = utf8_advance(markedText, cursor);
|
||||
char c = 0;
|
||||
if (!p)
|
||||
p = &markedText[strlen(markedText)];
|
||||
|
||||
c = *p;
|
||||
*p = 0;
|
||||
TTF_SizeUTF8(font, markedText, &w, 0);
|
||||
cursorRect.x += w;
|
||||
*p = c;
|
||||
}
|
||||
RenderText(screen, font, markedText, markedRect.x, markedRect.y, textColor);
|
||||
TTF_SizeUTF8(font, markedText, &w, &h);
|
||||
#endif
|
||||
|
@ -192,8 +247,6 @@ void Redraw()
|
|||
underlineRect.h = 2;
|
||||
underlineRect.w = w;
|
||||
|
||||
cursorRect.x += w + 1;
|
||||
|
||||
SDL_FillRect(screen, &underlineRect, lineColor);
|
||||
}
|
||||
|
||||
|
@ -295,13 +348,13 @@ int main(int argc, char *argv[])
|
|||
fprintf(stderr, "Keyboard: text input \"%s\"\n", event.text.text);
|
||||
|
||||
if (SDL_strlen(text) + SDL_strlen(event.text.text) < sizeof(text))
|
||||
SDL_strlcpy(text + SDL_strlen(text), event.text.text, sizeof(text));
|
||||
SDL_strlcat(text, event.text.text, sizeof(text));
|
||||
|
||||
fprintf(stderr, "text inputed: %s\n", text);
|
||||
|
||||
// After text inputed, we can clear up markedText because it
|
||||
// is committed
|
||||
markedText = NULL;
|
||||
markedText[0] = 0;
|
||||
Redraw();
|
||||
break;
|
||||
|
||||
|
@ -309,7 +362,8 @@ int main(int argc, char *argv[])
|
|||
fprintf(stderr, "text editing \"%s\", selected range (%d, %d)\n",
|
||||
event.edit.text, event.edit.start, event.edit.length);
|
||||
|
||||
markedText = event.edit.text;
|
||||
strcpy(markedText, event.edit.text);
|
||||
cursor = event.edit.start;
|
||||
Redraw();
|
||||
break;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue