From 249f46e706f1d8470486434cefa5eae4a56cae12 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Tue, 25 May 2010 18:53:09 -0400 Subject: [PATCH 01/30] Adding GLTSF (somewhat based on SFML, no actual TSF code yet) --- EXCLUDE/GLTSF/GLTSF.sln | 20 ++ EXCLUDE/GLTSF/GLTSF.vcxproj | 97 ++++++++ EXCLUDE/GLTSF/GLTSF.vcxproj.filters | 45 ++++ EXCLUDE/GLTSF/include/App.hpp | 26 +++ EXCLUDE/GLTSF/include/Video_Mode.hpp | 30 +++ EXCLUDE/GLTSF/include/Window.hpp | 55 +++++ EXCLUDE/GLTSF/include/Window_Listener.hpp | 13 ++ EXCLUDE/GLTSF/src/App.cpp | 56 +++++ EXCLUDE/GLTSF/src/Main.cpp | 17 ++ EXCLUDE/GLTSF/src/Video_Mode.cpp | 100 ++++++++ EXCLUDE/GLTSF/src/Window.cpp | 263 ++++++++++++++++++++++ 11 files changed, 722 insertions(+) create mode 100644 EXCLUDE/GLTSF/GLTSF.sln create mode 100644 EXCLUDE/GLTSF/GLTSF.vcxproj create mode 100644 EXCLUDE/GLTSF/GLTSF.vcxproj.filters create mode 100644 EXCLUDE/GLTSF/include/App.hpp create mode 100644 EXCLUDE/GLTSF/include/Video_Mode.hpp create mode 100644 EXCLUDE/GLTSF/include/Window.hpp create mode 100644 EXCLUDE/GLTSF/include/Window_Listener.hpp create mode 100644 EXCLUDE/GLTSF/src/App.cpp create mode 100644 EXCLUDE/GLTSF/src/Main.cpp create mode 100644 EXCLUDE/GLTSF/src/Video_Mode.cpp create mode 100644 EXCLUDE/GLTSF/src/Window.cpp diff --git a/EXCLUDE/GLTSF/GLTSF.sln b/EXCLUDE/GLTSF/GLTSF.sln new file mode 100644 index 000000000..f69c11422 --- /dev/null +++ b/EXCLUDE/GLTSF/GLTSF.sln @@ -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 diff --git a/EXCLUDE/GLTSF/GLTSF.vcxproj b/EXCLUDE/GLTSF/GLTSF.vcxproj new file mode 100644 index 000000000..374e16c12 --- /dev/null +++ b/EXCLUDE/GLTSF/GLTSF.vcxproj @@ -0,0 +1,97 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {790D58BA-E5F6-4286-A9C6-0DC28779789D} + Win32Proj + GLTSF + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + true + $(SolutionDir)bin\ + obj\$(Configuration)\ + + + false + $(SolutionDir)bin\ + obj\$(Configuration)\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + include;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/EXCLUDE/GLTSF/GLTSF.vcxproj.filters b/EXCLUDE/GLTSF/GLTSF.vcxproj.filters new file mode 100644 index 000000000..04c10f6df --- /dev/null +++ b/EXCLUDE/GLTSF/GLTSF.vcxproj.filters @@ -0,0 +1,45 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/EXCLUDE/GLTSF/include/App.hpp b/EXCLUDE/GLTSF/include/App.hpp new file mode 100644 index 000000000..658f73b81 --- /dev/null +++ b/EXCLUDE/GLTSF/include/App.hpp @@ -0,0 +1,26 @@ +#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); + +private: + Window my_Window; + bool my_Done; +}; + +#endif diff --git a/EXCLUDE/GLTSF/include/Video_Mode.hpp b/EXCLUDE/GLTSF/include/Video_Mode.hpp new file mode 100644 index 000000000..00a801400 --- /dev/null +++ b/EXCLUDE/GLTSF/include/Video_Mode.hpp @@ -0,0 +1,30 @@ +#ifndef VIDEO_MODE_HPP +#define VIDEO_MODE_HPP + +#include + +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 diff --git a/EXCLUDE/GLTSF/include/Window.hpp b/EXCLUDE/GLTSF/include/Window.hpp new file mode 100644 index 000000000..f07fd477a --- /dev/null +++ b/EXCLUDE/GLTSF/include/Window.hpp @@ -0,0 +1,55 @@ +#ifndef WINDOW_HPP +#define WINDOW_HPP + +#include + +#define WIN32_LEAN_AND_MEAN +#include + +#include "Video_Mode.hpp" +#include "Window_Listener.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 Update(); + void Display(); + +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 diff --git a/EXCLUDE/GLTSF/include/Window_Listener.hpp b/EXCLUDE/GLTSF/include/Window_Listener.hpp new file mode 100644 index 000000000..52396f7e8 --- /dev/null +++ b/EXCLUDE/GLTSF/include/Window_Listener.hpp @@ -0,0 +1,13 @@ +#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){} +}; + +#endif diff --git a/EXCLUDE/GLTSF/src/App.cpp b/EXCLUDE/GLTSF/src/App.cpp new file mode 100644 index 000000000..ae8ca73a5 --- /dev/null +++ b/EXCLUDE/GLTSF/src/App.cpp @@ -0,0 +1,56 @@ +#include "App.hpp" + +App::App() : my_Done(false) +{ + +} + +App::~App() +{ + Finalize(); +} + +void App::Initialize() +{ + Finalize(); + + my_Window.Initialize(L"GLTSF", Video_Mode(800, 600, 32), false); + my_Window.Set_Listener(this); + my_Window.Show(); +} + +void App::Finalize() +{ + my_Window.Finalize(); +} + +void App::Run() +{ + Initialize(); + while (!my_Done) + { + my_Window.Update(); + 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) +{ + +} diff --git a/EXCLUDE/GLTSF/src/Main.cpp b/EXCLUDE/GLTSF/src/Main.cpp new file mode 100644 index 000000000..31febadbf --- /dev/null +++ b/EXCLUDE/GLTSF/src/Main.cpp @@ -0,0 +1,17 @@ +#include "App.hpp" +#include + +int main(int argc, char *argv[]) +{ + try + { + App theApp; + theApp.Run(); + } + catch (const std::exception& e) + { + printf("Error: %s\n", e.what()); + return 1; + } + return 0; +} diff --git a/EXCLUDE/GLTSF/src/Video_Mode.cpp b/EXCLUDE/GLTSF/src/Video_Mode.cpp new file mode 100644 index 000000000..177e8b956 --- /dev/null +++ b/EXCLUDE/GLTSF/src/Video_Mode.cpp @@ -0,0 +1,100 @@ +#include "Video_Mode.hpp" +#include +#include +#define WIN32_LEAN_AND_MEAN +#include + +namespace +{ + + typedef std::vector 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()); + } +} diff --git a/EXCLUDE/GLTSF/src/Window.cpp b/EXCLUDE/GLTSF/src/Window.cpp new file mode 100644 index 000000000..955693c05 --- /dev/null +++ b/EXCLUDE/GLTSF/src/Window.cpp @@ -0,0 +1,263 @@ +#include "Window.hpp" + +#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(); +} + +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_OVERLAPPEDWINDOW; + 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(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(reinterpret_cast(lParam)->lpCreateParams); + SetWindowLongPtr(Handle, GWLP_USERDATA, This); + return 0; + } + break; + case WM_DESTROY: + PostQuitMessage(0); + return 0; + break; + default: + { + Window* Win = reinterpret_cast(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_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; + 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::Update() +{ + 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); +} From 301e0597a3b0e1bf3f94e4aa39ce9b7891f8dd54 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Thu, 27 May 2010 20:47:52 -0400 Subject: [PATCH 02/30] Adding some initial TSF code --- EXCLUDE/GLTSF/GLTSF.vcxproj | 2 ++ EXCLUDE/GLTSF/GLTSF.vcxproj.filters | 6 ++++ EXCLUDE/GLTSF/include/TSF.hpp | 44 +++++++++++++++++++++++++++++ EXCLUDE/GLTSF/src/TSF.cpp | 1 + 4 files changed, 53 insertions(+) create mode 100644 EXCLUDE/GLTSF/include/TSF.hpp create mode 100644 EXCLUDE/GLTSF/src/TSF.cpp diff --git a/EXCLUDE/GLTSF/GLTSF.vcxproj b/EXCLUDE/GLTSF/GLTSF.vcxproj index 374e16c12..bc2928c22 100644 --- a/EXCLUDE/GLTSF/GLTSF.vcxproj +++ b/EXCLUDE/GLTSF/GLTSF.vcxproj @@ -81,6 +81,7 @@ + @@ -88,6 +89,7 @@ + diff --git a/EXCLUDE/GLTSF/GLTSF.vcxproj.filters b/EXCLUDE/GLTSF/GLTSF.vcxproj.filters index 04c10f6df..acab9f8e0 100644 --- a/EXCLUDE/GLTSF/GLTSF.vcxproj.filters +++ b/EXCLUDE/GLTSF/GLTSF.vcxproj.filters @@ -27,6 +27,9 @@ Header Files + + Header Files + @@ -41,5 +44,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/EXCLUDE/GLTSF/include/TSF.hpp b/EXCLUDE/GLTSF/include/TSF.hpp new file mode 100644 index 000000000..5453b9acd --- /dev/null +++ b/EXCLUDE/GLTSF/include/TSF.hpp @@ -0,0 +1,44 @@ +#ifndef TSF_HPP +#define TSF_HPP + +#include + +class TSF +{ +public: + +protected: + class UI_Sink : public ITfUIElementSink, public ITfInputProcessorProfileActivationSink + { + public: + UI_Sink(); + ~UI_Sink(); + + // IUnknown + STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj); + STDMETHODIMP_(ULONG) AddRef(void); + STDMETHODIMP_(ULONG) Release(void); + + // ITfUIElementSink + STDMETHODIMP BeginUIElement(DWORD dwUIElementId, BOOL *pbShow); + STDMETHODIMP UpdateUIElement(DWORD dwUIElementId); + STDMETHODIMP EndUIElement(DWORD dwUIElementId); + + // ITfInputProcessorProfileActivationSink + STDMETHODIMP OnActivated(DWORD dwProfileType, LANGID langid, + REFCLSID clsid, REFGUID catid, + REFGUID guidProfile, HKL hkl, + DWORD dwFlags); + + // ITfCompartmentEventSink + STDMETHODIMP OnChange(REFGUID rguid); + + private: + LONG my_Reference_Count; + }; + +private: + +}; + +#endif diff --git a/EXCLUDE/GLTSF/src/TSF.cpp b/EXCLUDE/GLTSF/src/TSF.cpp new file mode 100644 index 000000000..f21d968cd --- /dev/null +++ b/EXCLUDE/GLTSF/src/TSF.cpp @@ -0,0 +1 @@ +#include "TSF.hpp" From a1f1bc895265423d737c6bbe830f26b8c3635fed Mon Sep 17 00:00:00 2001 From: dewyatt Date: Sun, 30 May 2010 15:48:16 -0400 Subject: [PATCH 03/30] Implementing base parts of TSF --- EXCLUDE/GLTSF/include/TSF.hpp | 15 +++- EXCLUDE/GLTSF/src/TSF.cpp | 139 ++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 1 deletion(-) diff --git a/EXCLUDE/GLTSF/include/TSF.hpp b/EXCLUDE/GLTSF/include/TSF.hpp index 5453b9acd..c37f4a4be 100644 --- a/EXCLUDE/GLTSF/include/TSF.hpp +++ b/EXCLUDE/GLTSF/include/TSF.hpp @@ -2,6 +2,7 @@ #define TSF_HPP #include +#include class TSF { @@ -37,8 +38,20 @@ protected: LONG my_Reference_Count; }; -private: + TSF(); + ~TSF(); + void Initialize(); + void Finalize(); + +private: + bool my_COM_Initialized; + + CComPtr my_Thread_Manager; + UI_Sink *my_UI_Sink; + + DWORD my_UI_Element_Sink_Cookie; + DWORD my_IPPA_Sink_Cookie; }; #endif diff --git a/EXCLUDE/GLTSF/src/TSF.cpp b/EXCLUDE/GLTSF/src/TSF.cpp index f21d968cd..2f2df17c5 100644 --- a/EXCLUDE/GLTSF/src/TSF.cpp +++ b/EXCLUDE/GLTSF/src/TSF.cpp @@ -1 +1,140 @@ #include "TSF.hpp" +#include + +TSF::TSF() : my_COM_Initialized(false), + my_UI_Sink(0), + my_UI_Element_Sink_Cookie(TF_INVALID_COOKIE), + my_IPPA_Sink_Cookie(TF_INVALID_COOKIE) +{ + +} + +TSF::~TSF() +{ + Finalize(); +} + +void TSF::Initialize() +{ + Finalize(); + + if (S_OK != CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)) + throw std::runtime_error("Failed to initialize COM"); + + my_COM_Initialized = true; + if (S_OK != CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, __uuidof(ITfThreadMgrEx), (void **)&my_Thread_Manager)) + throw std::runtime_error("Failed to create ITfThreadMgrEx instance"); + + TfClientId Client_Id = 0; + if (FAILED(my_Thread_Manager->ActivateEx(&Client_Id, TF_TMAE_UIELEMENTENABLEDONLY))) + throw std::runtime_error("ITfThreadMgrEx::ActivateEx failed"); + + my_UI_Sink = new UI_Sink(); + ITfSource *Source = NULL; + if (FAILED(my_Thread_Manager->QueryInterface(__uuidof(ITfSource), (void **)&Source))) + throw std::runtime_error("QueryInterface failed"); + + if (FAILED(Source->AdviseSink(__uuidof(ITfUIElementSink), (ITfUIElementSink *)my_UI_Sink, &my_UI_Element_Sink_Cookie))) + throw std::runtime_error("AdviseSink failed"); + + if (FAILED(Source->AdviseSink(__uuidof(ITfInputProcessorProfileActivationSink), (ITfInputProcessorProfileActivationSink *)my_UI_Sink, &my_IPPA_Sink_Cookie))) + throw std::runtime_error("AdviseSink failed"); +} + +void TSF::Finalize() +{ + if (my_UI_Sink) + { + ITfSource *Source = NULL; + if (SUCCEEDED(my_Thread_Manager->QueryInterface(__uuidof(ITfSource), (void **)&Source))) + { + Source->UnadviseSink(my_IPPA_Sink_Cookie); + Source->UnadviseSink(my_UI_Element_Sink_Cookie); + Source->Release(); + } + if (my_Thread_Manager) + my_Thread_Manager->Deactivate(); + + my_UI_Sink->Release(); + delete my_UI_Sink; + my_UI_Sink = NULL; + } + my_Thread_Manager = NULL; + if (my_COM_Initialized) + { + CoUninitialize(); + my_COM_Initialized = false; + } +} + +TSF::UI_Sink::UI_Sink() +{ + my_Reference_Count = 1; +} + +TSF::UI_Sink::~UI_Sink() +{ + +} + +STDMETHODIMP TSF::UI_Sink::QueryInterface(REFIID riid, void **ppvObj) +{ + if (NULL == ppvObj) + return E_INVALIDARG; + + *ppvObj = NULL; + if (IsEqualIID(riid, IID_IUnknown)) + *ppvObj = reinterpret_cast(this); + else if (IsEqualIID(riid, __uuidof(ITfUIElementSink))) + *ppvObj = reinterpret_cast(this); + else if (IsEqualIID(riid, __uuidof(ITfInputProcessorProfileActivationSink))) + *ppvObj = reinterpret_cast(this); + else if (IsEqualIID(riid, __uuidof(ITfCompartmentEventSink))) + *ppvObj = reinterpret_cast(this); + + if (*ppvObj) + { + AddRef(); + return S_OK; + } + return E_NOINTERFACE; +} + +ULONG TSF::UI_Sink::AddRef(void) +{ + return ++my_Reference_Count; +} + +ULONG TSF::UI_Sink::Release(void) +{ + LONG Count = --my_Reference_Count; + if (0 == Count) + delete this; + + return Count; +} + +STDMETHODIMP TSF::UI_Sink::BeginUIElement(DWORD dwUIElementId, BOOL *pbShow) +{ + return S_OK; +} + +STDMETHODIMP TSF::UI_Sink::UpdateUIElement(DWORD dwUIElementId) +{ + return S_OK; +} + +STDMETHODIMP TSF::UI_Sink::EndUIElement(DWORD dwUIElementId) +{ + return S_OK; +} + +STDMETHODIMP TSF::UI_Sink::OnActivated(DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, REFGUID guidProfile, HKL hkl, DWORD dwFlags) +{ + return S_OK; +} + +STDMETHODIMP TSF::UI_Sink::OnChange(REFGUID rguid) +{ + return S_OK; +} From 52def78851df14b28a065eb7974ea6051a3debad Mon Sep 17 00:00:00 2001 From: dewyatt Date: Tue, 8 Jun 2010 05:22:49 -0400 Subject: [PATCH 04/30] Change SDL to not use DefWindowProc as the window class' window procedure. For some reason, having lpfnWndProc=DefWindowProc during window class registration causes IME input to not work in windows. With this small change, IME input should now work in SDL windows but not in fullscreen mode. --- src/video/win32/SDL_win32events.c | 2 +- src/video/win32/SDL_win32window.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/win32/SDL_win32events.c b/src/video/win32/SDL_win32events.c index df4a3b722..6d30beee8 100644 --- a/src/video/win32/SDL_win32events.c +++ b/src/video/win32/SDL_win32events.c @@ -703,7 +703,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)) { diff --git a/src/video/win32/SDL_win32window.c b/src/video/win32/SDL_win32window.c index f69d38573..d69ba6a63 100644 --- a/src/video/win32/SDL_win32window.c +++ b/src/video/win32/SDL_win32window.c @@ -112,7 +112,7 @@ 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; } SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc); From 649b23090a872457b26c3478266bb4e1823094f1 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Wed, 9 Jun 2010 00:03:54 -0400 Subject: [PATCH 05/30] Added On_Char method to Window_Listener for WM_CHAR messages. Removed a lot of TSF code because part of it was wrong and part was too complicated. Added Clear method to clear the window. IME input should work in both windowed mode and fullscreen mode with these changes. I have tested on Windows XP SP3 and Windows 7 Ultimate in VirtualBox. When you type a character (with an IME or not), the console will show the code point as U+XXXX. You use Left Alt+Shift (or whatever you have it set to) to switch input languages as usual. Hit ESC to exit (or close the window in windowed mode). The program will pause before exiting so you can review the console output (press a key to exit). --- EXCLUDE/GLTSF/include/App.hpp | 6 + EXCLUDE/GLTSF/include/TSF.hpp | 46 +------ EXCLUDE/GLTSF/include/Window.hpp | 3 + EXCLUDE/GLTSF/include/Window_Listener.hpp | 1 + EXCLUDE/GLTSF/src/App.cpp | 12 +- EXCLUDE/GLTSF/src/Main.cpp | 11 +- EXCLUDE/GLTSF/src/TSF.cpp | 144 ++++------------------ EXCLUDE/GLTSF/src/Window.cpp | 11 +- 8 files changed, 66 insertions(+), 168 deletions(-) diff --git a/EXCLUDE/GLTSF/include/App.hpp b/EXCLUDE/GLTSF/include/App.hpp index 658f73b81..afa9783e1 100644 --- a/EXCLUDE/GLTSF/include/App.hpp +++ b/EXCLUDE/GLTSF/include/App.hpp @@ -17,8 +17,14 @@ 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); private: + static const int Width = 800; + static const int Height = 600; + static const int Bits_Per_Pixel = 32; + static const bool Fullscreen = false; + Window my_Window; bool my_Done; }; diff --git a/EXCLUDE/GLTSF/include/TSF.hpp b/EXCLUDE/GLTSF/include/TSF.hpp index c37f4a4be..9e58b1e4e 100644 --- a/EXCLUDE/GLTSF/include/TSF.hpp +++ b/EXCLUDE/GLTSF/include/TSF.hpp @@ -7,51 +7,15 @@ class TSF { public: - -protected: - class UI_Sink : public ITfUIElementSink, public ITfInputProcessorProfileActivationSink - { - public: - UI_Sink(); - ~UI_Sink(); - - // IUnknown - STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj); - STDMETHODIMP_(ULONG) AddRef(void); - STDMETHODIMP_(ULONG) Release(void); - - // ITfUIElementSink - STDMETHODIMP BeginUIElement(DWORD dwUIElementId, BOOL *pbShow); - STDMETHODIMP UpdateUIElement(DWORD dwUIElementId); - STDMETHODIMP EndUIElement(DWORD dwUIElementId); - - // ITfInputProcessorProfileActivationSink - STDMETHODIMP OnActivated(DWORD dwProfileType, LANGID langid, - REFCLSID clsid, REFGUID catid, - REFGUID guidProfile, HKL hkl, - DWORD dwFlags); - - // ITfCompartmentEventSink - STDMETHODIMP OnChange(REFGUID rguid); - - private: - LONG my_Reference_Count; - }; - - TSF(); - ~TSF(); - - void Initialize(); - void Finalize(); + static void Initialize(); + static void Finalize(); private: - bool my_COM_Initialized; + TSF(); - CComPtr my_Thread_Manager; - UI_Sink *my_UI_Sink; + static bool COM_Initialized; - DWORD my_UI_Element_Sink_Cookie; - DWORD my_IPPA_Sink_Cookie; + static CComPtr Thread_Manager; }; #endif diff --git a/EXCLUDE/GLTSF/include/Window.hpp b/EXCLUDE/GLTSF/include/Window.hpp index f07fd477a..eda00a5a3 100644 --- a/EXCLUDE/GLTSF/include/Window.hpp +++ b/EXCLUDE/GLTSF/include/Window.hpp @@ -8,6 +8,7 @@ #include "Video_Mode.hpp" #include "Window_Listener.hpp" +#include "TSF.hpp" class Window { @@ -26,6 +27,8 @@ public: void Update(); void Display(); + void Clear(); + private: static const wchar_t *Window_Class_Name; diff --git a/EXCLUDE/GLTSF/include/Window_Listener.hpp b/EXCLUDE/GLTSF/include/Window_Listener.hpp index 52396f7e8..c99c2418a 100644 --- a/EXCLUDE/GLTSF/include/Window_Listener.hpp +++ b/EXCLUDE/GLTSF/include/Window_Listener.hpp @@ -8,6 +8,7 @@ public: virtual void On_Key_Down(int Key){} virtual void On_Key_Up(int Key){} + virtual void On_Char(unsigned int Char){} }; #endif diff --git a/EXCLUDE/GLTSF/src/App.cpp b/EXCLUDE/GLTSF/src/App.cpp index ae8ca73a5..6ce3b5627 100644 --- a/EXCLUDE/GLTSF/src/App.cpp +++ b/EXCLUDE/GLTSF/src/App.cpp @@ -1,20 +1,22 @@ #include "App.hpp" +#include "TSF.hpp" App::App() : my_Done(false) { - + TSF::Initialize(); } App::~App() { Finalize(); + TSF::Finalize(); } void App::Initialize() { Finalize(); - my_Window.Initialize(L"GLTSF", Video_Mode(800, 600, 32), false); + my_Window.Initialize(L"GLTSF", Video_Mode(Width, Height, Bits_Per_Pixel), Fullscreen); my_Window.Set_Listener(this); my_Window.Show(); } @@ -30,6 +32,7 @@ void App::Run() while (!my_Done) { my_Window.Update(); + my_Window.Clear(); my_Window.Display(); } } @@ -54,3 +57,8 @@ void App::On_Key_Up(int Key) { } + +void App::On_Char(unsigned int Char) +{ + printf("Char: U+%04X\n", Char); +} diff --git a/EXCLUDE/GLTSF/src/Main.cpp b/EXCLUDE/GLTSF/src/Main.cpp index 31febadbf..26c975da4 100644 --- a/EXCLUDE/GLTSF/src/Main.cpp +++ b/EXCLUDE/GLTSF/src/Main.cpp @@ -3,6 +3,7 @@ int main(int argc, char *argv[]) { + int Result = EXIT_SUCCESS; try { App theApp; @@ -11,7 +12,13 @@ int main(int argc, char *argv[]) catch (const std::exception& e) { printf("Error: %s\n", e.what()); - return 1; + Result = EXIT_FAILURE; } - return 0; + catch (...) + { + printf("Unhandled exception\n"); + Result = EXIT_FAILURE; + } + system("PAUSE"); + return Result; } diff --git a/EXCLUDE/GLTSF/src/TSF.cpp b/EXCLUDE/GLTSF/src/TSF.cpp index 2f2df17c5..f447e6c5b 100644 --- a/EXCLUDE/GLTSF/src/TSF.cpp +++ b/EXCLUDE/GLTSF/src/TSF.cpp @@ -1,140 +1,40 @@ #include "TSF.hpp" #include -TSF::TSF() : my_COM_Initialized(false), - my_UI_Sink(0), - my_UI_Element_Sink_Cookie(TF_INVALID_COOKIE), - my_IPPA_Sink_Cookie(TF_INVALID_COOKIE) -{ - -} - -TSF::~TSF() -{ - Finalize(); -} +bool TSF::COM_Initialized = false; +CComPtr TSF::Thread_Manager; void TSF::Initialize() { - Finalize(); + if (!COM_Initialized) + { + HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + if (S_OK != hr && S_FALSE != hr) + throw std::runtime_error("Failed to initialize COM"); - if (S_OK != CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)) - 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(&Thread_Manager)))) + throw std::runtime_error("Failed to create ITfThreadMgr instance"); - my_COM_Initialized = true; - if (S_OK != CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, __uuidof(ITfThreadMgrEx), (void **)&my_Thread_Manager)) - throw std::runtime_error("Failed to create ITfThreadMgrEx instance"); - - TfClientId Client_Id = 0; - if (FAILED(my_Thread_Manager->ActivateEx(&Client_Id, TF_TMAE_UIELEMENTENABLEDONLY))) - throw std::runtime_error("ITfThreadMgrEx::ActivateEx failed"); - - my_UI_Sink = new UI_Sink(); - ITfSource *Source = NULL; - if (FAILED(my_Thread_Manager->QueryInterface(__uuidof(ITfSource), (void **)&Source))) - throw std::runtime_error("QueryInterface failed"); - - if (FAILED(Source->AdviseSink(__uuidof(ITfUIElementSink), (ITfUIElementSink *)my_UI_Sink, &my_UI_Element_Sink_Cookie))) - throw std::runtime_error("AdviseSink failed"); - - if (FAILED(Source->AdviseSink(__uuidof(ITfInputProcessorProfileActivationSink), (ITfInputProcessorProfileActivationSink *)my_UI_Sink, &my_IPPA_Sink_Cookie))) - throw std::runtime_error("AdviseSink failed"); + TfClientId ClientId; + if (FAILED(Thread_Manager->Activate(&ClientId))) + throw std::runtime_error("ITfThreadMgr::Activate failed"); + } } void TSF::Finalize() { - if (my_UI_Sink) + if (Thread_Manager) { - ITfSource *Source = NULL; - if (SUCCEEDED(my_Thread_Manager->QueryInterface(__uuidof(ITfSource), (void **)&Source))) - { - Source->UnadviseSink(my_IPPA_Sink_Cookie); - Source->UnadviseSink(my_UI_Element_Sink_Cookie); - Source->Release(); - } - if (my_Thread_Manager) - my_Thread_Manager->Deactivate(); - - my_UI_Sink->Release(); - delete my_UI_Sink; - my_UI_Sink = NULL; + Thread_Manager->Deactivate(); + Thread_Manager = NULL; } - my_Thread_Manager = NULL; - if (my_COM_Initialized) + if (COM_Initialized) { CoUninitialize(); - my_COM_Initialized = false; + COM_Initialized = false; } } - -TSF::UI_Sink::UI_Sink() -{ - my_Reference_Count = 1; -} - -TSF::UI_Sink::~UI_Sink() -{ - -} - -STDMETHODIMP TSF::UI_Sink::QueryInterface(REFIID riid, void **ppvObj) -{ - if (NULL == ppvObj) - return E_INVALIDARG; - - *ppvObj = NULL; - if (IsEqualIID(riid, IID_IUnknown)) - *ppvObj = reinterpret_cast(this); - else if (IsEqualIID(riid, __uuidof(ITfUIElementSink))) - *ppvObj = reinterpret_cast(this); - else if (IsEqualIID(riid, __uuidof(ITfInputProcessorProfileActivationSink))) - *ppvObj = reinterpret_cast(this); - else if (IsEqualIID(riid, __uuidof(ITfCompartmentEventSink))) - *ppvObj = reinterpret_cast(this); - - if (*ppvObj) - { - AddRef(); - return S_OK; - } - return E_NOINTERFACE; -} - -ULONG TSF::UI_Sink::AddRef(void) -{ - return ++my_Reference_Count; -} - -ULONG TSF::UI_Sink::Release(void) -{ - LONG Count = --my_Reference_Count; - if (0 == Count) - delete this; - - return Count; -} - -STDMETHODIMP TSF::UI_Sink::BeginUIElement(DWORD dwUIElementId, BOOL *pbShow) -{ - return S_OK; -} - -STDMETHODIMP TSF::UI_Sink::UpdateUIElement(DWORD dwUIElementId) -{ - return S_OK; -} - -STDMETHODIMP TSF::UI_Sink::EndUIElement(DWORD dwUIElementId) -{ - return S_OK; -} - -STDMETHODIMP TSF::UI_Sink::OnActivated(DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, REFGUID guidProfile, HKL hkl, DWORD dwFlags) -{ - return S_OK; -} - -STDMETHODIMP TSF::UI_Sink::OnChange(REFGUID rguid) -{ - return S_OK; -} diff --git a/EXCLUDE/GLTSF/src/Window.cpp b/EXCLUDE/GLTSF/src/Window.cpp index 955693c05..bbb08654a 100644 --- a/EXCLUDE/GLTSF/src/Window.cpp +++ b/EXCLUDE/GLTSF/src/Window.cpp @@ -1,4 +1,5 @@ #include "Window.hpp" +#include #pragma comment(lib, "opengl32.lib") @@ -83,7 +84,7 @@ void Window::Create_Window(const std::wstring &Title, const Video_Mode &Mode, bo int Height = my_Video_Mode.Height; ReleaseDC(NULL, Screen_DC); - DWORD Style = WS_OVERLAPPEDWINDOW; + DWORD Style = WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU; if (!my_Fullscreen) { RECT Rect = {0, 0, Width, Height}; @@ -227,6 +228,9 @@ LRESULT Window::Handle_Message(HWND Handle, UINT Message, WPARAM wParam, LPARAM 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; @@ -261,3 +265,8 @@ void Window::Display() if (my_Device_Context && my_GL_Context) SwapBuffers(my_Device_Context); } + +void Window::Clear() +{ + glClear(GL_COLOR_BUFFER_BIT); +} From 36437b89caefeb56f1fefa244a94032adf1ec5c5 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Wed, 9 Jun 2010 21:36:32 -0400 Subject: [PATCH 06/30] Added else to make things clear. --- src/video/win32/SDL_win32window.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/video/win32/SDL_win32window.c b/src/video/win32/SDL_win32window.c index d69ba6a63..2b8c75fe8 100644 --- a/src/video/win32/SDL_win32window.c +++ b/src/video/win32/SDL_win32window.c @@ -115,7 +115,9 @@ SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created) if (data->wndproc == WIN_WindowProc) { data->wndproc = NULL; } - SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc); + else { + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc); + } /* Fill in the SDL window with the window data */ { From fca96b4c825c06f57b503417c2e1e3427aa7dc0e Mon Sep 17 00:00:00 2001 From: dewyatt Date: Fri, 11 Jun 2010 18:32:18 -0400 Subject: [PATCH 07/30] Added vs2008 project files for GLTSF (2008 is much faster on my old computer) --- EXCLUDE/GLTSF/GLTSF.vcproj | 231 +++++++++++++++++++++++++++++++++ EXCLUDE/GLTSF/GLTSF_vs2008.sln | 20 +++ 2 files changed, 251 insertions(+) create mode 100644 EXCLUDE/GLTSF/GLTSF.vcproj create mode 100644 EXCLUDE/GLTSF/GLTSF_vs2008.sln diff --git a/EXCLUDE/GLTSF/GLTSF.vcproj b/EXCLUDE/GLTSF/GLTSF.vcproj new file mode 100644 index 000000000..25c8a75bd --- /dev/null +++ b/EXCLUDE/GLTSF/GLTSF.vcproj @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/EXCLUDE/GLTSF/GLTSF_vs2008.sln b/EXCLUDE/GLTSF/GLTSF_vs2008.sln new file mode 100644 index 000000000..319a4c0db --- /dev/null +++ b/EXCLUDE/GLTSF/GLTSF_vs2008.sln @@ -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 From f5b3329281822b43362b5d2481f6f2376cdd4e47 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Sat, 12 Jun 2010 03:19:43 -0400 Subject: [PATCH 08/30] Renamed Window::Update to Window::Handle_Events. Removed Window::Clear. Added Window::Show_Cursor/Hide_Cursor. Added On_Resized event. --- EXCLUDE/GLTSF/include/Window.hpp | 5 +++-- EXCLUDE/GLTSF/include/Window_Listener.hpp | 2 +- EXCLUDE/GLTSF/src/Window.cpp | 15 ++++++++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/EXCLUDE/GLTSF/include/Window.hpp b/EXCLUDE/GLTSF/include/Window.hpp index eda00a5a3..f019cd268 100644 --- a/EXCLUDE/GLTSF/include/Window.hpp +++ b/EXCLUDE/GLTSF/include/Window.hpp @@ -24,10 +24,11 @@ public: void Show(); void Hide(); - void Update(); + void Handle_Events(); void Display(); - void Clear(); + void Show_Cursor(); + void Hide_Cursor(); private: static const wchar_t *Window_Class_Name; diff --git a/EXCLUDE/GLTSF/include/Window_Listener.hpp b/EXCLUDE/GLTSF/include/Window_Listener.hpp index c99c2418a..a5a96e731 100644 --- a/EXCLUDE/GLTSF/include/Window_Listener.hpp +++ b/EXCLUDE/GLTSF/include/Window_Listener.hpp @@ -5,10 +5,10 @@ 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 diff --git a/EXCLUDE/GLTSF/src/Window.cpp b/EXCLUDE/GLTSF/src/Window.cpp index bbb08654a..0160d65ec 100644 --- a/EXCLUDE/GLTSF/src/Window.cpp +++ b/EXCLUDE/GLTSF/src/Window.cpp @@ -17,6 +17,7 @@ Window::Window() : my_Handle(0), Window::~Window() { Finalize(); + Show_Cursor(); } void Window::Initialize(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen) @@ -219,6 +220,9 @@ LRESULT Window::Handle_Message(HWND Handle, UINT Message, WPARAM wParam, LPARAM { switch (Message) { + case WM_SIZE: + Call_Listener(On_Resized(LOWORD(lParam), HIWORD(lParam))); + break; case WM_CLOSE: Call_Listener(On_Close()); break; @@ -250,7 +254,7 @@ void Window::Hide() ShowWindow(my_Handle, SW_HIDE); } -void Window::Update() +void Window::Handle_Events() { MSG Message = {0}; while (PeekMessageW(&Message, NULL, 0, 0, PM_REMOVE)) @@ -266,7 +270,12 @@ void Window::Display() SwapBuffers(my_Device_Context); } -void Window::Clear() +void Window::Show_Cursor() { - glClear(GL_COLOR_BUFFER_BIT); + ShowCursor(TRUE); +} + +void Window::Hide_Cursor() +{ + ShowCursor(FALSE); } From 4ec949ec5b1502b65b3c72509f9591d0c598a695 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Sat, 12 Jun 2010 03:21:54 -0400 Subject: [PATCH 09/30] Added support for On_Resized event to App. Added OpenGL code to draw a rotating triangle. Rearranged main loop code. --- EXCLUDE/GLTSF/include/App.hpp | 6 ++++- EXCLUDE/GLTSF/src/App.cpp | 45 +++++++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/EXCLUDE/GLTSF/include/App.hpp b/EXCLUDE/GLTSF/include/App.hpp index afa9783e1..88cdf41da 100644 --- a/EXCLUDE/GLTSF/include/App.hpp +++ b/EXCLUDE/GLTSF/include/App.hpp @@ -18,12 +18,16 @@ public: virtual void On_Key_Down(int Key); virtual void On_Key_Up(int Key); virtual void On_Char(unsigned int Char); + virtual void On_Resized(unsigned int Width, unsigned int Height); private: + void Update(); + void Draw(); + static const int Width = 800; static const int Height = 600; static const int Bits_Per_Pixel = 32; - static const bool Fullscreen = false; + static const bool Fullscreen = true; Window my_Window; bool my_Done; diff --git a/EXCLUDE/GLTSF/src/App.cpp b/EXCLUDE/GLTSF/src/App.cpp index 6ce3b5627..feb8be51c 100644 --- a/EXCLUDE/GLTSF/src/App.cpp +++ b/EXCLUDE/GLTSF/src/App.cpp @@ -1,5 +1,11 @@ #include "App.hpp" #include "TSF.hpp" +#include +#include + +#pragma comment(lib, "glu32.lib") + +GLfloat Rotation = 0.0f; App::App() : my_Done(false) { @@ -19,6 +25,7 @@ void App::Initialize() 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() @@ -31,8 +38,10 @@ void App::Run() Initialize(); while (!my_Done) { - my_Window.Update(); - my_Window.Clear(); + my_Window.Handle_Events(); + + Update(); + Draw(); my_Window.Display(); } } @@ -62,3 +71,35 @@ 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(); +} From 4b2cb56c1294328e2039b6c4753a678a4050d80f Mon Sep 17 00:00:00 2001 From: dewyatt Date: Mon, 21 Jun 2010 17:16:37 -0400 Subject: [PATCH 10/30] Starting to implement ITextStoreACP. It's very incomplete and will probably change quite a bit but it's a start. ITextStoreACP is the minimum interface to be considered TSF-aware. --- EXCLUDE/GLTSF/include/TSF.hpp | 62 +++++++ EXCLUDE/GLTSF/src/TSF.cpp | 309 +++++++++++++++++++++++++++++++++- 2 files changed, 369 insertions(+), 2 deletions(-) diff --git a/EXCLUDE/GLTSF/include/TSF.hpp b/EXCLUDE/GLTSF/include/TSF.hpp index 9e58b1e4e..f6f3fbea8 100644 --- a/EXCLUDE/GLTSF/include/TSF.hpp +++ b/EXCLUDE/GLTSF/include/TSF.hpp @@ -11,11 +11,73 @@ public: 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 my_Document_Manager; + CComPtr my_Context; + DWORD my_Edit_Cookie; + CComPtr my_Sink; + DWORD my_Sink_Mask; + DWORD my_Lock; + DWORD my_Lock_Queued; + CComPtr my_Composition_View; + TS_SELECTION_ACP my_Composition_Selection; + }; + TSF(); static bool COM_Initialized; static CComPtr Thread_Manager; + static TfClientId Client_Id; + static TSF_Text_Store *Text_Store; }; #endif diff --git a/EXCLUDE/GLTSF/src/TSF.cpp b/EXCLUDE/GLTSF/src/TSF.cpp index f447e6c5b..e88d44516 100644 --- a/EXCLUDE/GLTSF/src/TSF.cpp +++ b/EXCLUDE/GLTSF/src/TSF.cpp @@ -3,6 +3,8 @@ bool TSF::COM_Initialized = false; CComPtr TSF::Thread_Manager; +TfClientId TSF::Client_Id; +TSF::TSF_Text_Store *TSF::Text_Store = NULL; void TSF::Initialize() { @@ -19,9 +21,11 @@ void TSF::Initialize() if (FAILED(CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, reinterpret_cast(&Thread_Manager)))) throw std::runtime_error("Failed to create ITfThreadMgr instance"); - TfClientId ClientId; - if (FAILED(Thread_Manager->Activate(&ClientId))) + if (FAILED(Thread_Manager->Activate(&Client_Id))) throw std::runtime_error("ITfThreadMgr::Activate failed"); + + Text_Store = new TSF_Text_Store; + Text_Store->Initialize(); } } @@ -38,3 +42,304 @@ void TSF::Finalize() 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(this); + else if (IID_ITfContextOwnerCompositionSink == riid) + *ppvObject = static_cast(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; +} + +STDMETHODIMP TSF::TSF_Text_Store::AdviseSink(REFIID riid, IUnknown *punk, DWORD dwMask) +{ + if (!punk || IID_ITextStoreACPSink != riid) + return E_INVALIDARG; + + if (!my_Sink) + { + punk->QueryInterface(&my_Sink); + if (!my_Sink) + return E_UNEXPECTED; + } + else + { + CComPtr 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) +{ + if (!punk) + return E_INVALIDARG; + + if (!my_Sink) + return CONNECT_E_NOCONNECTION; + + CComPtr 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) +{ + if (!my_Sink) + return E_FAIL; + + if (!phrSession) + return 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) +{ + if (!pdcs) + return 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) +{ + if (acpTestStart < 0 || acpTestStart > acpTestEnd || !pacpResultStart || !pacpResultEnd) + return 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) +{ + if (TS_LF_READ != (my_Lock & TS_LF_READ)) + return TS_E_NOLOCK; + + if (!ulCount || !pSelection || !pcFetched) + return E_INVALIDARG; + + *pcFetched = 0; + if (TS_DEFAULT_SELECTION != ulIndex && 0 != ulIndex) + return TS_E_NOSELECTION; + + if (my_Composition_View) + { + *pSelection = my_Composition_Selection; + } + else + { + //TODO + } + 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) +{ + return E_NOTIMPL; +} + +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) +{ + return E_NOTIMPL; +} + +STDMETHODIMP TSF::TSF_Text_Store::GetEmbedded(LONG acpPos, REFGUID rguidService, REFIID riid, IUnknown **ppunk) +{ + return E_NOTIMPL; +} + +STDMETHODIMP TSF::TSF_Text_Store::QueryInsertEmbedded(const GUID *pguidService, const FORMATETC *pFormatEtc, BOOL *pfInsertable) +{ + 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) +{ + return E_NOTIMPL; +} + +STDMETHODIMP TSF::TSF_Text_Store::RequestSupportedAttrs(DWORD dwFlags, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs) +{ + return E_NOTIMPL; +} + +STDMETHODIMP TSF::TSF_Text_Store::RequestAttrsAtPosition(LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags) +{ + return E_NOTIMPL; +} + +STDMETHODIMP TSF::TSF_Text_Store::RequestAttrsTransitioningAtPosition(LONG acpPos, ULONG cFilterAttrs, const TS_ATTRID *paFilterAttrs, DWORD dwFlags) +{ + 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) +{ + return E_NOTIMPL; +} + +STDMETHODIMP TSF::TSF_Text_Store::RetrieveRequestedAttrs(ULONG ulCount, TS_ATTRVAL *paAttrVals, ULONG *pcFetched) +{ + 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) +{ + *pfOk = FALSE; + return S_OK; +} + +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(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() +{ + +} From cbda698ad4f365181a390cf315a6ba2518770cb3 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Sun, 27 Jun 2010 22:03:08 -0400 Subject: [PATCH 11/30] Added condition check macros to make the code clear and easier to debug. Updated code to use macros. --- EXCLUDE/GLTSF/src/TSF.cpp | 79 +++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/EXCLUDE/GLTSF/src/TSF.cpp b/EXCLUDE/GLTSF/src/TSF.cpp index e88d44516..4060397ff 100644 --- a/EXCLUDE/GLTSF/src/TSF.cpp +++ b/EXCLUDE/GLTSF/src/TSF.cpp @@ -74,16 +74,22 @@ STDMETHODIMP_(ULONG) TSF::TSF_Text_Store::Release() 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) { - if (!punk || IID_ITextStoreACPSink != riid) - return E_INVALIDARG; + ENSURE(punk && IID_ITextStoreACP == riid, E_INVALIDARG); if (!my_Sink) { - punk->QueryInterface(&my_Sink); - if (!my_Sink) - return E_UNEXPECTED; + HRESULT hr = punk->QueryInterface(&my_Sink); + ENSURE(SUCCEEDED(hr) && my_Sink, E_UNEXPECTED); } else { @@ -99,11 +105,8 @@ STDMETHODIMP TSF::TSF_Text_Store::AdviseSink(REFIID riid, IUnknown *punk, DWORD STDMETHODIMP TSF::TSF_Text_Store::UnadviseSink(IUnknown *punk) { - if (!punk) - return E_INVALIDARG; - - if (!my_Sink) - return CONNECT_E_NOCONNECTION; + ENSURE(punk, E_INVALIDARG); + ENSURE(my_Sink, CONNECT_E_NOCONNECTION); CComPtr Unknown_1, Unknown_2; punk->QueryInterface(&Unknown_1); @@ -119,12 +122,8 @@ STDMETHODIMP TSF::TSF_Text_Store::UnadviseSink(IUnknown *punk) STDMETHODIMP TSF::TSF_Text_Store::RequestLock(DWORD dwLockFlags, HRESULT *phrSession) { - if (!my_Sink) - return E_FAIL; - - if (!phrSession) - return E_INVALIDARG; - + ENSURE(my_Sink, E_FAIL); + ENSURE(phrSession, E_INVALIDARG); if (my_Lock) { if (TS_LF_READ == (my_Lock & TS_LF_READWRITE) @@ -157,9 +156,7 @@ STDMETHODIMP TSF::TSF_Text_Store::RequestLock(DWORD dwLockFlags, HRESULT *phrSes STDMETHODIMP TSF::TSF_Text_Store::GetStatus(TS_STATUS *pdcs) { - if (!pdcs) - return E_INVALIDARG; - + ENSURE(pdcs, E_INVALIDARG); pdcs->dwDynamicFlags = 0; pdcs->dwStaticFlags = TS_SS_NOHIDDENTEXT; return S_OK; @@ -167,8 +164,7 @@ STDMETHODIMP TSF::TSF_Text_Store::GetStatus(TS_STATUS *pdcs) STDMETHODIMP TSF::TSF_Text_Store::QueryInsert(LONG acpTestStart, LONG acpTestEnd, ULONG cch, LONG *pacpResultStart, LONG *pacpResultEnd) { - if (acpTestStart < 0 || acpTestStart > acpTestEnd || !pacpResultStart || !pacpResultEnd) - return E_INVALIDARG; + ENSURE(0 <= acpTestStart && acpTestStart <= acpTestEnd && pacpResultStart && pacpResultEnd, E_INVALIDARG); *pacpResultStart = acpTestStart; *pacpResultEnd = acpTestStart + cch; @@ -177,16 +173,11 @@ STDMETHODIMP TSF::TSF_Text_Store::QueryInsert(LONG acpTestStart, LONG acpTestEnd STDMETHODIMP TSF::TSF_Text_Store::GetSelection(ULONG ulIndex, ULONG ulCount, TS_SELECTION_ACP *pSelection, ULONG *pcFetched) { - if (TS_LF_READ != (my_Lock & TS_LF_READ)) - return TS_E_NOLOCK; - - if (!ulCount || !pSelection || !pcFetched) - return E_INVALIDARG; + ENSURE(TS_LF_READ == (my_Lock && TS_LF_READ), TS_E_NOLOCK); + ENSURE(ulCount && pSelection && pcFetched, E_INVALIDARG); *pcFetched = 0; - if (TS_DEFAULT_SELECTION != ulIndex && 0 != ulIndex) - return TS_E_NOSELECTION; - + ENSURE(TS_DEFAULT_SELECTION == ulIndex || 0 == ulIndex, TS_E_NOSELECTION); if (my_Composition_View) { *pSelection = my_Composition_Selection; @@ -195,6 +186,7 @@ STDMETHODIMP TSF::TSF_Text_Store::GetSelection(ULONG ulIndex, ULONG ulCount, TS_ { //TODO } + *pcFetched = 1; return S_OK; } @@ -205,7 +197,18 @@ STDMETHODIMP TSF::TSF_Text_Store::SetSelection(ULONG ulCount, const TS_SELECTION 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) { - return E_NOTIMPL; + 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) @@ -215,16 +218,23 @@ STDMETHODIMP TSF::TSF_Text_Store::SetText(DWORD dwFlags, LONG acpStart, LONG acp 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; } @@ -240,31 +250,37 @@ STDMETHODIMP TSF::TSF_Text_Store::InsertTextAtSelection(DWORD dwFlags, const WCH 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; } @@ -300,8 +316,7 @@ STDMETHODIMP TSF::TSF_Text_Store::GetWnd(TsViewCookie vcView, HWND *phwnd) STDMETHODIMP TSF::TSF_Text_Store::OnStartComposition(ITfCompositionView *pComposition, BOOL *pfOk) { - *pfOk = FALSE; - return S_OK; + return E_NOTIMPL; } STDMETHODIMP TSF::TSF_Text_Store::OnUpdateComposition(ITfCompositionView *pComposition, ITfRange *pRangeNew) From 825ef53157e62effee4ca0c51c24ae493a6e0c01 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Wed, 30 Jun 2010 17:29:20 -0400 Subject: [PATCH 12/30] Added GLIMM (using IMM instead of TSF) Uses small bit of TSF to fully disable cicero (TSF for non-TSF enabled apps) --- EXCLUDE/GLIMM/GLIMM.sln | 20 ++ EXCLUDE/GLIMM/GLIMM.vcproj | 233 +++++++++++++++++ EXCLUDE/GLIMM/include/App.hpp | 36 +++ EXCLUDE/GLIMM/include/IMM.hpp | 30 +++ EXCLUDE/GLIMM/include/Video_Mode.hpp | 30 +++ EXCLUDE/GLIMM/include/Window.hpp | 62 +++++ EXCLUDE/GLIMM/include/Window_Listener.hpp | 14 ++ EXCLUDE/GLIMM/src/App.cpp | 103 ++++++++ EXCLUDE/GLIMM/src/IMM.cpp | 165 ++++++++++++ EXCLUDE/GLIMM/src/Main.cpp | 24 ++ EXCLUDE/GLIMM/src/Video_Mode.cpp | 100 ++++++++ EXCLUDE/GLIMM/src/Window.cpp | 293 ++++++++++++++++++++++ 12 files changed, 1110 insertions(+) create mode 100644 EXCLUDE/GLIMM/GLIMM.sln create mode 100644 EXCLUDE/GLIMM/GLIMM.vcproj create mode 100644 EXCLUDE/GLIMM/include/App.hpp create mode 100644 EXCLUDE/GLIMM/include/IMM.hpp create mode 100644 EXCLUDE/GLIMM/include/Video_Mode.hpp create mode 100644 EXCLUDE/GLIMM/include/Window.hpp create mode 100644 EXCLUDE/GLIMM/include/Window_Listener.hpp create mode 100644 EXCLUDE/GLIMM/src/App.cpp create mode 100644 EXCLUDE/GLIMM/src/IMM.cpp create mode 100644 EXCLUDE/GLIMM/src/Main.cpp create mode 100644 EXCLUDE/GLIMM/src/Video_Mode.cpp create mode 100644 EXCLUDE/GLIMM/src/Window.cpp diff --git a/EXCLUDE/GLIMM/GLIMM.sln b/EXCLUDE/GLIMM/GLIMM.sln new file mode 100644 index 000000000..6dd674eef --- /dev/null +++ b/EXCLUDE/GLIMM/GLIMM.sln @@ -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 diff --git a/EXCLUDE/GLIMM/GLIMM.vcproj b/EXCLUDE/GLIMM/GLIMM.vcproj new file mode 100644 index 000000000..5949e86d4 --- /dev/null +++ b/EXCLUDE/GLIMM/GLIMM.vcproj @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/EXCLUDE/GLIMM/include/App.hpp b/EXCLUDE/GLIMM/include/App.hpp new file mode 100644 index 000000000..c7609fc37 --- /dev/null +++ b/EXCLUDE/GLIMM/include/App.hpp @@ -0,0 +1,36 @@ +#ifndef APP_HPP +#define APP_HPP + +#include "Window.hpp" + +class App : public Window_Listener +{ +public: + App(); + virtual ~App(); + + void Initialize(); + void Finalize(); + + void Run(); + + virtual void On_Close(); + virtual void On_Key_Down(int Key); + virtual void On_Key_Up(int Key); + virtual void On_Char(unsigned int Char); + virtual void On_Resized(unsigned int Width, unsigned int Height); + +private: + void Update(); + void Draw(); + + static const int Width = 800; + static const int Height = 600; + static const int Bits_Per_Pixel = 32; + static const bool Fullscreen = false; + + Window my_Window; + bool my_Done; +}; + +#endif diff --git a/EXCLUDE/GLIMM/include/IMM.hpp b/EXCLUDE/GLIMM/include/IMM.hpp new file mode 100644 index 000000000..ae2dfb813 --- /dev/null +++ b/EXCLUDE/GLIMM/include/IMM.hpp @@ -0,0 +1,30 @@ +#ifndef IMM_HPP +#define IMM_HPP + +#define WIN32_LEAN_AND_MEAN +#include +#include + +class IMM +{ +public: + IMM(); + ~IMM(); + + void Initialize(HWND Window); + void Finalize(); + + LRESULT Handle_Message(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam, bool &Ate); + +private: + void Update_Input_Locale(); + + bool my_COM_Initialized; + ITfThreadMgr *my_Thread_Manager; + HWND my_Window; + HIMC my_Context; + HKL my_HKL; + bool my_Vertical_Candidates; +}; + +#endif diff --git a/EXCLUDE/GLIMM/include/Video_Mode.hpp b/EXCLUDE/GLIMM/include/Video_Mode.hpp new file mode 100644 index 000000000..00a801400 --- /dev/null +++ b/EXCLUDE/GLIMM/include/Video_Mode.hpp @@ -0,0 +1,30 @@ +#ifndef VIDEO_MODE_HPP +#define VIDEO_MODE_HPP + +#include + +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 diff --git a/EXCLUDE/GLIMM/include/Window.hpp b/EXCLUDE/GLIMM/include/Window.hpp new file mode 100644 index 000000000..61e8cf7fe --- /dev/null +++ b/EXCLUDE/GLIMM/include/Window.hpp @@ -0,0 +1,62 @@ +#ifndef WINDOW_HPP +#define WINDOW_HPP + +#include + +#define WIN32_LEAN_AND_MEAN +#include + +#include "Video_Mode.hpp" +#include "Window_Listener.hpp" +#include "IMM.hpp" + +class Window +{ +public: + Window(); + ~Window(); + + void Initialize(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen); + void Finalize(); + + void Set_Listener(Window_Listener *Listener); + + void Show(); + void Hide(); + + void Handle_Events(); + void Display(); + + void Show_Cursor(); + void Hide_Cursor(); + + HWND Get_Handle(); + +private: + static const wchar_t *Window_Class_Name; + + void Register_Class(); + void Unregister_Class(); + + void Create_Window(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen); + void Destroy_Window(); + + void Create_Context(const Video_Mode &Mode); + void Destroy_Context(); + + void Switch_To_Fullscreen(const Video_Mode &Mode); + + LRESULT Handle_Message(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam); + static LRESULT CALLBACK Window_Procedure(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam); + + HWND my_Handle; + Video_Mode my_Video_Mode; + bool my_Fullscreen; + HDC my_Device_Context; + HGLRC my_GL_Context; + bool my_Class_Registered; + Window_Listener *my_Listener; + IMM my_IMM; +}; + +#endif diff --git a/EXCLUDE/GLIMM/include/Window_Listener.hpp b/EXCLUDE/GLIMM/include/Window_Listener.hpp new file mode 100644 index 000000000..a5a96e731 --- /dev/null +++ b/EXCLUDE/GLIMM/include/Window_Listener.hpp @@ -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 diff --git a/EXCLUDE/GLIMM/src/App.cpp b/EXCLUDE/GLIMM/src/App.cpp new file mode 100644 index 000000000..b2a527c57 --- /dev/null +++ b/EXCLUDE/GLIMM/src/App.cpp @@ -0,0 +1,103 @@ +#include "App.hpp" +#include +#include + +#pragma comment(lib, "glu32.lib") + +GLfloat Rotation = 0.0f; + +App::App() : my_Done(false) +{ + +} + +App::~App() +{ + Finalize(); +} + +void App::Initialize() +{ + Finalize(); + + my_Window.Initialize(L"GLTSF", Video_Mode(Width, Height, Bits_Per_Pixel), Fullscreen); + my_Window.Set_Listener(this); + my_Window.Show(); + my_Window.Hide_Cursor(); +} + +void App::Finalize() +{ + my_Window.Finalize(); +} + +void App::Run() +{ + Initialize(); + while (!my_Done) + { + my_Window.Handle_Events(); + + Update(); + Draw(); + my_Window.Display(); + } +} + +void App::On_Close() +{ + my_Done = true; + my_Window.Hide(); +} + +void App::On_Key_Down(int Key) +{ + switch (Key) + { + case VK_ESCAPE: + On_Close(); + break; + } +} + +void App::On_Key_Up(int Key) +{ + +} + +void App::On_Char(unsigned int Char) +{ + printf("Char: U+%04X\n", Char); +} + +void App::On_Resized(unsigned int Width, unsigned int Height) +{ + glViewport(0, 0, Width, Height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void App::Update() +{ + Rotation += 0.2f; +} + +void App::Draw() +{ + glClear(GL_COLOR_BUFFER_BIT); + + glLoadIdentity(); + glRotatef(Rotation, 0.0f, 0.0f, -1.0f); + + glBegin(GL_TRIANGLES); + glColor3f(0.7f, 0.0f, 0.0f); + glVertex3f(0.0f, 0.5f, 0.0f); + glColor3f(0.0f, 0.7f, 0.0f); + glVertex3f(-0.5f, -0.5f, 0.0f); + glColor3f(0.0f, 0.0f, 0.7f); + glVertex3f(0.5f, -0.5f, 0.0f); + glEnd(); +} diff --git a/EXCLUDE/GLIMM/src/IMM.cpp b/EXCLUDE/GLIMM/src/IMM.cpp new file mode 100644 index 000000000..0ef3fdc93 --- /dev/null +++ b/EXCLUDE/GLIMM/src/IMM.cpp @@ -0,0 +1,165 @@ +#include "IMM.hpp" +#include + +IMM::IMM() : my_COM_Initialized(false), + my_Thread_Manager(0), + my_Window(0), + my_Context(0), + my_HKL(0), + my_Vertical_Candidates(false) +{ + +} + +IMM::~IMM() +{ + Finalize(); +} + +void IMM::Initialize(HWND Window) +{ + Finalize(); + + my_Window = Window; + + if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))) + { + my_COM_Initialized = true; + if (SUCCEEDED(CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, reinterpret_cast(&my_Thread_Manager)))) + { + ITfDocumentMgr *Document_Manager = 0; + if (FAILED(my_Thread_Manager->AssociateFocus(Window, NULL, &Document_Manager))) + printf("Warning: ITfThreadMgr->AssociateFocus failed\n"); + + if (Document_Manager) + Document_Manager->Release(); + } + else + printf("Warning: Failed to create ITfThreadMgr instance\n"); + } + else + printf("Warning: Failed to initialize COM\n"); + + ImmDisableTextFrameService(-1); + + my_Context = ImmGetContext(my_Window); + if (!ImmReleaseContext(my_Window, my_Context)) + throw std::runtime_error("Error releasing context"); + + if (!my_Context) + throw std::runtime_error("No context"); + + Update_Input_Locale(); +} + +void IMM::Finalize() +{ + if (my_Thread_Manager) + { + my_Thread_Manager->Release(); + my_Thread_Manager = 0; + } + if (my_COM_Initialized) + { + CoUninitialize(); + my_COM_Initialized = false; + } +} + +#define GET_LANG(hkl) LOWORD((hkl)) +#define GET_PRIMLANG(hkl) ((WORD)PRIMARYLANGID(GET_LANG((hkl)))) +#define GET_SUBLANG(hkl) SUBLANGID(GET_LANG((hkl))) + +void IMM::Update_Input_Locale() +{ + static HKL Previous_HKL = 0; + my_HKL = GetKeyboardLayout(0); + if (Previous_HKL == my_HKL) + return; + + Previous_HKL = my_HKL; + my_Vertical_Candidates = false; + switch (GET_PRIMLANG(my_HKL)) + { + case LANG_CHINESE: + my_Vertical_Candidates = true; + switch (GET_SUBLANG(my_HKL)) + { + case SUBLANG_CHINESE_SIMPLIFIED: + my_Vertical_Candidates = false; + break; + } + break; + case LANG_JAPANESE: + my_Vertical_Candidates = true; + break; + } +} + +LRESULT IMM::Handle_Message(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam, bool &Ate) +{ + Ate = false; + switch (Message) + { + case WM_INPUTLANGCHANGE: + Update_Input_Locale(); + break; + case WM_IME_SETCONTEXT: + lParam = 0; + return DefWindowProcW(my_Window, Message, wParam, lParam); + break; + case WM_IME_STARTCOMPOSITION: + Ate = true; + break; + case WM_IME_COMPOSITION: + { + Ate = true; + HIMC Context = ImmGetContext(Window); + if (!Context) + break; + + if (lParam & GCS_RESULTSTR) + { + LONG Length = ImmGetCompositionStringW(Context, GCS_RESULTSTR, 0, 0); + std::wstring Composition(Length / sizeof(wchar_t), 0); + Length = ImmGetCompositionStringW(Context, GCS_RESULTSTR, &Composition[0], Composition.size() * sizeof(Composition[0])); + printf("GCS_RESULTSTR: "); + for (LONG i = 0; i < Length / sizeof(wchar_t); ++i) + printf("U+%04X ", Composition[i]); + + printf("\n"); + } + if (lParam & GCS_COMPSTR) + { + LONG Length = ImmGetCompositionStringW(Context, GCS_COMPSTR, 0, 0); + std::wstring Composition(Length / sizeof(wchar_t), 0); + Length = ImmGetCompositionStringW(Context, GCS_COMPSTR, &Composition[0], Composition.size() * sizeof(Composition[0])); + printf("GCS_COMPSTR: "); + for (LONG i = 0; i < Length / sizeof(wchar_t); ++i) + printf("U+%04X ", Composition[i]); + + printf("\n"); + } + ImmReleaseContext(Window, Context); + } + break; + case WM_IME_ENDCOMPOSITION: + break; + case WM_IME_NOTIFY: + switch (wParam) + { + case IMN_SETCONVERSIONMODE: + + break; + case IMN_SETOPENSTATUS: + Update_Input_Locale(); + break; + case IMN_OPENCANDIDATE: + case IMN_CHANGECANDIDATE: + Ate = true; + break; + } + break; + } + return 0; +} diff --git a/EXCLUDE/GLIMM/src/Main.cpp b/EXCLUDE/GLIMM/src/Main.cpp new file mode 100644 index 000000000..26c975da4 --- /dev/null +++ b/EXCLUDE/GLIMM/src/Main.cpp @@ -0,0 +1,24 @@ +#include "App.hpp" +#include + +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; +} diff --git a/EXCLUDE/GLIMM/src/Video_Mode.cpp b/EXCLUDE/GLIMM/src/Video_Mode.cpp new file mode 100644 index 000000000..177e8b956 --- /dev/null +++ b/EXCLUDE/GLIMM/src/Video_Mode.cpp @@ -0,0 +1,100 @@ +#include "Video_Mode.hpp" +#include +#include +#define WIN32_LEAN_AND_MEAN +#include + +namespace +{ + + typedef std::vector 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()); + } +} diff --git a/EXCLUDE/GLIMM/src/Window.cpp b/EXCLUDE/GLIMM/src/Window.cpp new file mode 100644 index 000000000..10b985353 --- /dev/null +++ b/EXCLUDE/GLIMM/src/Window.cpp @@ -0,0 +1,293 @@ +#include "Window.hpp" +#include + +#pragma comment(lib, "opengl32.lib") + +const wchar_t *Window::Window_Class_Name = L"GLTSF"; + +Window::Window() : my_Handle(0), + my_Device_Context(0), + my_GL_Context(0), + my_Class_Registered(false), + my_Listener(0) +{ + +} + +Window::~Window() +{ + Finalize(); + Show_Cursor(); +} + +void Window::Initialize(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen) +{ + Finalize(); + + my_Video_Mode = Mode; + if (!my_Video_Mode.Is_Valid()) + throw std::runtime_error("Invalid video mode"); + + my_Fullscreen = Fullscreen; + Register_Class(); + Create_Window(Title, Mode, Fullscreen); + my_IMM.Initialize(my_Handle); +} + +void Window::Finalize() +{ + my_IMM.Finalize(); + Destroy_Window(); + Unregister_Class(); +} + +void Window::Set_Listener(Window_Listener *Listener) +{ + my_Listener = Listener; +} + +void Window::Show() +{ + if (my_Handle) + ShowWindow(my_Handle, SW_SHOW); +} + +void Window::Hide() +{ + if (my_Handle) + ShowWindow(my_Handle, SW_HIDE); +} + +void Window::Handle_Events() +{ + MSG Message = {0}; + while (PeekMessageW(&Message, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&Message); + DispatchMessageW(&Message); + } +} + +void Window::Display() +{ + if (my_Device_Context && my_GL_Context) + SwapBuffers(my_Device_Context); +} + +void Window::Show_Cursor() +{ + ShowCursor(TRUE); +} + +void Window::Hide_Cursor() +{ + ShowCursor(FALSE); +} + +HWND Window::Get_Handle() +{ + return my_Handle; +} + +void Window::Register_Class() +{ + WNDCLASSEXW Window_Class = {0}; + Window_Class.cbSize = sizeof(Window_Class); + Window_Class.style = 0; + Window_Class.lpfnWndProc = &Window::Window_Procedure; + Window_Class.cbClsExtra = 0; + Window_Class.cbWndExtra = 0; + Window_Class.hInstance = GetModuleHandle(NULL); + Window_Class.hIcon = NULL; + Window_Class.hCursor = NULL; + Window_Class.hbrBackground = NULL; + Window_Class.lpszMenuName = NULL; + Window_Class.lpszClassName = Window_Class_Name; + Window_Class.hIconSm = NULL; + if (0 == RegisterClassExW(&Window_Class)) + throw std::runtime_error("Failed to register window class"); + + my_Class_Registered = true; +} + +void Window::Unregister_Class() +{ + if (my_Class_Registered) + { + if (0 == UnregisterClassW(Window_Class_Name, GetModuleHandle(NULL))) + printf("Warning: Failed to unregister window class\n"); + + my_Class_Registered = false; + } +} + +void Window::Create_Window(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen) +{ + HDC Screen_DC = GetDC(NULL); + int Left = (GetDeviceCaps(Screen_DC, HORZRES) - my_Video_Mode.Width) / 2; + int Top = (GetDeviceCaps(Screen_DC, VERTRES) - my_Video_Mode.Height) / 2; + int Width = my_Video_Mode.Width; + int Height = my_Video_Mode.Height; + ReleaseDC(NULL, Screen_DC); + + DWORD Style = WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU; + if (!my_Fullscreen) + { + RECT Rect = {0, 0, Width, Height}; + AdjustWindowRect(&Rect, Style, false); + Width = Rect.right - Rect.left; + Height = Rect.bottom - Rect.top; + } + my_Handle = CreateWindowW(Window_Class_Name, Title.c_str(), Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this); + if (!my_Handle) + throw std::runtime_error("Failed to create window"); + + if (Fullscreen) + Switch_To_Fullscreen(Mode); + + Create_Context(Mode); + + RECT Rect = {0}; + GetClientRect(my_Handle, &Rect); + //TODO: ... +} + +void Window::Destroy_Window() +{ + Destroy_Context(); + if (my_Handle) + { + DestroyWindow(my_Handle); + my_Handle = 0; + + if (my_Fullscreen) + ChangeDisplaySettings(NULL, 0); + } +} + +void Window::Create_Context(const Video_Mode &Mode) +{ + my_Device_Context = GetDC(my_Handle); + if (!my_Device_Context) + throw std::runtime_error("Failed to get device context"); + + PIXELFORMATDESCRIPTOR Pixel_Descriptor = {0}; + Pixel_Descriptor.nSize = sizeof(Pixel_Descriptor); + Pixel_Descriptor.nVersion = 1; + Pixel_Descriptor.iLayerType = PFD_MAIN_PLANE; + Pixel_Descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + Pixel_Descriptor.iPixelType = PFD_TYPE_RGBA; + Pixel_Descriptor.cColorBits = static_cast(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(reinterpret_cast(lParam)->lpCreateParams); + SetWindowLongPtr(Handle, GWLP_USERDATA, This); + return 0; + } + break; + case WM_DESTROY: + PostQuitMessage(0); + return 0; + break; + default: + { + Window* Win = reinterpret_cast(GetWindowLongPtr(Handle, GWLP_USERDATA)); + if (Win) + return Win->Handle_Message(Handle, Message, wParam, lParam); + } + break; + } + return DefWindowProcW(Handle, Message, wParam, lParam); +} + +#define Call_Listener(x)\ + if (my_Listener) my_Listener->x + +LRESULT Window::Handle_Message(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam) +{ + bool IMM_Message = false; + LRESULT Result = my_IMM.Handle_Message(Handle, Message, wParam, lParam, IMM_Message); + if (IMM_Message) + return Result; + + switch (Message) + { + case WM_SIZE: + Call_Listener(On_Resized(LOWORD(lParam), HIWORD(lParam))); + break; + case WM_CLOSE: + Call_Listener(On_Close()); + break; + case WM_KEYDOWN: + Call_Listener(On_Key_Down(wParam)); + break; + case WM_KEYUP: + Call_Listener(On_Key_Up(wParam)); + break; + case WM_CHAR: + Call_Listener(On_Char(wParam)); + break; + default: + return DefWindowProcW(Handle, Message, wParam, lParam); + break; + } + return 0; +} From 6d7e820588d539b16b7786490c3320fa6e736593 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Sun, 4 Jul 2010 06:07:38 -0400 Subject: [PATCH 13/30] Added Get_IMM method to Window. Added focus gain/loss events for IMM. --- EXCLUDE/GLIMM/include/Window.hpp | 1 + EXCLUDE/GLIMM/src/Window.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/EXCLUDE/GLIMM/include/Window.hpp b/EXCLUDE/GLIMM/include/Window.hpp index 61e8cf7fe..dc465d421 100644 --- a/EXCLUDE/GLIMM/include/Window.hpp +++ b/EXCLUDE/GLIMM/include/Window.hpp @@ -31,6 +31,7 @@ public: void Hide_Cursor(); HWND Get_Handle(); + IMM &Get_IMM(); private: static const wchar_t *Window_Class_Name; diff --git a/EXCLUDE/GLIMM/src/Window.cpp b/EXCLUDE/GLIMM/src/Window.cpp index 10b985353..dc00303e9 100644 --- a/EXCLUDE/GLIMM/src/Window.cpp +++ b/EXCLUDE/GLIMM/src/Window.cpp @@ -89,6 +89,11 @@ HWND Window::Get_Handle() return my_Handle; } +IMM & Window::Get_IMM() +{ + return my_IMM; +} + void Window::Register_Class() { WNDCLASSEXW Window_Class = {0}; @@ -285,6 +290,12 @@ LRESULT Window::Handle_Message(HWND Handle, UINT Message, WPARAM wParam, LPARAM 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; default: return DefWindowProcW(Handle, Message, wParam, lParam); break; From 71f0192c595469e6db4ed9a4924c5f6dfff2f54f Mon Sep 17 00:00:00 2001 From: dewyatt Date: Sun, 4 Jul 2010 06:15:42 -0400 Subject: [PATCH 14/30] Fixed window title (from GLTSF to GLIMM). --- EXCLUDE/GLIMM/src/App.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/EXCLUDE/GLIMM/src/App.cpp b/EXCLUDE/GLIMM/src/App.cpp index b2a527c57..e3da11c45 100644 --- a/EXCLUDE/GLIMM/src/App.cpp +++ b/EXCLUDE/GLIMM/src/App.cpp @@ -20,7 +20,7 @@ void App::Initialize() { Finalize(); - my_Window.Initialize(L"GLTSF", Video_Mode(Width, Height, Bits_Per_Pixel), Fullscreen); + 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(); @@ -57,6 +57,9 @@ void App::On_Key_Down(int Key) case VK_ESCAPE: On_Close(); break; + case VK_TAB: + my_Window.Get_IMM().Toggle(); + break; } } From 56aecc4828cabd3c92e419d7a38faf5fef2c844f Mon Sep 17 00:00:00 2001 From: dewyatt Date: Tue, 6 Jul 2010 02:00:15 -0400 Subject: [PATCH 15/30] Added mouse button click to toggle IMM. --- EXCLUDE/GLIMM/include/App.hpp | 3 ++- EXCLUDE/GLIMM/src/App.cpp | 13 ++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/EXCLUDE/GLIMM/include/App.hpp b/EXCLUDE/GLIMM/include/App.hpp index c7609fc37..5c9ff3efa 100644 --- a/EXCLUDE/GLIMM/include/App.hpp +++ b/EXCLUDE/GLIMM/include/App.hpp @@ -19,6 +19,7 @@ public: 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(); @@ -27,7 +28,7 @@ private: static const int Width = 800; static const int Height = 600; static const int Bits_Per_Pixel = 32; - static const bool Fullscreen = false; + static const bool Fullscreen = true; Window my_Window; bool my_Done; diff --git a/EXCLUDE/GLIMM/src/App.cpp b/EXCLUDE/GLIMM/src/App.cpp index e3da11c45..393ac5b88 100644 --- a/EXCLUDE/GLIMM/src/App.cpp +++ b/EXCLUDE/GLIMM/src/App.cpp @@ -57,9 +57,6 @@ void App::On_Key_Down(int Key) case VK_ESCAPE: On_Close(); break; - case VK_TAB: - my_Window.Get_IMM().Toggle(); - break; } } @@ -83,6 +80,16 @@ void App::On_Resized(unsigned int Width, unsigned int Height) 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; From bfba97da7f3f1cc46956552a504002c34651b681 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Tue, 6 Jul 2010 02:06:17 -0400 Subject: [PATCH 16/30] Many changes, preparing to pull/merge main repo to get SDL_GetKeyboardFocus. --- EXCLUDE/GLIMM/include/IMM.hpp | 11 +++ EXCLUDE/GLIMM/include/Window_Listener.hpp | 9 +++ EXCLUDE/GLIMM/src/IMM.cpp | 96 ++++++++++++++++++++--- EXCLUDE/GLIMM/src/Window.cpp | 13 +++ 4 files changed, 117 insertions(+), 12 deletions(-) diff --git a/EXCLUDE/GLIMM/include/IMM.hpp b/EXCLUDE/GLIMM/include/IMM.hpp index ae2dfb813..45be3d61f 100644 --- a/EXCLUDE/GLIMM/include/IMM.hpp +++ b/EXCLUDE/GLIMM/include/IMM.hpp @@ -16,8 +16,18 @@ public: 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; @@ -25,6 +35,7 @@ private: HIMC my_Context; HKL my_HKL; bool my_Vertical_Candidates; + bool my_Enabled; }; #endif diff --git a/EXCLUDE/GLIMM/include/Window_Listener.hpp b/EXCLUDE/GLIMM/include/Window_Listener.hpp index a5a96e731..206dd50ba 100644 --- a/EXCLUDE/GLIMM/include/Window_Listener.hpp +++ b/EXCLUDE/GLIMM/include/Window_Listener.hpp @@ -1,6 +1,12 @@ #ifndef WINDOW_LISTENER_HPP #define WINDOW_LISTENER_HPP +enum Mouse_Button +{ + Mouse_Button_Left, + Mouse_Button_Right +}; + class Window_Listener { public: @@ -9,6 +15,9 @@ public: 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 diff --git a/EXCLUDE/GLIMM/src/IMM.cpp b/EXCLUDE/GLIMM/src/IMM.cpp index 0ef3fdc93..c949ae4a5 100644 --- a/EXCLUDE/GLIMM/src/IMM.cpp +++ b/EXCLUDE/GLIMM/src/IMM.cpp @@ -6,7 +6,8 @@ IMM::IMM() : my_COM_Initialized(false), my_Window(0), my_Context(0), my_HKL(0), - my_Vertical_Candidates(false) + my_Vertical_Candidates(false), + my_Enabled(false) { } @@ -28,11 +29,13 @@ void IMM::Initialize(HWND Window) if (SUCCEEDED(CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, reinterpret_cast(&my_Thread_Manager)))) { ITfDocumentMgr *Document_Manager = 0; - if (FAILED(my_Thread_Manager->AssociateFocus(Window, NULL, &Document_Manager))) + if (SUCCEEDED(my_Thread_Manager->AssociateFocus(Window, NULL, &Document_Manager))) + { + if (Document_Manager) + Document_Manager->Release(); + } + else printf("Warning: ITfThreadMgr->AssociateFocus failed\n"); - - if (Document_Manager) - Document_Manager->Release(); } else printf("Warning: Failed to create ITfThreadMgr instance\n"); @@ -40,16 +43,16 @@ void IMM::Initialize(HWND Window) else printf("Warning: Failed to initialize COM\n"); - ImmDisableTextFrameService(-1); + ImmDisableTextFrameService((DWORD)-1); my_Context = ImmGetContext(my_Window); - if (!ImmReleaseContext(my_Window, my_Context)) - throw std::runtime_error("Error releasing context"); - + ImmReleaseContext(my_Window, my_Context); if (!my_Context) - throw std::runtime_error("No context"); + throw std::runtime_error("No context (No IME installed?)"); Update_Input_Locale(); + Cancel_Composition(); + Disable(); } void IMM::Finalize() @@ -102,11 +105,10 @@ LRESULT IMM::Handle_Message(HWND Window, UINT Message, WPARAM wParam, LPARAM lPa switch (Message) { case WM_INPUTLANGCHANGE: - Update_Input_Locale(); + Input_Language_Changed(); break; case WM_IME_SETCONTEXT: lParam = 0; - return DefWindowProcW(my_Window, Message, wParam, lParam); break; case WM_IME_STARTCOMPOSITION: Ate = true; @@ -158,8 +160,78 @@ LRESULT IMM::Handle_Message(HWND Window, UINT Message, WPARAM wParam, LPARAM lPa 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); + } +} diff --git a/EXCLUDE/GLIMM/src/Window.cpp b/EXCLUDE/GLIMM/src/Window.cpp index dc00303e9..eb59121ab 100644 --- a/EXCLUDE/GLIMM/src/Window.cpp +++ b/EXCLUDE/GLIMM/src/Window.cpp @@ -31,6 +31,7 @@ void Window::Initialize(const std::wstring &Title, const Video_Mode &Mode, bool my_Fullscreen = Fullscreen; Register_Class(); Create_Window(Title, Mode, Fullscreen); + Show(); my_IMM.Initialize(my_Handle); } @@ -296,6 +297,18 @@ LRESULT Window::Handle_Message(HWND Handle, UINT Message, WPARAM wParam, LPARAM 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; From a9eb1670a17c900bd1b4547c27ff67bf61290b1b Mon Sep 17 00:00:00 2001 From: dewyatt Date: Tue, 6 Jul 2010 02:34:49 -0400 Subject: [PATCH 17/30] Added empty text input functions for win32. --- src/video/win32/SDL_win32keyboard.c | 19 +++++++++++++++++++ src/video/win32/SDL_win32keyboard.h | 4 ++++ src/video/win32/SDL_win32video.c | 3 +++ 3 files changed, 26 insertions(+) diff --git a/src/video/win32/SDL_win32keyboard.c b/src/video/win32/SDL_win32keyboard.c index fb4e0ff41..6f0cc410d 100644 --- a/src/video/win32/SDL_win32keyboard.c +++ b/src/video/win32/SDL_win32keyboard.c @@ -122,4 +122,23 @@ WIN_QuitKeyboard(_THIS) { } +void +WIN_StartTextInput(_THIS) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + +} + +void +WIN_StopTextInput(_THIS) +{ + +} + +void +WIN_SetTextInputRect(_THIS, SDL_Rect *rect) +{ + +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/win32/SDL_win32keyboard.h b/src/video/win32/SDL_win32keyboard.h index c67410a63..76894931e 100644 --- a/src/video/win32/SDL_win32keyboard.h +++ b/src/video/win32/SDL_win32keyboard.h @@ -31,6 +31,10 @@ 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); + #endif /* _SDL_win32keyboard_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/win32/SDL_win32video.c b/src/video/win32/SDL_win32video.c index c93d4f72e..40b5a3b72 100644 --- a/src/video/win32/SDL_win32video.c +++ b/src/video/win32/SDL_win32video.c @@ -162,6 +162,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_StartTextInput; + device->SetTextInputRect = WIN_SetTextInputRect; device->free = WIN_DeleteDevice; From 9fad608a86b2c336e0394654bf13ed47959beb9d Mon Sep 17 00:00:00 2001 From: dewyatt Date: Tue, 6 Jul 2010 03:27:22 -0400 Subject: [PATCH 18/30] Added missing line to make things compile. --- src/video/win32/SDL_win32keyboard.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/video/win32/SDL_win32keyboard.c b/src/video/win32/SDL_win32keyboard.c index 6f0cc410d..cbb760d0d 100644 --- a/src/video/win32/SDL_win32keyboard.c +++ b/src/video/win32/SDL_win32keyboard.c @@ -125,7 +125,8 @@ WIN_QuitKeyboard(_THIS) void WIN_StartTextInput(_THIS) { - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + SDL_Window *window = SDL_GetKeyboardFocus(); + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; } From 9807496e302975181a487b2f3dc38a10feabe8ba Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 6 Jul 2010 08:22:36 -0700 Subject: [PATCH 19/30] Fixed fullscreen window position Fixed position calculation for centered windows --- src/video/win32/SDL_win32window.c | 33 +++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/video/win32/SDL_win32window.c b/src/video/win32/SDL_win32window.c index b3e4c3171..79e04d71d 100644 --- a/src/video/win32/SDL_win32window.c +++ b/src/video/win32/SDL_win32window.c @@ -186,7 +186,6 @@ WIN_CreateWindow(_THIS, SDL_Window * window) { SDL_VideoDisplay *display = window->display; HWND hwnd; - HWND top; RECT rect; SDL_Rect bounds; DWORD style = (WS_CLIPSIBLINGS | WS_CLIPCHILDREN); @@ -204,11 +203,6 @@ WIN_CreateWindow(_THIS, SDL_Window * window) } /* Figure out what the window area will be */ - if (window->flags & SDL_WINDOW_FULLSCREEN) { - top = HWND_TOPMOST; - } else { - top = HWND_NOTOPMOST; - } rect.left = 0; rect.top = 0; rect.right = window->w; @@ -218,9 +212,17 @@ WIN_CreateWindow(_THIS, SDL_Window * window) h = (rect.bottom - rect.top); WIN_GetDisplayBounds(_this, display, &bounds); + if (window->flags & SDL_WINDOW_FULLSCREEN) { + /* The bounds when this window is visible is the fullscreen mode */ + SDL_DisplayMode fullscreen_mode; + if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) { + bounds.w = fullscreen_mode.w; + bounds.h = fullscreen_mode.h; + } + } if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->x == SDL_WINDOWPOS_CENTERED) { - x = bounds.x + (bounds.w - window->w) / 2; + x = bounds.x + (bounds.w - w) / 2; } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { if (bounds.x == 0) { x = CW_USEDEFAULT; @@ -232,7 +234,7 @@ WIN_CreateWindow(_THIS, SDL_Window * window) } if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->y == SDL_WINDOWPOS_CENTERED) { - y = bounds.y + (bounds.h - window->h) / 2; + y = bounds.y + (bounds.h - h) / 2; } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { if (bounds.x == 0) { y = CW_USEDEFAULT; @@ -389,6 +391,7 @@ WIN_SetWindowPosition(_THIS, SDL_Window * window) HWND top; BOOL menu; int x, y; + int w, h; /* Figure out what the window area will be */ if (window->flags & SDL_WINDOW_FULLSCREEN) { @@ -407,17 +410,27 @@ WIN_SetWindowPosition(_THIS, SDL_Window * window) menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); #endif AdjustWindowRectEx(&rect, style, menu, 0); + w = (rect.right - rect.left); + h = (rect.bottom - rect.top); WIN_GetDisplayBounds(_this, display, &bounds); + if (window->flags & SDL_WINDOW_FULLSCREEN) { + /* The bounds when this window is visible is the fullscreen mode */ + SDL_DisplayMode fullscreen_mode; + if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) { + bounds.w = fullscreen_mode.w; + bounds.h = fullscreen_mode.h; + } + } if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->x == SDL_WINDOWPOS_CENTERED) { - x = bounds.x + (bounds.w - window->w) / 2; + x = bounds.x + (bounds.w - w) / 2; } else { x = bounds.x + window->x + rect.left; } if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->y == SDL_WINDOWPOS_CENTERED) { - y = bounds.y + (bounds.h - window->h) / 2; + y = bounds.y + (bounds.h - h) / 2; } else { y = bounds.y + window->y + rect.top; } From 2beaeb40800765d3b379223d98165f0e9e6234ee Mon Sep 17 00:00:00 2001 From: dewyatt Date: Thu, 8 Jul 2010 01:35:47 -0400 Subject: [PATCH 20/30] Changed StartTextInput to take an SDL_Window parameter. --- include/SDL_keyboard.h | 2 +- src/SDL_compat.c | 2 +- src/events/SDL_keyboard.c | 2 +- src/video/SDL_sysvideo.h | 2 +- src/video/SDL_video.c | 4 ++-- src/video/win32/SDL_win32keyboard.c | 3 +-- src/video/win32/SDL_win32keyboard.h | 2 +- src/video/win32/SDL_win32video.c | 2 +- 8 files changed, 9 insertions(+), 10 deletions(-) diff --git a/include/SDL_keyboard.h b/include/SDL_keyboard.h index 4482ac028..fca34506f 100644 --- a/include/SDL_keyboard.h +++ b/include/SDL_keyboard.h @@ -140,7 +140,7 @@ extern DECLSPEC const char *SDLCALL SDL_GetKeyName(SDLKey key); * \sa SDL_StopTextInput() * \sa SDL_SetTextInputRect() */ -extern DECLSPEC void SDLCALL SDL_StartTextInput(void); +extern DECLSPEC void SDLCALL SDL_StartTextInput(SDL_Window *window); /** * \brief Stop receiving any text input events. diff --git a/src/SDL_compat.c b/src/SDL_compat.c index bb8e46ba8..51b9b5ceb 100644 --- a/src/SDL_compat.c +++ b/src/SDL_compat.c @@ -1740,7 +1740,7 @@ SDL_EnableUNICODE(int enable) switch (enable) { case 1: SDL_enabled_UNICODE = 1; - SDL_StartTextInput(); + SDL_StartTextInput(SDL_VideoWindow); break; case 0: SDL_enabled_UNICODE = 0; diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index f25bc6af8..5de1116e3 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -617,7 +617,7 @@ SDL_SetKeyboardFocus(SDL_Window * window) 0, 0); if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { - SDL_StartTextInput(); + SDL_StartTextInput(window); } } } diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 0a82717ec..69ecb440d 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -299,7 +299,7 @@ struct SDL_VideoDevice void (*SuspendScreenSaver) (_THIS); /* Text input */ - void (*StartTextInput) (_THIS); + void (*StartTextInput) (_THIS, SDL_Window *window); void (*StopTextInput) (_THIS); void (*SetTextInputRect) (_THIS, SDL_Rect *rect); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index db8b5d3cb..744defea4 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -3385,10 +3385,10 @@ SDL_GetWindowWMInfo(SDL_Window * window, struct SDL_SysWMinfo *info) } void -SDL_StartTextInput(void) +SDL_StartTextInput(SDL_Window *window) { if (_this && _this->StartTextInput) { - _this->StartTextInput(_this); + _this->StartTextInput(_this, window); } SDL_EventState(SDL_TEXTINPUT, SDL_ENABLE); SDL_EventState(SDL_TEXTEDITING, SDL_ENABLE); diff --git a/src/video/win32/SDL_win32keyboard.c b/src/video/win32/SDL_win32keyboard.c index cbb760d0d..4ee297be7 100644 --- a/src/video/win32/SDL_win32keyboard.c +++ b/src/video/win32/SDL_win32keyboard.c @@ -123,9 +123,8 @@ WIN_QuitKeyboard(_THIS) } void -WIN_StartTextInput(_THIS) +WIN_StartTextInput(_THIS, SDL_Window *window) { - SDL_Window *window = SDL_GetKeyboardFocus(); HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; } diff --git a/src/video/win32/SDL_win32keyboard.h b/src/video/win32/SDL_win32keyboard.h index 76894931e..d9e54b3bd 100644 --- a/src/video/win32/SDL_win32keyboard.h +++ b/src/video/win32/SDL_win32keyboard.h @@ -31,7 +31,7 @@ extern void WIN_InitKeyboard(_THIS); extern void WIN_UpdateKeymap(void); extern void WIN_QuitKeyboard(_THIS); -extern void WIN_StartTextInput(_THIS); +extern void WIN_StartTextInput(_THIS, SDL_Window *window); extern void WIN_StopTextInput(_THIS); extern void WIN_SetTextInputRect(_THIS, SDL_Rect *rect); diff --git a/src/video/win32/SDL_win32video.c b/src/video/win32/SDL_win32video.c index 40b5a3b72..b169bd959 100644 --- a/src/video/win32/SDL_win32video.c +++ b/src/video/win32/SDL_win32video.c @@ -163,7 +163,7 @@ WIN_CreateDevice(int devindex) device->GL_DeleteContext = WIN_GL_DeleteContext; #endif device->StartTextInput = WIN_StartTextInput; - device->StopTextInput = WIN_StartTextInput; + device->StopTextInput = WIN_StopTextInput; device->SetTextInputRect = WIN_SetTextInputRect; device->free = WIN_DeleteDevice; From 2f1a5c4653578559b5f76ae79444991f71f9ccd2 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Sat, 10 Jul 2010 13:15:47 -0400 Subject: [PATCH 21/30] Changed StopTextInput to take an SDL_Window parameter. --- include/SDL_keyboard.h | 2 +- src/SDL_compat.c | 2 +- src/video/SDL_sysvideo.h | 2 +- src/video/SDL_video.c | 4 ++-- src/video/win32/SDL_win32keyboard.c | 2 +- src/video/win32/SDL_win32keyboard.h | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/SDL_keyboard.h b/include/SDL_keyboard.h index fca34506f..cccafd001 100644 --- a/include/SDL_keyboard.h +++ b/include/SDL_keyboard.h @@ -147,7 +147,7 @@ extern DECLSPEC void SDLCALL SDL_StartTextInput(SDL_Window *window); * * \sa SDL_StartTextInput() */ -extern DECLSPEC void SDLCALL SDL_StopTextInput(void); +extern DECLSPEC void SDLCALL SDL_StopTextInput(SDL_Window *window); /** * \brief Set the rectangle used to type Unicode text inputs. diff --git a/src/SDL_compat.c b/src/SDL_compat.c index 51b9b5ceb..112510598 100644 --- a/src/SDL_compat.c +++ b/src/SDL_compat.c @@ -1744,7 +1744,7 @@ SDL_EnableUNICODE(int enable) break; case 0: SDL_enabled_UNICODE = 0; - SDL_StopTextInput(); + SDL_StopTextInput(SDL_VideoWindow); break; } return previous; diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 69ecb440d..7d93428f1 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -300,7 +300,7 @@ struct SDL_VideoDevice /* Text input */ void (*StartTextInput) (_THIS, SDL_Window *window); - void (*StopTextInput) (_THIS); + void (*StopTextInput) (_THIS, SDL_Window *window); void (*SetTextInputRect) (_THIS, SDL_Rect *rect); /* * * */ diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 744defea4..8e10ede43 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -3395,10 +3395,10 @@ SDL_StartTextInput(SDL_Window *window) } void -SDL_StopTextInput(void) +SDL_StopTextInput(SDL_Window *window) { if (_this && _this->StopTextInput) { - _this->StopTextInput(_this); + _this->StopTextInput(_this, window); } SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE); SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE); diff --git a/src/video/win32/SDL_win32keyboard.c b/src/video/win32/SDL_win32keyboard.c index 4ee297be7..3f2c4055f 100644 --- a/src/video/win32/SDL_win32keyboard.c +++ b/src/video/win32/SDL_win32keyboard.c @@ -130,7 +130,7 @@ WIN_StartTextInput(_THIS, SDL_Window *window) } void -WIN_StopTextInput(_THIS) +WIN_StopTextInput(_THIS, SDL_Window *window) { } diff --git a/src/video/win32/SDL_win32keyboard.h b/src/video/win32/SDL_win32keyboard.h index d9e54b3bd..dd3b3610d 100644 --- a/src/video/win32/SDL_win32keyboard.h +++ b/src/video/win32/SDL_win32keyboard.h @@ -32,7 +32,7 @@ extern void WIN_UpdateKeymap(void); extern void WIN_QuitKeyboard(_THIS); extern void WIN_StartTextInput(_THIS, SDL_Window *window); -extern void WIN_StopTextInput(_THIS); +extern void WIN_StopTextInput(_THIS, SDL_Window *window); extern void WIN_SetTextInputRect(_THIS, SDL_Rect *rect); #endif /* _SDL_win32keyboard_h */ From 3d5a6d8597552ef30b1a82646725f93675e77197 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Mon, 12 Jul 2010 11:33:27 -0400 Subject: [PATCH 22/30] Initial IMM implementation. IME input should now work fairly well. --- src/video/win32/SDL_win32events.c | 2 + src/video/win32/SDL_win32keyboard.c | 186 +++++++++++++++++++++++++++- src/video/win32/SDL_win32keyboard.h | 2 + src/video/win32/SDL_win32video.h | 10 ++ 4 files changed, 197 insertions(+), 3 deletions(-) diff --git a/src/video/win32/SDL_win32events.c b/src/video/win32/SDL_win32events.c index 185acc1f6..acbb0b497 100644 --- a/src/video/win32/SDL_win32events.c +++ b/src/video/win32/SDL_win32events.c @@ -131,6 +131,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) { diff --git a/src/video/win32/SDL_win32keyboard.c b/src/video/win32/SDL_win32keyboard.c index 3f2c4055f..c5de9dcc0 100644 --- a/src/video/win32/SDL_win32keyboard.c +++ b/src/video/win32/SDL_win32keyboard.c @@ -26,6 +26,9 @@ #include "../../events/SDL_keyboard_c.h" #include "../../events/scancodes_win32.h" +#include +#include + #ifndef MAPVK_VK_TO_VSC #define MAPVK_VK_TO_VSC 0 #endif @@ -46,6 +49,11 @@ BYTE keypad_scancodes[10] = { 82, 79, 80, 81, 75, 76, 77, 71, 72, 73 }; +void IME_Disable(SDL_VideoData *videodata, HWND hwnd); +void IME_Enable(SDL_VideoData *videodata, HWND hwnd); +void IME_Init(SDL_VideoData *videodata, HWND hwnd); +void IME_Quit(SDL_VideoData *videodata); + void WIN_InitKeyboard(_THIS) { @@ -81,6 +89,15 @@ WIN_InitKeyboard(_THIS) data->key_layout = win32_scancode_table; + data->ime_com_initialized = SDL_FALSE; + data->ime_thread_mgr = 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; + WIN_UpdateKeymap(); SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu"); @@ -120,19 +137,25 @@ WIN_UpdateKeymap() void WIN_QuitKeyboard(_THIS) { + IME_Quit((SDL_VideoData *)_this->driverdata); } void WIN_StartTextInput(_THIS, SDL_Window *window) { - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - + 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) { - + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + IME_Init(videodata, hwnd); + IME_Disable(videodata, hwnd); } void @@ -141,4 +164,161 @@ WIN_SetTextInputRect(_THIS, SDL_Rect *rect) } +void +IME_Disable(SDL_VideoData *videodata, HWND hwnd) +{ + if (!videodata->ime_initialized || !videodata->ime_hwnd_current) + return; + + if (videodata->ime_hwnd_current == videodata->ime_hwnd_main) + ImmAssociateContext(videodata->ime_hwnd_current, NULL); + + videodata->ime_enabled = SDL_FALSE; +} + +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; +} + +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_thread_mgr); + } + videodata->ime_initialized = SDL_TRUE; + videodata->ime_hwnd_current = videodata->ime_hwnd_main; + if (videodata->ime_thread_mgr) { + struct ITfDocumentMgr *document_mgr = 0; + if (SUCCEEDED(videodata->ime_thread_mgr->lpVtbl->AssociateFocus(videodata->ime_thread_mgr, hwnd, NULL, &document_mgr))) { + if (document_mgr) + document_mgr->lpVtbl->Release(document_mgr); + } + } + 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_Disable(videodata, hwnd); +} + +void +IME_Quit(SDL_VideoData *videodata) +{ + if (!videodata->ime_initialized) + return; + + 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_thread_mgr) + { + videodata->ime_thread_mgr->lpVtbl->Release(videodata->ime_thread_mgr); + videodata->ime_thread_mgr = 0; + } + if (videodata->ime_com_initialized) + { + CoUninitialize(); + videodata->ime_com_initialized = SDL_FALSE; + } + videodata->ime_initialized = SDL_FALSE; +} + +SDL_bool +IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata) +{ + SDL_bool trap = SDL_FALSE; + HIMC himc = 0; + WCHAR Buffer[SDL_TEXTINPUTEVENT_TEXT_SIZE / 2]; + if (!videodata->ime_initialized || !videodata->ime_available || !videodata->ime_enabled) + return SDL_FALSE; + + switch (msg) + { + case WM_INPUTLANGCHANGE: + 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) + { + LONG Length = 0; + char *s = 0; + Length = ImmGetCompositionStringW(himc, GCS_RESULTSTR, Buffer, sizeof(Buffer) * sizeof(Buffer[0])); + Buffer[Length / sizeof(Buffer[0])] = 0; + s = WIN_StringToUTF8(Buffer); + SDL_SendKeyboardText(s); + SDL_free(s); + } + if (*lParam & GCS_COMPSTR) + { + LONG Length = 0; + DWORD Cursor = 0; + char *s = 0; + Length = ImmGetCompositionStringW(himc, GCS_COMPSTR, Buffer, sizeof(Buffer) * sizeof(Buffer[0])); + Buffer[Length / sizeof(Buffer[0])] = 0; + s = WIN_StringToUTF8(Buffer); + Cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0)); + SDL_SendEditingText(s, Cursor, 0); + SDL_free(s); + } + ImmReleaseContext(hwnd, himc); + break; + case WM_IME_ENDCOMPOSITION: + SDL_SendKeyboardText(""); + break; + case WM_IME_NOTIFY: + switch (wParam) + { + case IMN_SETCONVERSIONMODE: + break; + case IMN_SETOPENSTATUS: + break; + case IMN_OPENCANDIDATE: + case IMN_CHANGECANDIDATE: + trap = SDL_TRUE; + break; + case IMN_CLOSECANDIDATE: + trap = SDL_TRUE; + break; + case IMN_PRIVATE: + break; + default: + trap = SDL_TRUE; + break; + } + break; + } + return trap; +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/win32/SDL_win32keyboard.h b/src/video/win32/SDL_win32keyboard.h index dd3b3610d..b2acc0165 100644 --- a/src/video/win32/SDL_win32keyboard.h +++ b/src/video/win32/SDL_win32keyboard.h @@ -35,6 +35,8 @@ extern void WIN_StartTextInput(_THIS, SDL_Window *window); extern void WIN_StopTextInput(_THIS, SDL_Window *window); 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: */ diff --git a/src/video/win32/SDL_win32video.h b/src/video/win32/SDL_win32video.h index 3cfb63219..4d427f0cb 100644 --- a/src/video/win32/SDL_win32video.h +++ b/src/video/win32/SDL_win32video.h @@ -75,6 +75,16 @@ typedef struct SDL_VideoData #endif const SDL_scancode *key_layout; + + SDL_bool ime_com_initialized; + struct ITfThreadMgr *ime_thread_mgr; + SDL_bool ime_initialized; + SDL_bool ime_enabled; + SDL_bool ime_available; + HWND ime_hwnd_main; + HWND ime_hwnd_current; + HIMC ime_himc; + } SDL_VideoData; #endif /* _SDL_win32video_h */ From 7e8c791089cd7d284ed14e7668338700b491b58e Mon Sep 17 00:00:00 2001 From: dewyatt Date: Mon, 12 Jul 2010 14:17:43 -0400 Subject: [PATCH 23/30] Changed Start/StopTextInput back to not take any parameters. We call SDL_GetKeyboardFocus internally now. --- include/SDL_keyboard.h | 4 ++-- src/SDL_compat.c | 4 ++-- src/events/SDL_keyboard.c | 2 +- src/video/SDL_sysvideo.h | 4 ++-- src/video/SDL_video.c | 8 ++++---- src/video/win32/SDL_win32keyboard.c | 28 ++++++++++++++++++---------- src/video/win32/SDL_win32keyboard.h | 4 ++-- 7 files changed, 31 insertions(+), 23 deletions(-) diff --git a/include/SDL_keyboard.h b/include/SDL_keyboard.h index cccafd001..4482ac028 100644 --- a/include/SDL_keyboard.h +++ b/include/SDL_keyboard.h @@ -140,14 +140,14 @@ extern DECLSPEC const char *SDLCALL SDL_GetKeyName(SDLKey key); * \sa SDL_StopTextInput() * \sa SDL_SetTextInputRect() */ -extern DECLSPEC void SDLCALL SDL_StartTextInput(SDL_Window *window); +extern DECLSPEC void SDLCALL SDL_StartTextInput(void); /** * \brief Stop receiving any text input events. * * \sa SDL_StartTextInput() */ -extern DECLSPEC void SDLCALL SDL_StopTextInput(SDL_Window *window); +extern DECLSPEC void SDLCALL SDL_StopTextInput(void); /** * \brief Set the rectangle used to type Unicode text inputs. diff --git a/src/SDL_compat.c b/src/SDL_compat.c index 112510598..bb8e46ba8 100644 --- a/src/SDL_compat.c +++ b/src/SDL_compat.c @@ -1740,11 +1740,11 @@ SDL_EnableUNICODE(int enable) switch (enable) { case 1: SDL_enabled_UNICODE = 1; - SDL_StartTextInput(SDL_VideoWindow); + SDL_StartTextInput(); break; case 0: SDL_enabled_UNICODE = 0; - SDL_StopTextInput(SDL_VideoWindow); + SDL_StopTextInput(); break; } return previous; diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index 5de1116e3..f25bc6af8 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -617,7 +617,7 @@ SDL_SetKeyboardFocus(SDL_Window * window) 0, 0); if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { - SDL_StartTextInput(window); + SDL_StartTextInput(); } } } diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 7d93428f1..0a82717ec 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -299,8 +299,8 @@ struct SDL_VideoDevice void (*SuspendScreenSaver) (_THIS); /* Text input */ - void (*StartTextInput) (_THIS, SDL_Window *window); - void (*StopTextInput) (_THIS, SDL_Window *window); + void (*StartTextInput) (_THIS); + void (*StopTextInput) (_THIS); void (*SetTextInputRect) (_THIS, SDL_Rect *rect); /* * * */ diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 8e10ede43..db8b5d3cb 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -3385,20 +3385,20 @@ SDL_GetWindowWMInfo(SDL_Window * window, struct SDL_SysWMinfo *info) } void -SDL_StartTextInput(SDL_Window *window) +SDL_StartTextInput(void) { if (_this && _this->StartTextInput) { - _this->StartTextInput(_this, window); + _this->StartTextInput(_this); } SDL_EventState(SDL_TEXTINPUT, SDL_ENABLE); SDL_EventState(SDL_TEXTEDITING, SDL_ENABLE); } void -SDL_StopTextInput(SDL_Window *window) +SDL_StopTextInput(void) { if (_this && _this->StopTextInput) { - _this->StopTextInput(_this, window); + _this->StopTextInput(_this); } SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE); SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE); diff --git a/src/video/win32/SDL_win32keyboard.c b/src/video/win32/SDL_win32keyboard.c index c5de9dcc0..23caa2d28 100644 --- a/src/video/win32/SDL_win32keyboard.c +++ b/src/video/win32/SDL_win32keyboard.c @@ -141,21 +141,29 @@ WIN_QuitKeyboard(_THIS) } void -WIN_StartTextInput(_THIS, SDL_Window *window) +WIN_StartTextInput(_THIS) { - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; - IME_Init(videodata, hwnd); - IME_Enable(videodata, hwnd); + 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) +WIN_StopTextInput(_THIS) { - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; - IME_Init(videodata, hwnd); - IME_Disable(videodata, hwnd); + 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 diff --git a/src/video/win32/SDL_win32keyboard.h b/src/video/win32/SDL_win32keyboard.h index b2acc0165..670730bba 100644 --- a/src/video/win32/SDL_win32keyboard.h +++ b/src/video/win32/SDL_win32keyboard.h @@ -31,8 +31,8 @@ extern void WIN_InitKeyboard(_THIS); extern void WIN_UpdateKeymap(void); extern void WIN_QuitKeyboard(_THIS); -extern void WIN_StartTextInput(_THIS, SDL_Window *window); -extern void WIN_StopTextInput(_THIS, SDL_Window *window); +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); From 34d5cdc704ce4bd590bf61a8424ee224a8ebe9d4 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Tue, 13 Jul 2010 15:05:45 -0400 Subject: [PATCH 24/30] Added SDL_utf8strlcpy to copy at UTF-8 character boundaries. Changed SDL_SendKeyboardText and SDL_SendEditingText to use SDL_utf8strlcpy. --- include/SDL_stdinc.h | 3 +++ src/events/SDL_keyboard.c | 4 ++-- src/stdlib/SDL_string.c | 47 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index c7e7edd57..fb143acb5 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -470,6 +470,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 diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index f25bc6af8..f56075eaa 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -766,7 +766,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); } @@ -787,7 +787,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); diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index d70f8666a..b6839c1cf 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -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) @@ -362,6 +377,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) From 1d79a9b5d824510e03216796a98472a57ca35762 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Sat, 24 Jul 2010 20:48:50 -0400 Subject: [PATCH 25/30] Changed markedText to have its own storage to resolve multiple bugs. Changed an odd strcpy to a more appropriate strcat. --- test/testime.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/testime.c b/test/testime.c index 6975d652d..874931609 100644 --- a/test/testime.c +++ b/test/testime.c @@ -25,7 +25,7 @@ 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]; void usage() { @@ -124,7 +124,7 @@ void InitInput() text[0] = 0; markedRect = textRect; - markedText = NULL; + markedText[0] = 0; SDL_StartTextInput(); } @@ -178,7 +178,7 @@ void Redraw() cursorRect.h = h; SDL_FillRect(screen, &markedRect, backColor); - if (markedText) + if (markedText[0]) { #ifdef HAVE_SDL_TTF RenderText(screen, font, markedText, markedRect.x, markedRect.y, textColor); @@ -293,13 +293,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)) - strcpy(text + SDL_strlen(text), event.text.text); + strcat(text, event.text.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; @@ -307,7 +307,7 @@ 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); Redraw(); break; From cae6f1376daa7e0e2fdc99e25b5541379ea084b7 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Sun, 25 Jul 2010 13:17:31 -0400 Subject: [PATCH 26/30] Correctly draw cursor based on position. Had to add UTF-8 functions utf8_length, utf8_next, utf8_advance. --- test/testime.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/test/testime.c b/test/testime.c index 874931609..4d207985e 100644 --- a/test/testime.c +++ b/test/testime.c @@ -26,6 +26,48 @@ SDL_Rect textRect, markedRect; Uint32 lineColor, backColor; SDL_Color textColor = { 0, 0, 0 }; 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() { @@ -181,6 +223,19 @@ void Redraw() 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 @@ -190,8 +245,6 @@ void Redraw() underlineRect.h = 2; underlineRect.w = w; - cursorRect.x += w + 1; - SDL_FillRect(screen, &underlineRect, lineColor); } @@ -308,6 +361,7 @@ int main(int argc, char *argv[]) event.edit.text, event.edit.start, event.edit.length); strcpy(markedText, event.edit.text); + cursor = event.edit.start; Redraw(); break; From 12881b428cf97a716cc8b8fce3b4b609e190e834 Mon Sep 17 00:00:00 2001 From: dewyatt Date: Tue, 3 Aug 2010 16:52:10 -0400 Subject: [PATCH 27/30] Added SDL_wcslcpy and SDL_wcslcat. --- include/SDL_stdinc.h | 13 +++++++++++++ src/stdlib/SDL_string.c | 27 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index be201bb7e..a2d9ce48a 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -470,6 +470,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 diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index b6839c1cf..02f086773 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -363,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) From aa7b525b35feab3a07f5ab59870f1bfa515d779e Mon Sep 17 00:00:00 2001 From: dewyatt Date: Tue, 3 Aug 2010 16:57:49 -0400 Subject: [PATCH 28/30] Large commit with initial reading string support, TSF UILess code, etc. --- src/video/win32/SDL_win32keyboard.c | 866 +++++++++++++++++++++++++--- src/video/win32/SDL_win32video.h | 245 +++++--- 2 files changed, 949 insertions(+), 162 deletions(-) diff --git a/src/video/win32/SDL_win32keyboard.c b/src/video/win32/SDL_win32keyboard.c index 23caa2d28..d2fe416e9 100644 --- a/src/video/win32/SDL_win32keyboard.c +++ b/src/video/win32/SDL_win32keyboard.c @@ -26,8 +26,13 @@ #include "../../events/SDL_keyboard_c.h" #include "../../events/scancodes_win32.h" -#include #include +#include + +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 @@ -49,11 +54,6 @@ BYTE keypad_scancodes[10] = { 82, 79, 80, 81, 75, 76, 77, 71, 72, 73 }; -void IME_Disable(SDL_VideoData *videodata, HWND hwnd); -void IME_Enable(SDL_VideoData *videodata, HWND hwnd); -void IME_Init(SDL_VideoData *videodata, HWND hwnd); -void IME_Quit(SDL_VideoData *videodata); - void WIN_InitKeyboard(_THIS) { @@ -90,13 +90,32 @@ WIN_InitKeyboard(_THIS) data->key_layout = win32_scancode_table; data->ime_com_initialized = SDL_FALSE; - data->ime_thread_mgr = 0; + 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(); @@ -144,8 +163,7 @@ void WIN_StartTextInput(_THIS) { SDL_Window *window = SDL_GetKeyboardFocus(); - if (window) - { + if (window) { HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; IME_Init(videodata, hwnd); @@ -157,8 +175,7 @@ void WIN_StopTextInput(_THIS) { SDL_Window *window = SDL_GetKeyboardFocus(); - if (window) - { + if (window) { HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; IME_Init(videodata, hwnd); @@ -172,19 +189,94 @@ WIN_SetTextInputRect(_THIS, SDL_Rect *rect) } -void -IME_Disable(SDL_VideoData *videodata, HWND hwnd) +#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 || !videodata->ime_hwnd_current) + if (videodata->ime_initialized) return; - if (videodata->ime_hwnd_current == videodata->ime_hwnd_main) - ImmAssociateContext(videodata->ime_hwnd_current, NULL); + 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"); - videodata->ime_enabled = SDL_FALSE; + 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); } -void +static void IME_Enable(SDL_VideoData *videodata, HWND hwnd) { if (!videodata->ime_initialized || !videodata->ime_hwnd_current) @@ -198,54 +290,45 @@ IME_Enable(SDL_VideoData *videodata, HWND hwnd) ImmAssociateContext(videodata->ime_hwnd_current, videodata->ime_himc); videodata->ime_enabled = SDL_TRUE; + IME_UpdateInputLocale(videodata); + UILess_EnableUIUpdates(videodata); } -void -IME_Init(SDL_VideoData *videodata, HWND hwnd) +static void +IME_Disable(SDL_VideoData *videodata, HWND hwnd) { - if (videodata->ime_initialized) + if (!videodata->ime_initialized || !videodata->ime_hwnd_current) 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_thread_mgr); - } - videodata->ime_initialized = SDL_TRUE; - videodata->ime_hwnd_current = videodata->ime_hwnd_main; - if (videodata->ime_thread_mgr) { - struct ITfDocumentMgr *document_mgr = 0; - if (SUCCEEDED(videodata->ime_thread_mgr->lpVtbl->AssociateFocus(videodata->ime_thread_mgr, hwnd, NULL, &document_mgr))) { - if (document_mgr) - document_mgr->lpVtbl->Release(document_mgr); - } - } - 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_Disable(videodata, hwnd); + 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); } -void +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_thread_mgr) + if (videodata->ime_himm32) { - videodata->ime_thread_mgr->lpVtbl->Release(videodata->ime_thread_mgr); - videodata->ime_thread_mgr = 0; + 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) { @@ -255,18 +338,384 @@ IME_Quit(SDL_VideoData *videodata) 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 uLang = PRIMLANG(); + HWND hwndime = 0; + IME_UpdateInputLocale(videodata); + IME_SetupAPI(videodata); + if (uLang != 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 hklPrevious = 0; + videodata->ime_hkl = GetKeyboardLayout(0); + if (hklPrevious == videodata->ime_hkl) + return; + + hklPrevious = 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 wBuffer[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; + wBuffer[0] = 0; + if (videodata->ime_readingstring[0]) + { + size_t len = SDL_min(SDL_wcslen(videodata->ime_composition), (size_t)videodata->ime_cursor); + SDL_wcslcpy(wBuffer, videodata->ime_composition, len + 1); + SDL_wcslcat(wBuffer, videodata->ime_readingstring, sizeof(wBuffer)); + SDL_wcslcat(wBuffer, &videodata->ime_composition[len], sizeof(wBuffer) - len); + } + else + { + SDL_wcslcpy(wBuffer, videodata->ime_composition, sizeof(videodata->ime_composition)); + } + s = WIN_StringToUTF8(wBuffer); + 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; - WCHAR Buffer[SDL_TEXTINPUTEVENT_TEXT_SIZE / 2]; 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; @@ -279,37 +728,31 @@ IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoD himc = ImmGetContext(hwnd); if (*lParam & GCS_RESULTSTR) { - LONG Length = 0; - char *s = 0; - Length = ImmGetCompositionStringW(himc, GCS_RESULTSTR, Buffer, sizeof(Buffer) * sizeof(Buffer[0])); - Buffer[Length / sizeof(Buffer[0])] = 0; - s = WIN_StringToUTF8(Buffer); - SDL_SendKeyboardText(s); - SDL_free(s); + IME_GetCompositionString(videodata, himc, GCS_RESULTSTR); + IME_SendInputEvent(videodata); } if (*lParam & GCS_COMPSTR) { - LONG Length = 0; - DWORD Cursor = 0; - char *s = 0; - Length = ImmGetCompositionStringW(himc, GCS_COMPSTR, Buffer, sizeof(Buffer) * sizeof(Buffer[0])); - Buffer[Length / sizeof(Buffer[0])] = 0; - s = WIN_StringToUTF8(Buffer); - Cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0)); - SDL_SendEditingText(s, Cursor, 0); - SDL_free(s); + 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: - SDL_SendKeyboardText(""); + 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: - break; case IMN_SETOPENSTATUS: + IME_UpdateInputLocale(videodata); break; case IMN_OPENCANDIDATE: case IMN_CHANGECANDIDATE: @@ -319,6 +762,34 @@ IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoD 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; @@ -329,4 +800,265 @@ IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoD 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 *pElement = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId); + ITfReadingInformationUIElement *preading = 0; + ITfCandidateListUIElement *pcandidates = 0; + SDL_VideoData *videodata = (SDL_VideoData *)sink->data; + if (!pElement) + return E_INVALIDARG; + + *pbShow = FALSE; + if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) + { + BSTR bstr; + if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) + { + WCHAR *s = (WCHAR *)bstr; + SysFreeString(bstr); + } + preading->lpVtbl->Release(preading); + } + else if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfCandidateListUIElement, (PVOID *)&pcandidates))) + { + pcandidates->lpVtbl->Release(pcandidates); + } + return S_OK; +} + +STDMETHODIMP UIElementSink_UpdateUIElement(TSFSink *sink, DWORD dwUIElementId) +{ + ITfUIElement *pElement = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId); + ITfReadingInformationUIElement *preading = 0; + ITfCandidateListUIElement *pcandidates = 0; + SDL_VideoData *videodata = (SDL_VideoData *)sink->data; + if (!pElement) + return E_INVALIDARG; + + if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &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); + } + else if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfCandidateListUIElement, (PVOID *)&pcandidates))) + { + pcandidates->lpVtbl->Release(pcandidates); + } + return S_OK; +} + +STDMETHODIMP UIElementSink_EndUIElement(TSFSink *sink, DWORD dwUIElementId) +{ + ITfUIElement *pElement = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId); + ITfReadingInformationUIElement *preading = 0; + ITfCandidateListUIElement *pcandidates = 0; + SDL_VideoData *videodata = (SDL_VideoData *)sink->data; + if (!pElement) + return E_INVALIDARG; + + if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) + { + videodata->ime_readingstring[0] = 0; + IME_SendEditingEvent(videodata); + preading->lpVtbl->Release(preading); + } + else if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfCandidateListUIElement, (PVOID *)&pcandidates))) + { + pcandidates->lpVtbl->Release(pcandidates); + } + 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: */ diff --git a/src/video/win32/SDL_win32video.h b/src/video/win32/SDL_win32video.h index 063fe4e2b..697cd8e32 100644 --- a/src/video/win32/SDL_win32video.h +++ b/src/video/win32/SDL_win32video.h @@ -1,95 +1,150 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifndef _SDL_win32video_h -#define _SDL_win32video_h - -#include "../SDL_sysvideo.h" - -#define WIN32_LEAN_AND_MEAN -#define STRICT -#define UNICODE -#undef WINVER -#define WINVER 0x500 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices() */ -#include - -#if SDL_VIDEO_RENDER_D3D -//#include -#define D3D_DEBUG_INFO -#include "d3d9.h" -#endif - -#if SDL_VIDEO_RENDER_DDRAW -/* WIN32_LEAN_AND_MEAN was defined, so we have to include this by hand */ -#include -#include "ddraw.h" -#endif - -#include "SDL_win32clipboard.h" -#include "SDL_win32events.h" -#include "SDL_win32gamma.h" -#include "SDL_win32keyboard.h" -#include "SDL_win32modes.h" -#include "SDL_win32mouse.h" -#include "SDL_win32opengl.h" -#include "SDL_win32window.h" - -#ifdef UNICODE -#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "UCS-2", (char *)S, (SDL_wcslen(S)+1)*sizeof(WCHAR)) -#define WIN_UTF8ToString(S) (WCHAR *)SDL_iconv_string("UCS-2", "UTF-8", (char *)S, SDL_strlen(S)+1) -#else -#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "ASCII", (char *)S, (SDL_strlen(S)+1)) -#define WIN_UTF8ToString(S) SDL_iconv_string("ASCII", "UTF-8", (char *)S, SDL_strlen(S)+1) -#endif -extern void WIN_SetError(const char *prefix); - -/* Private display data */ - -typedef struct SDL_VideoData -{ -#if SDL_VIDEO_RENDER_D3D - HANDLE d3dDLL; - IDirect3D9 *d3d; -#endif -#if SDL_VIDEO_RENDER_DDRAW - HANDLE ddrawDLL; - IDirectDraw *ddraw; -#endif - - const SDL_scancode *key_layout; - DWORD clipboard_count; - - SDL_bool ime_com_initialized; - struct ITfThreadMgr *ime_thread_mgr; - SDL_bool ime_initialized; - SDL_bool ime_enabled; - SDL_bool ime_available; - HWND ime_hwnd_main; - HWND ime_hwnd_current; - HIMC ime_himc; - -} SDL_VideoData; - -#endif /* _SDL_win32video_h */ - -/* vi: set ts=4 sw=4 expandtab: */ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#ifndef _SDL_win32video_h +#define _SDL_win32video_h + +#include "../SDL_sysvideo.h" + +#define WIN32_LEAN_AND_MEAN +#define STRICT +#define UNICODE +#undef WINVER +#define WINVER 0x500 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices() */ +#include + +#include + +#if SDL_VIDEO_RENDER_D3D +//#include +#define D3D_DEBUG_INFO +#include "d3d9.h" +#endif + +#if SDL_VIDEO_RENDER_DDRAW +/* WIN32_LEAN_AND_MEAN was defined, so we have to include this by hand */ +#include +#include "ddraw.h" +#endif + +#include "SDL_win32clipboard.h" +#include "SDL_win32events.h" +#include "SDL_win32gamma.h" +#include "SDL_win32keyboard.h" +#include "SDL_win32modes.h" +#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)) +#define WIN_UTF8ToString(S) (WCHAR *)SDL_iconv_string("UCS-2", "UTF-8", (char *)S, SDL_strlen(S)+1) +#else +#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "ASCII", (char *)S, (SDL_strlen(S)+1)) +#define WIN_UTF8ToString(S) SDL_iconv_string("ASCII", "UTF-8", (char *)S, SDL_strlen(S)+1) +#endif +extern void WIN_SetError(const char *prefix); + +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 +{ +#if SDL_VIDEO_RENDER_D3D + HANDLE d3dDLL; + IDirect3D9 *d3d; +#endif +#if SDL_VIDEO_RENDER_DDRAW + HANDLE ddrawDLL; + IDirectDraw *ddraw; +#endif + + const SDL_scancode *key_layout; + DWORD clipboard_count; + + 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 */ + +/* vi: set ts=4 sw=4 expandtab: */ From d980c084c78d0f3a2634891d02400225f446092a Mon Sep 17 00:00:00 2001 From: dewyatt Date: Wed, 4 Aug 2010 23:17:12 -0400 Subject: [PATCH 29/30] Updated to fit SDL style a little more. --- src/video/win32/SDL_win32keyboard.c | 196 ++++++++++------------------ 1 file changed, 69 insertions(+), 127 deletions(-) diff --git a/src/video/win32/SDL_win32keyboard.c b/src/video/win32/SDL_win32keyboard.c index d2fe416e9..4895984ee 100644 --- a/src/video/win32/SDL_win32keyboard.c +++ b/src/video/win32/SDL_win32keyboard.c @@ -320,18 +320,15 @@ IME_Quit(SDL_VideoData *videodata) videodata->ime_hwnd_main = 0; videodata->ime_himc = 0; - if (videodata->ime_himm32) - { + if (videodata->ime_himm32) { FreeLibrary(videodata->ime_himm32); videodata->ime_himm32 = 0; } - if (videodata->ime_threadmgr) - { + if (videodata->ime_threadmgr) { videodata->ime_threadmgr->lpVtbl->Release(videodata->ime_threadmgr); videodata->ime_threadmgr = 0; } - if (videodata->ime_com_initialized) - { + if (videodata->ime_com_initialized) { CoUninitialize(); videodata->ime_com_initialized = SDL_FALSE; } @@ -354,8 +351,7 @@ IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd) return; videodata->ime_readingstring[0] = 0; - if (!osversion.dwOSVersionInfoSize) - { + if (!osversion.dwOSVersionInfoSize) { osversion.dwOSVersionInfoSize = sizeof(osversion); GetVersionExA(&osversion); } @@ -367,11 +363,9 @@ IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd) if (!himc) return; - if (videodata->GetReadingString) - { + if (videodata->GetReadingString) { len = videodata->GetReadingString(himc, 0, 0, &err, &vertical, &maxuilen); - if (len) - { + if (len) { if (len > SDL_arraysize(buffer)) len = SDL_arraysize(buffer); @@ -379,8 +373,7 @@ IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd) } SDL_wcslcpy(videodata->ime_readingstring, s, len); } - else - { + else { LPINPUTCONTEXT2 lpimc = videodata->ImmLockIMC(himc); LPBYTE p = 0; s = 0; @@ -434,9 +427,8 @@ IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd) break; } if (s) - { SDL_wcslcpy(videodata->ime_readingstring, s, len + 1); - } + videodata->ImmUnlockIMCC(lpimc->hPrivate); videodata->ImmUnlockIMC(himc); } @@ -447,17 +439,15 @@ IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd) static void IME_InputLangChanged(SDL_VideoData *videodata) { - UINT uLang = PRIMLANG(); + UINT lang = PRIMLANG(); HWND hwndime = 0; IME_UpdateInputLocale(videodata); IME_SetupAPI(videodata); - if (uLang != PRIMLANG()) - { + if (lang != PRIMLANG()) { IME_ClearComposition(videodata); } hwndime = ImmGetDefaultIMEWnd(videodata->ime_hwnd_current); - if (hwndime) - { + if (hwndime) { SendMessageA(hwndime, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0); SendMessageA(hwndime, WM_IME_CONTROL, IMC_CLOSESTATUSWINDOW, 0); } @@ -485,8 +475,7 @@ IME_GetId(SDL_VideoData *videodata, UINT uIndex) hklprev = hkl; dwLang = ((DWORD)hkl & 0xffff); - if (videodata->ime_uiless && LANG() == LANG_CHT) - { + if (videodata->ime_uiless && LANG() == LANG_CHT) { dwRet[0] = IMEID_CHT_VER_VISTA; dwRet[1] = 0; return dwRet[0]; @@ -495,40 +484,31 @@ IME_GetId(SDL_VideoData *videodata, UINT uIndex) && hkl != CHT_HKL_NEW_CHANG_JIE && hkl != CHT_HKL_NEW_QUICK && hkl != CHT_HKL_HK_CANTONESE - && hkl != CHS_HKL) - { + && hkl != CHS_HKL) { dwRet[0] = dwRet[1] = 0; return dwRet[uIndex]; } - if (ImmGetIMEFileNameA(hkl, szTemp, sizeof(szTemp) - 1) <= 0) - { + if (ImmGetIMEFileNameA(hkl, szTemp, sizeof(szTemp) - 1) <= 0) { dwRet[0] = dwRet[1] = 0; return dwRet[uIndex]; } - if (!videodata->GetReadingString) - { + 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 - ) - { + && 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) - { + if (dwVerSize) { lpVerBuffer = SDL_malloc(dwVerSize); - if (lpVerBuffer) - { - if (GetFileVersionInfoA(szTemp, dwVerHandle, dwVerSize, lpVerBuffer)) - { - if (VerQueryValueA(lpVerBuffer, "\\", &lpVerData, &cbVerData)) - { + 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; @@ -545,9 +525,7 @@ IME_GetId(SDL_VideoData *videodata, UINT uIndex) dwLang == LANG_CHS && ( dwVer == MAKEIMEVERSION(4, 1) || dwVer == MAKEIMEVERSION(4, 2) || - dwVer == MAKEIMEVERSION(5, 3)) - ) - { + dwVer == MAKEIMEVERSION(5, 3))) { dwRet[0] = dwVer | dwLang; dwRet[1] = pVerFixedInfo->dwFileVersionLS; SDL_free(lpVerBuffer); @@ -588,11 +566,9 @@ IME_SetupAPI(SDL_VideoData *videodata) videodata->ShowReadingWindow = (BOOL (WINAPI *)(HIMC, BOOL)) GetProcAddress(hime, "ShowReadingWindow"); - if (videodata->ShowReadingWindow) - { + if (videodata->ShowReadingWindow) { HIMC himc = ImmGetContext(videodata->ime_hwnd_current); - if (himc) - { + if (himc) { videodata->ShowReadingWindow(himc, FALSE); ImmReleaseContext(videodata->ime_hwnd_current, himc); } @@ -615,12 +591,12 @@ IME_SetWindow(SDL_VideoData* videodata, HWND hwnd) static void IME_UpdateInputLocale(SDL_VideoData *videodata) { - static HKL hklPrevious = 0; + static HKL hklprev = 0; videodata->ime_hkl = GetKeyboardLayout(0); - if (hklPrevious == videodata->ime_hkl) + if (hklprev == videodata->ime_hkl) return; - hklPrevious = videodata->ime_hkl; + hklprev = videodata->ime_hkl; } static void @@ -652,21 +628,20 @@ 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; + LONG length = ImmGetCompositionStringW(himc, string, videodata->ime_composition, sizeof(videodata->ime_composition)); + if (length < 0) + length = 0; - Length /= sizeof(videodata->ime_composition[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) - { + if (videodata->ime_composition[videodata->ime_cursor] == 0x3000) { int i; - for (i = videodata->ime_cursor + 1; i < Length; ++i) + for (i = videodata->ime_cursor + 1; i < length; ++i) videodata->ime_composition[i - 1] = videodata->ime_composition[i]; - --Length; + --length; } - videodata->ime_composition[Length] = 0; + videodata->ime_composition[length] = 0; } static void @@ -686,20 +661,18 @@ static void IME_SendEditingEvent(SDL_VideoData *videodata) { char *s = 0; - WCHAR wBuffer[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; - wBuffer[0] = 0; - if (videodata->ime_readingstring[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(wBuffer, videodata->ime_composition, len + 1); - SDL_wcslcat(wBuffer, videodata->ime_readingstring, sizeof(wBuffer)); - SDL_wcslcat(wBuffer, &videodata->ime_composition[len], sizeof(wBuffer) - len); + 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(wBuffer, videodata->ime_composition, sizeof(videodata->ime_composition)); + else { + SDL_wcslcpy(buffer, videodata->ime_composition, sizeof(videodata->ime_composition)); } - s = WIN_StringToUTF8(wBuffer); + s = WIN_StringToUTF8(buffer); SDL_SendEditingText(s, videodata->ime_cursor + SDL_wcslen(videodata->ime_readingstring), 0); SDL_free(s); } @@ -726,13 +699,11 @@ IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoD case WM_IME_COMPOSITION: trap = SDL_TRUE; himc = ImmGetContext(hwnd); - if (*lParam & GCS_RESULTSTR) - { + if (*lParam & GCS_RESULTSTR) { IME_GetCompositionString(videodata, himc, GCS_RESULTSTR); IME_SendInputEvent(videodata); } - if (*lParam & GCS_COMPSTR) - { + if (*lParam & GCS_COMPSTR) { if (!videodata->ime_uiless) videodata->ime_readingstring[0] = 0; @@ -827,8 +798,7 @@ STDMETHODIMP UIElementSink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv else if (SDL_IsEqualIID(riid, &IID_ITfUIElementSink)) *ppv = (ITfUIElementSink *)sink; - if (*ppv) - { + if (*ppv) { TSFSink_AddRef(sink); return S_OK; } @@ -841,8 +811,7 @@ ITfUIElement *UILess_GetUIElement(SDL_VideoData *videodata, DWORD dwUIElementId) ITfUIElement *pelem = 0; ITfThreadMgrEx *threadmgrex = videodata->ime_threadmgrex; - if (SUCCEEDED(threadmgrex->lpVtbl->QueryInterface(threadmgrex, &IID_ITfUIElementMgr, (LPVOID *)&puiem))) - { + if (SUCCEEDED(threadmgrex->lpVtbl->QueryInterface(threadmgrex, &IID_ITfUIElementMgr, (LPVOID *)&puiem))) { puiem->lpVtbl->GetUIElement(puiem, dwUIElementId, &pelem); puiem->lpVtbl->Release(puiem); } @@ -851,45 +820,35 @@ ITfUIElement *UILess_GetUIElement(SDL_VideoData *videodata, DWORD dwUIElementId) STDMETHODIMP UIElementSink_BeginUIElement(TSFSink *sink, DWORD dwUIElementId, BOOL *pbShow) { - ITfUIElement *pElement = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId); + ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId); ITfReadingInformationUIElement *preading = 0; - ITfCandidateListUIElement *pcandidates = 0; SDL_VideoData *videodata = (SDL_VideoData *)sink->data; - if (!pElement) + if (!element) return E_INVALIDARG; *pbShow = FALSE; - if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) - { + if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) { BSTR bstr; - if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) - { + if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) { WCHAR *s = (WCHAR *)bstr; SysFreeString(bstr); } preading->lpVtbl->Release(preading); } - else if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfCandidateListUIElement, (PVOID *)&pcandidates))) - { - pcandidates->lpVtbl->Release(pcandidates); - } return S_OK; } STDMETHODIMP UIElementSink_UpdateUIElement(TSFSink *sink, DWORD dwUIElementId) { - ITfUIElement *pElement = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId); + ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId); ITfReadingInformationUIElement *preading = 0; - ITfCandidateListUIElement *pcandidates = 0; SDL_VideoData *videodata = (SDL_VideoData *)sink->data; - if (!pElement) + if (!element) return E_INVALIDARG; - if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) - { + if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) { BSTR bstr; - if (SUCCEEDED(preading->lpVtbl->GetString(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); @@ -897,32 +856,22 @@ STDMETHODIMP UIElementSink_UpdateUIElement(TSFSink *sink, DWORD dwUIElementId) } preading->lpVtbl->Release(preading); } - else if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfCandidateListUIElement, (PVOID *)&pcandidates))) - { - pcandidates->lpVtbl->Release(pcandidates); - } return S_OK; } STDMETHODIMP UIElementSink_EndUIElement(TSFSink *sink, DWORD dwUIElementId) { - ITfUIElement *pElement = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId); + ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId); ITfReadingInformationUIElement *preading = 0; - ITfCandidateListUIElement *pcandidates = 0; SDL_VideoData *videodata = (SDL_VideoData *)sink->data; - if (!pElement) + if (!element) return E_INVALIDARG; - if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) - { + if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) { videodata->ime_readingstring[0] = 0; IME_SendEditingEvent(videodata); preading->lpVtbl->Release(preading); } - else if (SUCCEEDED(pElement->lpVtbl->QueryInterface(pElement, &IID_ITfCandidateListUIElement, (PVOID *)&pcandidates))) - { - pcandidates->lpVtbl->Release(pcandidates); - } return S_OK; } @@ -937,8 +886,7 @@ STDMETHODIMP IPPASink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv) else if (SDL_IsEqualIID(riid, &IID_ITfInputProcessorProfileActivationSink)) *ppv = (ITfInputProcessorProfileActivationSink *)sink; - if (*ppv) - { + if (*ppv) { TSFSink_AddRef(sink); return S_OK; } @@ -976,8 +924,7 @@ UILess_EnableUIUpdates(SDL_VideoData *videodata) 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))) - { + 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); } @@ -990,8 +937,7 @@ UILess_DisableUIUpdates(SDL_VideoData *videodata) 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))) - { + 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); @@ -1021,12 +967,9 @@ UILess_SetupSinks(SDL_VideoData *videodata) 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))) - { + 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; } } @@ -1046,12 +989,11 @@ UILess_SetupSinks(SDL_VideoData *videodata) 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); + 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); From 7d245d0532a411552d3eb4f3f75c4102819c158e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 22 Aug 2010 12:34:31 -0700 Subject: [PATCH 30/30] Removed spurious carriage returns --- include/SDL_stdinc.h | 1602 ++++++++++++++-------------- src/haptic/nds/SDL_syshaptic.c | 80 +- src/joystick/nds/SDL_sysjoystick.c | 46 +- src/video/win32/SDL_win32video.c | 460 ++++---- 4 files changed, 1094 insertions(+), 1094 deletions(-) diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index a2d9ce48a..17a8a8a61 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -1,808 +1,808 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ - -/** - * \file SDL_stdinc.h - * - * This is a general header that includes C language support. - */ - -#ifndef _SDL_stdinc_h -#define _SDL_stdinc_h - -#include "SDL_config.h" - - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_STDIO_H -#include -#endif -#if defined(STDC_HEADERS) -# include -# include -# include -#else -# if defined(HAVE_STDLIB_H) -# include -# elif defined(HAVE_MALLOC_H) -# include -# endif -# if defined(HAVE_STDDEF_H) -# include -# endif -# if defined(HAVE_STDARG_H) -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H) -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#if defined(HAVE_INTTYPES_H) -# include -#elif defined(HAVE_STDINT_H) -# include -#endif -#ifdef HAVE_CTYPE_H -# include -#endif -#ifdef HAVE_MATH_H -# include -#endif -#if defined(HAVE_ICONV) && defined(HAVE_ICONV_H) -# include -#endif - -/** - * The number of elements in an array. - */ -#define SDL_arraysize(array) (sizeof(array)/sizeof(array[0])) -#define SDL_TABLESIZE(table) SDL_arraysize(table) - -/** - * \name Cast operators - * - * Use proper C++ casts when compiled as C++ to be compatible with the option - * -Wold-style-cast of GCC (and -Werror=old-style-cast in GCC 4.2 and above). - */ -/*@{*/ -#ifdef __cplusplus -#define SDL_reinterpret_cast(type, expression) reinterpret_cast(expression) -#define SDL_static_cast(type, expression) static_cast(expression) -#else -#define SDL_reinterpret_cast(type, expression) ((type)(expression)) -#define SDL_static_cast(type, expression) ((type)(expression)) -#endif -/*@}*//*Cast operators*/ - -/* Define a four character code as a Uint32 */ -#define SDL_FOURCC(A, B, C, D) \ - ((SDL_static_cast(Uint32, SDL_static_cast(Uint8, (A))) << 0) | \ - (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (B))) << 8) | \ - (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (C))) << 16) | \ - (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (D))) << 24)) - -/** - * \name Basic data types - */ -/*@{*/ - -typedef enum -{ - SDL_FALSE = 0, - SDL_TRUE = 1 -} SDL_bool; - -/** - * \brief A signed 8-bit integer type. - */ -typedef int8_t Sint8; -/** - * \brief An unsigned 8-bit integer type. - */ -typedef uint8_t Uint8; -/** - * \brief A signed 16-bit integer type. - */ -typedef int16_t Sint16; -/** - * \brief An unsigned 16-bit integer type. - */ -typedef uint16_t Uint16; -/** - * \brief A signed 32-bit integer type. - */ -typedef int32_t Sint32; -/** - * \brief An unsigned 32-bit integer type. - */ -typedef uint32_t Uint32; - -#ifdef SDL_HAS_64BIT_TYPE -/** - * \brief A signed 64-bit integer type. - * \warning On platforms without any sort of 64-bit datatype, this is equivalent to Sint32! - */ -typedef int64_t Sint64; -/** - * \brief An unsigned 64-bit integer type. - * \warning On platforms without any sort of 64-bit datatype, this is equivalent to Uint32! - */ -typedef uint64_t Uint64; -#else -/* This is really just a hack to prevent the compiler from complaining */ -typedef Sint32 Sint64; -typedef Uint32 Uint64; -#endif - -/*@}*//*Basic data types*/ - - -#define SDL_COMPILE_TIME_ASSERT(name, x) \ - typedef int SDL_dummy_ ## name[(x) * 2 - 1] -/** \cond */ -#ifndef DOXYGEN_SHOULD_IGNORE_THIS -SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1); -SDL_COMPILE_TIME_ASSERT(sint8, sizeof(Sint8) == 1); -SDL_COMPILE_TIME_ASSERT(uint16, sizeof(Uint16) == 2); -SDL_COMPILE_TIME_ASSERT(sint16, sizeof(Sint16) == 2); -SDL_COMPILE_TIME_ASSERT(uint32, sizeof(Uint32) == 4); -SDL_COMPILE_TIME_ASSERT(sint32, sizeof(Sint32) == 4); -#ifndef __NINTENDODS__ /* TODO: figure out why the following happens: - include/SDL_stdinc.h:150: error: size of array 'SDL_dummy_uint64' is negative - include/SDL_stdinc.h:151: error: size of array 'SDL_dummy_sint64' is negative */ -SDL_COMPILE_TIME_ASSERT(uint64, sizeof(Uint64) == 8); -SDL_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8); -#endif -#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ -/** \endcond */ - -/* Check to make sure enums are the size of ints, for structure packing. - For both Watcom C/C++ and Borland C/C++ the compiler option that makes - enums having the size of an int must be enabled. - This is "-b" for Borland C/C++ and "-ei" for Watcom C/C++ (v11). -*/ -/* Enable enums always int in CodeWarrior (for MPW use "-enum int") */ -#ifdef __MWERKS__ -#pragma enumsalwaysint on -#endif - -/** \cond */ -#ifndef DOXYGEN_SHOULD_IGNORE_THIS -#ifndef __NINTENDODS__ /* TODO: include/SDL_stdinc.h:174: error: size of array 'SDL_dummy_enum' is negative */ -typedef enum -{ - DUMMY_ENUM_VALUE -} SDL_DUMMY_ENUM; - -SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int)); -#endif -#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ -/** \endcond */ - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -/* *INDENT-OFF* */ -extern "C" { -/* *INDENT-ON* */ -#endif - -#ifdef HAVE_MALLOC -#define SDL_malloc malloc -#else -extern DECLSPEC void *SDLCALL SDL_malloc(size_t size); -#endif - -#ifdef HAVE_CALLOC -#define SDL_calloc calloc -#else -extern DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size); -#endif - -#ifdef HAVE_REALLOC -#define SDL_realloc realloc -#else -extern DECLSPEC void *SDLCALL SDL_realloc(void *mem, size_t size); -#endif - -#ifdef HAVE_FREE -#define SDL_free free -#else -extern DECLSPEC void SDLCALL SDL_free(void *mem); -#endif - -#if defined(HAVE_ALLOCA) && !defined(alloca) -# if defined(HAVE_ALLOCA_H) -# include -# elif defined(__GNUC__) -# define alloca __builtin_alloca -# elif defined(_MSC_VER) -# include -# define alloca _alloca -# elif defined(__WATCOMC__) -# include -# elif defined(__BORLANDC__) -# include -# elif defined(__DMC__) -# include -# elif defined(__AIX__) -#pragma alloca -# elif defined(__MRC__) -void *alloca(unsigned); -# else -char *alloca(); -# endif -#endif -#ifdef HAVE_ALLOCA -#define SDL_stack_alloc(type, count) (type*)alloca(sizeof(type)*(count)) -#define SDL_stack_free(data) -#else -#define SDL_stack_alloc(type, count) (type*)SDL_malloc(sizeof(type)*(count)) -#define SDL_stack_free(data) SDL_free(data) -#endif - -#ifdef HAVE_GETENV -#define SDL_getenv getenv -#else -extern DECLSPEC char *SDLCALL SDL_getenv(const char *name); -#endif - -/* SDL_putenv() has moved to SDL_compat. */ -#ifdef HAVE_SETENV -#define SDL_setenv setenv -#else -extern DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, - int overwrite); -#endif - -#ifdef HAVE_QSORT -#define SDL_qsort qsort -#else -extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, - int (*compare) (const void *, - const void *)); -#endif - -#ifdef HAVE_ABS -#define SDL_abs abs -#else -#define SDL_abs(X) ((X) < 0 ? -(X) : (X)) -#endif - -#define SDL_min(x, y) (((x) < (y)) ? (x) : (y)) -#define SDL_max(x, y) (((x) > (y)) ? (x) : (y)) - -#ifdef HAVE_CTYPE_H -#define SDL_isdigit(X) isdigit(X) -#define SDL_isspace(X) isspace(X) -#define SDL_toupper(X) toupper(X) -#define SDL_tolower(X) tolower(X) -#else -#define SDL_isdigit(X) (((X) >= '0') && ((X) <= '9')) -#define SDL_isspace(X) (((X) == ' ') || ((X) == '\t') || ((X) == '\r') || ((X) == '\n')) -#define SDL_toupper(X) (((X) >= 'a') && ((X) <= 'z') ? ('A'+((X)-'a')) : (X)) -#define SDL_tolower(X) (((X) >= 'A') && ((X) <= 'Z') ? ('a'+((X)-'A')) : (X)) -#endif - -#ifdef HAVE_MEMSET -#define SDL_memset memset -#else -extern DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len); -#endif -#define SDL_zero(x) SDL_memset(&(x), 0, sizeof((x))) -#define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x))) - -#if defined(__GNUC__) && defined(i386) -#define SDL_memset4(dst, val, len) \ -do { \ - int u0, u1, u2; \ - __asm__ __volatile__ ( \ - "cld\n\t" \ - "rep ; stosl\n\t" \ - : "=&D" (u0), "=&a" (u1), "=&c" (u2) \ - : "0" (dst), "1" (val), "2" (SDL_static_cast(Uint32, len)) \ - : "memory" ); \ -} while(0) -#endif -#ifndef SDL_memset4 -#define SDL_memset4(dst, val, len) \ -do { \ - unsigned _count = (len); \ - unsigned _n = (_count + 3) / 4; \ - Uint32 *_p = SDL_static_cast(Uint32 *, dst); \ - Uint32 _val = (val); \ - if (len == 0) break; \ - switch (_count % 4) { \ - case 0: do { *_p++ = _val; \ - case 3: *_p++ = _val; \ - case 2: *_p++ = _val; \ - case 1: *_p++ = _val; \ - } while ( --_n ); \ - } \ -} while(0) -#endif - -/* We can count on memcpy existing on Mac OS X and being well-tuned. */ -#if defined(__MACH__) && defined(__APPLE__) -#define SDL_memcpy(dst, src, len) memcpy(dst, src, len) -#elif defined(__GNUC__) && defined(i386) -#define SDL_memcpy(dst, src, len) \ -do { \ - int u0, u1, u2; \ - __asm__ __volatile__ ( \ - "cld\n\t" \ - "rep ; movsl\n\t" \ - "testb $2,%b4\n\t" \ - "je 1f\n\t" \ - "movsw\n" \ - "1:\ttestb $1,%b4\n\t" \ - "je 2f\n\t" \ - "movsb\n" \ - "2:" \ - : "=&c" (u0), "=&D" (u1), "=&S" (u2) \ - : "0" (SDL_static_cast(unsigned, len)/4), "q" (len), "1" (dst),"2" (src) \ - : "memory" ); \ -} while(0) -#endif -#ifndef SDL_memcpy -#ifdef HAVE_MEMCPY -#define SDL_memcpy memcpy -#elif defined(HAVE_BCOPY) -#define SDL_memcpy(d, s, n) bcopy((s), (d), (n)) -#else -extern DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, - size_t len); -#endif -#endif - -/* We can count on memcpy existing on Mac OS X and being well-tuned. */ -#if defined(__MACH__) && defined(__APPLE__) -#define SDL_memcpy4(dst, src, len) memcpy(dst, src, (len)*4) -#elif defined(__GNUC__) && defined(i386) -#define SDL_memcpy4(dst, src, len) \ -do { \ - int ecx, edi, esi; \ - __asm__ __volatile__ ( \ - "cld\n\t" \ - "rep ; movsl" \ - : "=&c" (ecx), "=&D" (edi), "=&S" (esi) \ - : "0" (SDL_static_cast(unsigned, len)), "1" (dst), "2" (src) \ - : "memory" ); \ -} while(0) -#endif -#ifndef SDL_memcpy4 -#define SDL_memcpy4(dst, src, len) SDL_memcpy(dst, src, (len) << 2) -#endif - -#if defined(__GNUC__) && defined(i386) -#define SDL_revcpy(dst, src, len) \ -do { \ - int u0, u1, u2; \ - char *dstp = SDL_static_cast(char *, dst); \ - char *srcp = SDL_static_cast(char *, src); \ - int n = (len); \ - if ( n >= 4 ) { \ - __asm__ __volatile__ ( \ - "std\n\t" \ - "rep ; movsl\n\t" \ - "cld\n\t" \ - : "=&c" (u0), "=&D" (u1), "=&S" (u2) \ - : "0" (n >> 2), \ - "1" (dstp+(n-4)), "2" (srcp+(n-4)) \ - : "memory" ); \ - } \ - switch (n & 3) { \ - case 3: dstp[2] = srcp[2]; \ - case 2: dstp[1] = srcp[1]; \ - case 1: dstp[0] = srcp[0]; \ - break; \ - default: \ - break; \ - } \ -} while(0) -#endif -#ifndef SDL_revcpy -extern DECLSPEC void *SDLCALL SDL_revcpy(void *dst, const void *src, - size_t len); -#endif - -#ifdef HAVE_MEMMOVE -#define SDL_memmove memmove -#elif defined(HAVE_BCOPY) -#define SDL_memmove(d, s, n) bcopy((s), (d), (n)) -#else -#define SDL_memmove(dst, src, len) \ -do { \ - if ( dst < src ) { \ - SDL_memcpy(dst, src, len); \ - } else { \ - SDL_revcpy(dst, src, len); \ - } \ -} while(0) -#endif - -#ifdef HAVE_MEMCMP -#define SDL_memcmp memcmp -#else -extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, - size_t len); -#endif - -#ifdef HAVE_STRLEN -#define SDL_strlen strlen -#else -extern DECLSPEC size_t SDLCALL SDL_strlen(const char *string); -#endif - -#ifdef HAVE_WCSLEN -#define SDL_wcslen wcslen -#else -#if !defined(wchar_t) && defined(__NINTENDODS__) -#define wchar_t short /* TODO: figure out why libnds doesn't have this */ -#endif -extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t * string); -#endif - -#ifdef HAVE_WCSLCPY -#define SDL_wcslcpy wcslcpy +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/** + * \file SDL_stdinc.h + * + * This is a general header that includes C language support. + */ + +#ifndef _SDL_stdinc_h +#define _SDL_stdinc_h + +#include "SDL_config.h" + + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_STDIO_H +#include +#endif +#if defined(STDC_HEADERS) +# include +# include +# include +#else +# if defined(HAVE_STDLIB_H) +# include +# elif defined(HAVE_MALLOC_H) +# include +# endif +# if defined(HAVE_STDDEF_H) +# include +# endif +# if defined(HAVE_STDARG_H) +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H) +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#if defined(HAVE_INTTYPES_H) +# include +#elif defined(HAVE_STDINT_H) +# include +#endif +#ifdef HAVE_CTYPE_H +# include +#endif +#ifdef HAVE_MATH_H +# include +#endif +#if defined(HAVE_ICONV) && defined(HAVE_ICONV_H) +# include +#endif + +/** + * The number of elements in an array. + */ +#define SDL_arraysize(array) (sizeof(array)/sizeof(array[0])) +#define SDL_TABLESIZE(table) SDL_arraysize(table) + +/** + * \name Cast operators + * + * Use proper C++ casts when compiled as C++ to be compatible with the option + * -Wold-style-cast of GCC (and -Werror=old-style-cast in GCC 4.2 and above). + */ +/*@{*/ +#ifdef __cplusplus +#define SDL_reinterpret_cast(type, expression) reinterpret_cast(expression) +#define SDL_static_cast(type, expression) static_cast(expression) +#else +#define SDL_reinterpret_cast(type, expression) ((type)(expression)) +#define SDL_static_cast(type, expression) ((type)(expression)) +#endif +/*@}*//*Cast operators*/ + +/* Define a four character code as a Uint32 */ +#define SDL_FOURCC(A, B, C, D) \ + ((SDL_static_cast(Uint32, SDL_static_cast(Uint8, (A))) << 0) | \ + (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (B))) << 8) | \ + (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (C))) << 16) | \ + (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (D))) << 24)) + +/** + * \name Basic data types + */ +/*@{*/ + +typedef enum +{ + SDL_FALSE = 0, + SDL_TRUE = 1 +} SDL_bool; + +/** + * \brief A signed 8-bit integer type. + */ +typedef int8_t Sint8; +/** + * \brief An unsigned 8-bit integer type. + */ +typedef uint8_t Uint8; +/** + * \brief A signed 16-bit integer type. + */ +typedef int16_t Sint16; +/** + * \brief An unsigned 16-bit integer type. + */ +typedef uint16_t Uint16; +/** + * \brief A signed 32-bit integer type. + */ +typedef int32_t Sint32; +/** + * \brief An unsigned 32-bit integer type. + */ +typedef uint32_t Uint32; + +#ifdef SDL_HAS_64BIT_TYPE +/** + * \brief A signed 64-bit integer type. + * \warning On platforms without any sort of 64-bit datatype, this is equivalent to Sint32! + */ +typedef int64_t Sint64; +/** + * \brief An unsigned 64-bit integer type. + * \warning On platforms without any sort of 64-bit datatype, this is equivalent to Uint32! + */ +typedef uint64_t Uint64; +#else +/* This is really just a hack to prevent the compiler from complaining */ +typedef Sint32 Sint64; +typedef Uint32 Uint64; +#endif + +/*@}*//*Basic data types*/ + + +#define SDL_COMPILE_TIME_ASSERT(name, x) \ + typedef int SDL_dummy_ ## name[(x) * 2 - 1] +/** \cond */ +#ifndef DOXYGEN_SHOULD_IGNORE_THIS +SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1); +SDL_COMPILE_TIME_ASSERT(sint8, sizeof(Sint8) == 1); +SDL_COMPILE_TIME_ASSERT(uint16, sizeof(Uint16) == 2); +SDL_COMPILE_TIME_ASSERT(sint16, sizeof(Sint16) == 2); +SDL_COMPILE_TIME_ASSERT(uint32, sizeof(Uint32) == 4); +SDL_COMPILE_TIME_ASSERT(sint32, sizeof(Sint32) == 4); +#ifndef __NINTENDODS__ /* TODO: figure out why the following happens: + include/SDL_stdinc.h:150: error: size of array 'SDL_dummy_uint64' is negative + include/SDL_stdinc.h:151: error: size of array 'SDL_dummy_sint64' is negative */ +SDL_COMPILE_TIME_ASSERT(uint64, sizeof(Uint64) == 8); +SDL_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8); +#endif +#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ +/** \endcond */ + +/* Check to make sure enums are the size of ints, for structure packing. + For both Watcom C/C++ and Borland C/C++ the compiler option that makes + enums having the size of an int must be enabled. + This is "-b" for Borland C/C++ and "-ei" for Watcom C/C++ (v11). +*/ +/* Enable enums always int in CodeWarrior (for MPW use "-enum int") */ +#ifdef __MWERKS__ +#pragma enumsalwaysint on +#endif + +/** \cond */ +#ifndef DOXYGEN_SHOULD_IGNORE_THIS +#ifndef __NINTENDODS__ /* TODO: include/SDL_stdinc.h:174: error: size of array 'SDL_dummy_enum' is negative */ +typedef enum +{ + DUMMY_ENUM_VALUE +} SDL_DUMMY_ENUM; + +SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int)); +#endif +#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ +/** \endcond */ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#ifdef HAVE_MALLOC +#define SDL_malloc malloc +#else +extern DECLSPEC void *SDLCALL SDL_malloc(size_t size); +#endif + +#ifdef HAVE_CALLOC +#define SDL_calloc calloc +#else +extern DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size); +#endif + +#ifdef HAVE_REALLOC +#define SDL_realloc realloc +#else +extern DECLSPEC void *SDLCALL SDL_realloc(void *mem, size_t size); +#endif + +#ifdef HAVE_FREE +#define SDL_free free +#else +extern DECLSPEC void SDLCALL SDL_free(void *mem); +#endif + +#if defined(HAVE_ALLOCA) && !defined(alloca) +# if defined(HAVE_ALLOCA_H) +# include +# elif defined(__GNUC__) +# define alloca __builtin_alloca +# elif defined(_MSC_VER) +# include +# define alloca _alloca +# elif defined(__WATCOMC__) +# include +# elif defined(__BORLANDC__) +# include +# elif defined(__DMC__) +# include +# elif defined(__AIX__) +#pragma alloca +# elif defined(__MRC__) +void *alloca(unsigned); +# else +char *alloca(); +# endif +#endif +#ifdef HAVE_ALLOCA +#define SDL_stack_alloc(type, count) (type*)alloca(sizeof(type)*(count)) +#define SDL_stack_free(data) +#else +#define SDL_stack_alloc(type, count) (type*)SDL_malloc(sizeof(type)*(count)) +#define SDL_stack_free(data) SDL_free(data) +#endif + +#ifdef HAVE_GETENV +#define SDL_getenv getenv +#else +extern DECLSPEC char *SDLCALL SDL_getenv(const char *name); +#endif + +/* SDL_putenv() has moved to SDL_compat. */ +#ifdef HAVE_SETENV +#define SDL_setenv setenv +#else +extern DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, + int overwrite); +#endif + +#ifdef HAVE_QSORT +#define SDL_qsort qsort +#else +extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, + int (*compare) (const void *, + const void *)); +#endif + +#ifdef HAVE_ABS +#define SDL_abs abs +#else +#define SDL_abs(X) ((X) < 0 ? -(X) : (X)) +#endif + +#define SDL_min(x, y) (((x) < (y)) ? (x) : (y)) +#define SDL_max(x, y) (((x) > (y)) ? (x) : (y)) + +#ifdef HAVE_CTYPE_H +#define SDL_isdigit(X) isdigit(X) +#define SDL_isspace(X) isspace(X) +#define SDL_toupper(X) toupper(X) +#define SDL_tolower(X) tolower(X) +#else +#define SDL_isdigit(X) (((X) >= '0') && ((X) <= '9')) +#define SDL_isspace(X) (((X) == ' ') || ((X) == '\t') || ((X) == '\r') || ((X) == '\n')) +#define SDL_toupper(X) (((X) >= 'a') && ((X) <= 'z') ? ('A'+((X)-'a')) : (X)) +#define SDL_tolower(X) (((X) >= 'A') && ((X) <= 'Z') ? ('a'+((X)-'A')) : (X)) +#endif + +#ifdef HAVE_MEMSET +#define SDL_memset memset +#else +extern DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len); +#endif +#define SDL_zero(x) SDL_memset(&(x), 0, sizeof((x))) +#define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x))) + +#if defined(__GNUC__) && defined(i386) +#define SDL_memset4(dst, val, len) \ +do { \ + int u0, u1, u2; \ + __asm__ __volatile__ ( \ + "cld\n\t" \ + "rep ; stosl\n\t" \ + : "=&D" (u0), "=&a" (u1), "=&c" (u2) \ + : "0" (dst), "1" (val), "2" (SDL_static_cast(Uint32, len)) \ + : "memory" ); \ +} while(0) +#endif +#ifndef SDL_memset4 +#define SDL_memset4(dst, val, len) \ +do { \ + unsigned _count = (len); \ + unsigned _n = (_count + 3) / 4; \ + Uint32 *_p = SDL_static_cast(Uint32 *, dst); \ + Uint32 _val = (val); \ + if (len == 0) break; \ + switch (_count % 4) { \ + case 0: do { *_p++ = _val; \ + case 3: *_p++ = _val; \ + case 2: *_p++ = _val; \ + case 1: *_p++ = _val; \ + } while ( --_n ); \ + } \ +} while(0) +#endif + +/* We can count on memcpy existing on Mac OS X and being well-tuned. */ +#if defined(__MACH__) && defined(__APPLE__) +#define SDL_memcpy(dst, src, len) memcpy(dst, src, len) +#elif defined(__GNUC__) && defined(i386) +#define SDL_memcpy(dst, src, len) \ +do { \ + int u0, u1, u2; \ + __asm__ __volatile__ ( \ + "cld\n\t" \ + "rep ; movsl\n\t" \ + "testb $2,%b4\n\t" \ + "je 1f\n\t" \ + "movsw\n" \ + "1:\ttestb $1,%b4\n\t" \ + "je 2f\n\t" \ + "movsb\n" \ + "2:" \ + : "=&c" (u0), "=&D" (u1), "=&S" (u2) \ + : "0" (SDL_static_cast(unsigned, len)/4), "q" (len), "1" (dst),"2" (src) \ + : "memory" ); \ +} while(0) +#endif +#ifndef SDL_memcpy +#ifdef HAVE_MEMCPY +#define SDL_memcpy memcpy +#elif defined(HAVE_BCOPY) +#define SDL_memcpy(d, s, n) bcopy((s), (d), (n)) +#else +extern DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, + size_t len); +#endif +#endif + +/* We can count on memcpy existing on Mac OS X and being well-tuned. */ +#if defined(__MACH__) && defined(__APPLE__) +#define SDL_memcpy4(dst, src, len) memcpy(dst, src, (len)*4) +#elif defined(__GNUC__) && defined(i386) +#define SDL_memcpy4(dst, src, len) \ +do { \ + int ecx, edi, esi; \ + __asm__ __volatile__ ( \ + "cld\n\t" \ + "rep ; movsl" \ + : "=&c" (ecx), "=&D" (edi), "=&S" (esi) \ + : "0" (SDL_static_cast(unsigned, len)), "1" (dst), "2" (src) \ + : "memory" ); \ +} while(0) +#endif +#ifndef SDL_memcpy4 +#define SDL_memcpy4(dst, src, len) SDL_memcpy(dst, src, (len) << 2) +#endif + +#if defined(__GNUC__) && defined(i386) +#define SDL_revcpy(dst, src, len) \ +do { \ + int u0, u1, u2; \ + char *dstp = SDL_static_cast(char *, dst); \ + char *srcp = SDL_static_cast(char *, src); \ + int n = (len); \ + if ( n >= 4 ) { \ + __asm__ __volatile__ ( \ + "std\n\t" \ + "rep ; movsl\n\t" \ + "cld\n\t" \ + : "=&c" (u0), "=&D" (u1), "=&S" (u2) \ + : "0" (n >> 2), \ + "1" (dstp+(n-4)), "2" (srcp+(n-4)) \ + : "memory" ); \ + } \ + switch (n & 3) { \ + case 3: dstp[2] = srcp[2]; \ + case 2: dstp[1] = srcp[1]; \ + case 1: dstp[0] = srcp[0]; \ + break; \ + default: \ + break; \ + } \ +} while(0) +#endif +#ifndef SDL_revcpy +extern DECLSPEC void *SDLCALL SDL_revcpy(void *dst, const void *src, + size_t len); +#endif + +#ifdef HAVE_MEMMOVE +#define SDL_memmove memmove +#elif defined(HAVE_BCOPY) +#define SDL_memmove(d, s, n) bcopy((s), (d), (n)) +#else +#define SDL_memmove(dst, src, len) \ +do { \ + if ( dst < src ) { \ + SDL_memcpy(dst, src, len); \ + } else { \ + SDL_revcpy(dst, src, len); \ + } \ +} while(0) +#endif + +#ifdef HAVE_MEMCMP +#define SDL_memcmp memcmp +#else +extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, + size_t len); +#endif + +#ifdef HAVE_STRLEN +#define SDL_strlen strlen +#else +extern DECLSPEC size_t SDLCALL SDL_strlen(const char *string); +#endif + +#ifdef HAVE_WCSLEN +#define SDL_wcslen wcslen +#else +#if !defined(wchar_t) && defined(__NINTENDODS__) +#define wchar_t short /* TODO: figure out why libnds doesn't have this */ +#endif +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 +#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 -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 -extern DECLSPEC size_t SDLCALL SDL_strlcat(char *dst, const char *src, - size_t maxlen); -#endif - -#ifdef HAVE_STRDUP -#define SDL_strdup strdup -#else -extern DECLSPEC char *SDLCALL SDL_strdup(const char *string); -#endif - -#ifdef HAVE__STRREV -#define SDL_strrev _strrev -#else -extern DECLSPEC char *SDLCALL SDL_strrev(char *string); -#endif - -#ifdef HAVE__STRUPR -#define SDL_strupr _strupr -#else -extern DECLSPEC char *SDLCALL SDL_strupr(char *string); -#endif - -#ifdef HAVE__STRLWR -#define SDL_strlwr _strlwr -#else -extern DECLSPEC char *SDLCALL SDL_strlwr(char *string); -#endif - -#ifdef HAVE_STRCHR -#define SDL_strchr strchr -#elif defined(HAVE_INDEX) -#define SDL_strchr index -#else -extern DECLSPEC char *SDLCALL SDL_strchr(const char *string, int c); -#endif - -#ifdef HAVE_STRRCHR -#define SDL_strrchr strrchr -#elif defined(HAVE_RINDEX) -#define SDL_strrchr rindex -#else -extern DECLSPEC char *SDLCALL SDL_strrchr(const char *string, int c); -#endif - -#ifdef HAVE_STRSTR -#define SDL_strstr strstr -#else -extern DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, - const char *needle); -#endif - -#ifdef HAVE_ITOA -#define SDL_itoa itoa -#else -#define SDL_itoa(value, string, radix) SDL_ltoa((long)value, string, radix) -#endif - -#ifdef HAVE__LTOA -#define SDL_ltoa _ltoa -#else -extern DECLSPEC char *SDLCALL SDL_ltoa(long value, char *string, int radix); -#endif - -#ifdef HAVE__UITOA -#define SDL_uitoa _uitoa -#else -#define SDL_uitoa(value, string, radix) SDL_ultoa((long)value, string, radix) -#endif - -#ifdef HAVE__ULTOA -#define SDL_ultoa _ultoa -#else -extern DECLSPEC char *SDLCALL SDL_ultoa(unsigned long value, char *string, - int radix); -#endif - -#ifdef HAVE_STRTOL -#define SDL_strtol strtol -#else -extern DECLSPEC long SDLCALL SDL_strtol(const char *string, char **endp, - int base); -#endif - -#ifdef HAVE_STRTOUL -#define SDL_strtoul strtoul -#else -extern DECLSPEC unsigned long SDLCALL SDL_strtoul(const char *string, - char **endp, int base); -#endif - -#ifdef SDL_HAS_64BIT_TYPE - -#ifdef HAVE__I64TOA -#define SDL_lltoa _i64toa -#else -extern DECLSPEC char *SDLCALL SDL_lltoa(Sint64 value, char *string, - int radix); -#endif - -#ifdef HAVE__UI64TOA -#define SDL_ulltoa _ui64toa -#else -extern DECLSPEC char *SDLCALL SDL_ulltoa(Uint64 value, char *string, - int radix); -#endif - -#ifdef HAVE_STRTOLL -#define SDL_strtoll strtoll -#else -extern DECLSPEC Sint64 SDLCALL SDL_strtoll(const char *string, char **endp, - int base); -#endif - -#ifdef HAVE_STRTOULL -#define SDL_strtoull strtoull -#else -extern DECLSPEC Uint64 SDLCALL SDL_strtoull(const char *string, char **endp, - int base); -#endif - -#endif /* SDL_HAS_64BIT_TYPE */ - -#ifdef HAVE_STRTOD -#define SDL_strtod strtod -#else -extern DECLSPEC double SDLCALL SDL_strtod(const char *string, char **endp); -#endif - -#ifdef HAVE_ATOI -#define SDL_atoi atoi -#else -#define SDL_atoi(X) SDL_strtol(X, NULL, 0) -#endif - -#ifdef HAVE_ATOF -#define SDL_atof atof -#else -#define SDL_atof(X) SDL_strtod(X, NULL) -#endif - -#ifdef HAVE_STRCMP -#define SDL_strcmp strcmp -#else -extern DECLSPEC int SDLCALL SDL_strcmp(const char *str1, const char *str2); -#endif - -#ifdef HAVE_STRNCMP -#define SDL_strncmp strncmp -#else -extern DECLSPEC int SDLCALL SDL_strncmp(const char *str1, const char *str2, - size_t maxlen); -#endif - -#ifdef HAVE_STRCASECMP -#define SDL_strcasecmp strcasecmp -#elif defined(HAVE__STRICMP) -#define SDL_strcasecmp _stricmp -#else -extern DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, - const char *str2); -#endif - -#ifdef HAVE_STRNCASECMP -#define SDL_strncasecmp strncasecmp -#elif defined(HAVE__STRNICMP) -#define SDL_strncasecmp _strnicmp -#else -extern DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, - const char *str2, size_t maxlen); -#endif - -#ifdef HAVE_SSCANF -#define SDL_sscanf sscanf -#else -extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, const char *fmt, - ...); -#endif - -#ifdef HAVE_SNPRINTF -#define SDL_snprintf snprintf -#else -extern DECLSPEC int SDLCALL SDL_snprintf(char *text, size_t maxlen, - const char *fmt, ...); -#endif - -#ifdef HAVE_VSNPRINTF -#define SDL_vsnprintf vsnprintf -#else -extern DECLSPEC int SDLCALL SDL_vsnprintf(char *text, size_t maxlen, - const char *fmt, va_list ap); -#endif - -#ifndef HAVE_M_PI -#define M_PI 3.14159265358979323846264338327950288 /* pi */ -#endif - -#ifdef HAVE_CEIL -#define SDL_ceil ceil -#else -#define SDL_ceil(x) ((double)(int)((x)+0.5)) -#endif - -#ifdef HAVE_COPYSIGN -#define SDL_copysign copysign -#else -extern DECLSPEC double SDLCALL SDL_copysign(double x, double y); -#endif - -#ifdef HAVE_COS -#define SDL_cos cos -#else -extern DECLSPEC double SDLCALL SDL_cos(double x); -#endif - -#ifdef HAVE_COSF -#define SDL_cosf cosf -#else -#define SDL_cosf(x) (float)SDL_cos((double)x) -#endif - -#ifdef HAVE_FABS -#define SDL_fabs fabs -#else -extern DECLSPEC double SDLCALL SDL_fabs(double x); -#endif - -#ifdef HAVE_FLOOR -#define SDL_floor floor -#else -extern DECLSPEC double SDLCALL SDL_floor(double x); -#endif - -#ifdef HAVE_LOG -#define SDL_log log -#else -extern DECLSPEC double SDLCALL SDL_log(double x); -#endif - -#ifdef HAVE_POW -#define SDL_pow pow -#else -extern DECLSPEC double SDLCALL SDL_pow(double x, double y); -#endif - -#ifdef HAVE_SCALBN -#define SDL_scalbn scalbn -#else -extern DECLSPEC double SDLCALL SDL_scalbn(double x, int n); -#endif - -#ifdef HAVE_SIN -#define SDL_sin sin -#else -extern DECLSPEC double SDLCALL SDL_sin(double x); -#endif - -#ifdef HAVE_SINF -#define SDL_sinf sinf -#else -#define SDL_sinf(x) (float)SDL_sin((double)x) -#endif - -#ifdef HAVE_SQRT -#define SDL_sqrt sqrt -#else -extern DECLSPEC double SDLCALL SDL_sqrt(double x); -#endif - -/* The SDL implementation of iconv() returns these error codes */ -#define SDL_ICONV_ERROR (size_t)-1 -#define SDL_ICONV_E2BIG (size_t)-2 -#define SDL_ICONV_EILSEQ (size_t)-3 -#define SDL_ICONV_EINVAL (size_t)-4 - -#if defined(HAVE_ICONV) && defined(HAVE_ICONV_H) -#define SDL_iconv_t iconv_t -#define SDL_iconv_open iconv_open -#define SDL_iconv_close iconv_close -#else -typedef struct _SDL_iconv_t *SDL_iconv_t; -extern DECLSPEC SDL_iconv_t SDLCALL SDL_iconv_open(const char *tocode, - const char *fromcode); -extern DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd); -#endif -extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, - size_t * inbytesleft, char **outbuf, - size_t * outbytesleft); -/** - * This function converts a string between encodings in one pass, returning a - * string that must be freed with SDL_free() or NULL on error. - */ -extern DECLSPEC char *SDLCALL SDL_iconv_string(const char *tocode, - const char *fromcode, - const char *inbuf, - size_t inbytesleft); -#define SDL_iconv_utf8_locale(S) SDL_iconv_string("", "UTF-8", S, SDL_strlen(S)+1) -#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2", "UTF-8", S, SDL_strlen(S)+1) -#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4", "UTF-8", S, SDL_strlen(S)+1) - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -/* *INDENT-OFF* */ -} -/* *INDENT-ON* */ -#endif -#include "close_code.h" - -#endif /* _SDL_stdinc_h */ - -/* vi: set ts=4 sw=4 expandtab: */ +#endif + + +#ifdef HAVE_STRLCPY +#define SDL_strlcpy strlcpy +#else +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 +extern DECLSPEC size_t SDLCALL SDL_strlcat(char *dst, const char *src, + size_t maxlen); +#endif + +#ifdef HAVE_STRDUP +#define SDL_strdup strdup +#else +extern DECLSPEC char *SDLCALL SDL_strdup(const char *string); +#endif + +#ifdef HAVE__STRREV +#define SDL_strrev _strrev +#else +extern DECLSPEC char *SDLCALL SDL_strrev(char *string); +#endif + +#ifdef HAVE__STRUPR +#define SDL_strupr _strupr +#else +extern DECLSPEC char *SDLCALL SDL_strupr(char *string); +#endif + +#ifdef HAVE__STRLWR +#define SDL_strlwr _strlwr +#else +extern DECLSPEC char *SDLCALL SDL_strlwr(char *string); +#endif + +#ifdef HAVE_STRCHR +#define SDL_strchr strchr +#elif defined(HAVE_INDEX) +#define SDL_strchr index +#else +extern DECLSPEC char *SDLCALL SDL_strchr(const char *string, int c); +#endif + +#ifdef HAVE_STRRCHR +#define SDL_strrchr strrchr +#elif defined(HAVE_RINDEX) +#define SDL_strrchr rindex +#else +extern DECLSPEC char *SDLCALL SDL_strrchr(const char *string, int c); +#endif + +#ifdef HAVE_STRSTR +#define SDL_strstr strstr +#else +extern DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, + const char *needle); +#endif + +#ifdef HAVE_ITOA +#define SDL_itoa itoa +#else +#define SDL_itoa(value, string, radix) SDL_ltoa((long)value, string, radix) +#endif + +#ifdef HAVE__LTOA +#define SDL_ltoa _ltoa +#else +extern DECLSPEC char *SDLCALL SDL_ltoa(long value, char *string, int radix); +#endif + +#ifdef HAVE__UITOA +#define SDL_uitoa _uitoa +#else +#define SDL_uitoa(value, string, radix) SDL_ultoa((long)value, string, radix) +#endif + +#ifdef HAVE__ULTOA +#define SDL_ultoa _ultoa +#else +extern DECLSPEC char *SDLCALL SDL_ultoa(unsigned long value, char *string, + int radix); +#endif + +#ifdef HAVE_STRTOL +#define SDL_strtol strtol +#else +extern DECLSPEC long SDLCALL SDL_strtol(const char *string, char **endp, + int base); +#endif + +#ifdef HAVE_STRTOUL +#define SDL_strtoul strtoul +#else +extern DECLSPEC unsigned long SDLCALL SDL_strtoul(const char *string, + char **endp, int base); +#endif + +#ifdef SDL_HAS_64BIT_TYPE + +#ifdef HAVE__I64TOA +#define SDL_lltoa _i64toa +#else +extern DECLSPEC char *SDLCALL SDL_lltoa(Sint64 value, char *string, + int radix); +#endif + +#ifdef HAVE__UI64TOA +#define SDL_ulltoa _ui64toa +#else +extern DECLSPEC char *SDLCALL SDL_ulltoa(Uint64 value, char *string, + int radix); +#endif + +#ifdef HAVE_STRTOLL +#define SDL_strtoll strtoll +#else +extern DECLSPEC Sint64 SDLCALL SDL_strtoll(const char *string, char **endp, + int base); +#endif + +#ifdef HAVE_STRTOULL +#define SDL_strtoull strtoull +#else +extern DECLSPEC Uint64 SDLCALL SDL_strtoull(const char *string, char **endp, + int base); +#endif + +#endif /* SDL_HAS_64BIT_TYPE */ + +#ifdef HAVE_STRTOD +#define SDL_strtod strtod +#else +extern DECLSPEC double SDLCALL SDL_strtod(const char *string, char **endp); +#endif + +#ifdef HAVE_ATOI +#define SDL_atoi atoi +#else +#define SDL_atoi(X) SDL_strtol(X, NULL, 0) +#endif + +#ifdef HAVE_ATOF +#define SDL_atof atof +#else +#define SDL_atof(X) SDL_strtod(X, NULL) +#endif + +#ifdef HAVE_STRCMP +#define SDL_strcmp strcmp +#else +extern DECLSPEC int SDLCALL SDL_strcmp(const char *str1, const char *str2); +#endif + +#ifdef HAVE_STRNCMP +#define SDL_strncmp strncmp +#else +extern DECLSPEC int SDLCALL SDL_strncmp(const char *str1, const char *str2, + size_t maxlen); +#endif + +#ifdef HAVE_STRCASECMP +#define SDL_strcasecmp strcasecmp +#elif defined(HAVE__STRICMP) +#define SDL_strcasecmp _stricmp +#else +extern DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, + const char *str2); +#endif + +#ifdef HAVE_STRNCASECMP +#define SDL_strncasecmp strncasecmp +#elif defined(HAVE__STRNICMP) +#define SDL_strncasecmp _strnicmp +#else +extern DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, + const char *str2, size_t maxlen); +#endif + +#ifdef HAVE_SSCANF +#define SDL_sscanf sscanf +#else +extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, const char *fmt, + ...); +#endif + +#ifdef HAVE_SNPRINTF +#define SDL_snprintf snprintf +#else +extern DECLSPEC int SDLCALL SDL_snprintf(char *text, size_t maxlen, + const char *fmt, ...); +#endif + +#ifdef HAVE_VSNPRINTF +#define SDL_vsnprintf vsnprintf +#else +extern DECLSPEC int SDLCALL SDL_vsnprintf(char *text, size_t maxlen, + const char *fmt, va_list ap); +#endif + +#ifndef HAVE_M_PI +#define M_PI 3.14159265358979323846264338327950288 /* pi */ +#endif + +#ifdef HAVE_CEIL +#define SDL_ceil ceil +#else +#define SDL_ceil(x) ((double)(int)((x)+0.5)) +#endif + +#ifdef HAVE_COPYSIGN +#define SDL_copysign copysign +#else +extern DECLSPEC double SDLCALL SDL_copysign(double x, double y); +#endif + +#ifdef HAVE_COS +#define SDL_cos cos +#else +extern DECLSPEC double SDLCALL SDL_cos(double x); +#endif + +#ifdef HAVE_COSF +#define SDL_cosf cosf +#else +#define SDL_cosf(x) (float)SDL_cos((double)x) +#endif + +#ifdef HAVE_FABS +#define SDL_fabs fabs +#else +extern DECLSPEC double SDLCALL SDL_fabs(double x); +#endif + +#ifdef HAVE_FLOOR +#define SDL_floor floor +#else +extern DECLSPEC double SDLCALL SDL_floor(double x); +#endif + +#ifdef HAVE_LOG +#define SDL_log log +#else +extern DECLSPEC double SDLCALL SDL_log(double x); +#endif + +#ifdef HAVE_POW +#define SDL_pow pow +#else +extern DECLSPEC double SDLCALL SDL_pow(double x, double y); +#endif + +#ifdef HAVE_SCALBN +#define SDL_scalbn scalbn +#else +extern DECLSPEC double SDLCALL SDL_scalbn(double x, int n); +#endif + +#ifdef HAVE_SIN +#define SDL_sin sin +#else +extern DECLSPEC double SDLCALL SDL_sin(double x); +#endif + +#ifdef HAVE_SINF +#define SDL_sinf sinf +#else +#define SDL_sinf(x) (float)SDL_sin((double)x) +#endif + +#ifdef HAVE_SQRT +#define SDL_sqrt sqrt +#else +extern DECLSPEC double SDLCALL SDL_sqrt(double x); +#endif + +/* The SDL implementation of iconv() returns these error codes */ +#define SDL_ICONV_ERROR (size_t)-1 +#define SDL_ICONV_E2BIG (size_t)-2 +#define SDL_ICONV_EILSEQ (size_t)-3 +#define SDL_ICONV_EINVAL (size_t)-4 + +#if defined(HAVE_ICONV) && defined(HAVE_ICONV_H) +#define SDL_iconv_t iconv_t +#define SDL_iconv_open iconv_open +#define SDL_iconv_close iconv_close +#else +typedef struct _SDL_iconv_t *SDL_iconv_t; +extern DECLSPEC SDL_iconv_t SDLCALL SDL_iconv_open(const char *tocode, + const char *fromcode); +extern DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd); +#endif +extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, + size_t * inbytesleft, char **outbuf, + size_t * outbytesleft); +/** + * This function converts a string between encodings in one pass, returning a + * string that must be freed with SDL_free() or NULL on error. + */ +extern DECLSPEC char *SDLCALL SDL_iconv_string(const char *tocode, + const char *fromcode, + const char *inbuf, + size_t inbytesleft); +#define SDL_iconv_utf8_locale(S) SDL_iconv_string("", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4", "UTF-8", S, SDL_strlen(S)+1) + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_stdinc_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/haptic/nds/SDL_syshaptic.c b/src/haptic/nds/SDL_syshaptic.c index 6cf9518b2..7ba3c90e5 100644 --- a/src/haptic/nds/SDL_syshaptic.c +++ b/src/haptic/nds/SDL_syshaptic.c @@ -43,35 +43,35 @@ typedef struct } NDS_HapticData; - void -NDS_EZF_OpenNorWrite() +void +NDS_EZF_OpenNorWrite() { - GBA_BUS[0x0FF0000] = 0xD200; - GBA_BUS[0x0000000] = 0x1500; - GBA_BUS[0x0010000] = 0xD200; - GBA_BUS[0x0020000] = 0x1500; - GBA_BUS[0x0E20000] = 0x1500; - GBA_BUS[0x0FE0000] = 0x1500; - } void + GBA_BUS[0x0FF0000] = 0xD200; + GBA_BUS[0x0000000] = 0x1500; + GBA_BUS[0x0010000] = 0xD200; + GBA_BUS[0x0020000] = 0x1500; + GBA_BUS[0x0E20000] = 0x1500; + GBA_BUS[0x0FE0000] = 0x1500; +} void -NDS_EZF_CloseNorWrite() +NDS_EZF_CloseNorWrite() { - GBA_BUS[0x0FF0000] = 0xD200; - GBA_BUS[0x0000000] = 0x1500; - GBA_BUS[0x0010000] = 0xD200; - GBA_BUS[0x0020000] = 0x1500; - GBA_BUS[0x0E20000] = 0xD200; - GBA_BUS[0x0FE0000] = 0x1500; - } + GBA_BUS[0x0FF0000] = 0xD200; + GBA_BUS[0x0000000] = 0x1500; + GBA_BUS[0x0010000] = 0xD200; + GBA_BUS[0x0020000] = 0x1500; + GBA_BUS[0x0E20000] = 0xD200; + GBA_BUS[0x0FE0000] = 0x1500; +} void NDS_EZF_ChipReset() { - GBA_BUS[0x0000] = 0x00F0; - GBA_BUS[0x1000] = 0x00F0; -} uint32 NDS_EZF_IsPresent() + GBA_BUS[0x0000] = 0x00F0; + GBA_BUS[0x1000] = 0x00F0; +} uint32 NDS_EZF_IsPresent() { - vuint16 id1, id2; + vuint16 id1, id2; NDS_EZF_OpenNorWrite(); @@ -81,35 +81,35 @@ NDS_EZF_ChipReset() GBA_BUS[0x1555] = 0x00AA; GBA_BUS[0x12AA] = 0x0055; GBA_BUS[0x1555] = 0x0090; - id1 = GBA_BUS[0x0001]; - id2 = GBA_BUS[0x1001]; - if ((id1 != 0x227E) || (id2 != 0x227E)) { + id1 = GBA_BUS[0x0001]; + id2 = GBA_BUS[0x1001]; + if ((id1 != 0x227E) || (id2 != 0x227E)) { NDS_EZF_CloseNorWrite(); - return 0; + return 0; } - id1 = GBA_BUS[0x000E]; - id2 = GBA_BUS[0x100E]; + id1 = GBA_BUS[0x000E]; + id2 = GBA_BUS[0x100E]; NDS_EZF_CloseNorWrite(); - if (id1 == 0x2218 && id2 == 0x2218) { - return 1; + if (id1 == 0x2218 && id2 == 0x2218) { + return 1; } - return 0; - } - void -NDS_EZF_SetShake(u8 pos) + return 0; +} +void +NDS_EZF_SetShake(u8 pos) { u16 data = ((pos % 3) | 0x00F0); - GBA_BUS[0x0FF0000] = 0xD200; - GBA_BUS[0x0000000] = 0x1500; - GBA_BUS[0x0010000] = 0xD200; - GBA_BUS[0x0020000] = 0x1500; - GBA_BUS[0x0F10000] = data; - GBA_BUS[0x0FE0000] = 0x1500; + GBA_BUS[0x0FF0000] = 0xD200; + GBA_BUS[0x0000000] = 0x1500; + GBA_BUS[0x0010000] = 0xD200; + GBA_BUS[0x0020000] = 0x1500; + GBA_BUS[0x0F10000] = data; + GBA_BUS[0x0FE0000] = 0x1500; GBA_BUS[0] = 0x0000; /* write any value for vibration. */ GBA_BUS[0] = 0x0002; - } +} static int SDL_SYS_LogicError(void) diff --git a/src/joystick/nds/SDL_sysjoystick.c b/src/joystick/nds/SDL_sysjoystick.c index cdfbdacac..e885a5da0 100644 --- a/src/joystick/nds/SDL_sysjoystick.c +++ b/src/joystick/nds/SDL_sysjoystick.c @@ -45,7 +45,7 @@ int SDL_SYS_JoystickInit(void) { SDL_numjoysticks = 1; - return (1); + return (1); } /* Function to get the device-dependent name of a joystick */ @@ -73,7 +73,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick) return 0; } - + /* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, * but instead should call SDL_PrivateJoystick*() to deliver events @@ -84,8 +84,8 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { u32 keysd, keysu; int magnitude = 16384; - - /*scanKeys(); - this is done in PumpEvents, because touch uses it too */ + + /*scanKeys(); - this is done in PumpEvents, because touch uses it too */ keysd = keysDown(); keysu = keysUp(); @@ -101,61 +101,61 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) if ((keysd & KEY_RIGHT)) { SDL_PrivateJoystickAxis(joystick, 0, magnitude); } - if ((keysu & (KEY_UP | KEY_DOWN))) { + if ((keysu & (KEY_UP | KEY_DOWN))) { SDL_PrivateJoystickAxis(joystick, 1, 0); } - if ((keysu & (KEY_LEFT | KEY_RIGHT))) { + if ((keysu & (KEY_LEFT | KEY_RIGHT))) { SDL_PrivateJoystickAxis(joystick, 0, 0); } - if ((keysd & KEY_A)) { + if ((keysd & KEY_A)) { SDL_PrivateJoystickButton(joystick, 0, SDL_PRESSED); } - if ((keysd & KEY_B)) { + if ((keysd & KEY_B)) { SDL_PrivateJoystickButton(joystick, 1, SDL_PRESSED); } - if ((keysd & KEY_X)) { + if ((keysd & KEY_X)) { SDL_PrivateJoystickButton(joystick, 2, SDL_PRESSED); } - if ((keysd & KEY_Y)) { + if ((keysd & KEY_Y)) { SDL_PrivateJoystickButton(joystick, 3, SDL_PRESSED); } - if ((keysd & KEY_L)) { + if ((keysd & KEY_L)) { SDL_PrivateJoystickButton(joystick, 4, SDL_PRESSED); } - if ((keysd & KEY_R)) { + if ((keysd & KEY_R)) { SDL_PrivateJoystickButton(joystick, 5, SDL_PRESSED); } - if ((keysd & KEY_SELECT)) { + if ((keysd & KEY_SELECT)) { SDL_PrivateJoystickButton(joystick, 6, SDL_PRESSED); } - if ((keysd & KEY_START)) { + if ((keysd & KEY_START)) { SDL_PrivateJoystickButton(joystick, 7, SDL_PRESSED); } - if ((keysu & KEY_A)) { + if ((keysu & KEY_A)) { SDL_PrivateJoystickButton(joystick, 0, SDL_RELEASED); } - if ((keysu & KEY_B)) { + if ((keysu & KEY_B)) { SDL_PrivateJoystickButton(joystick, 1, SDL_RELEASED); } - if ((keysu & KEY_X)) { + if ((keysu & KEY_X)) { SDL_PrivateJoystickButton(joystick, 2, SDL_RELEASED); } - if ((keysu & KEY_Y)) { + if ((keysu & KEY_Y)) { SDL_PrivateJoystickButton(joystick, 3, SDL_RELEASED); } - if ((keysu & KEY_L)) { + if ((keysu & KEY_L)) { SDL_PrivateJoystickButton(joystick, 4, SDL_RELEASED); } - if ((keysu & KEY_R)) { + if ((keysu & KEY_R)) { SDL_PrivateJoystickButton(joystick, 5, SDL_RELEASED); } - if ((keysu & KEY_SELECT)) { + if ((keysu & KEY_SELECT)) { SDL_PrivateJoystickButton(joystick, 6, SDL_RELEASED); } - if ((keysu & KEY_START)) { + if ((keysu & KEY_START)) { SDL_PrivateJoystickButton(joystick, 7, SDL_RELEASED); } - } +} /* Function to close a joystick after use */ void diff --git a/src/video/win32/SDL_win32video.c b/src/video/win32/SDL_win32video.c index f3bddacc5..4352403d9 100644 --- a/src/video/win32/SDL_win32video.c +++ b/src/video/win32/SDL_win32video.c @@ -1,230 +1,230 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#include "SDL_main.h" -#include "SDL_video.h" -#include "SDL_mouse.h" -#include "../SDL_sysvideo.h" -#include "../SDL_pixels_c.h" - -#include "SDL_win32video.h" -#include "SDL_d3drender.h" -#include "SDL_gdirender.h" - -/* Initialization/Query functions */ -static int WIN_VideoInit(_THIS); -static void WIN_VideoQuit(_THIS); - -/* Sets an error message based on GetLastError() */ -void -WIN_SetError(const char *prefix) -{ - TCHAR buffer[1024]; - char *message; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, - buffer, SDL_arraysize(buffer), NULL); - message = WIN_StringToUTF8(buffer); - SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ": " : "", message); - SDL_free(message); -} - -/* WIN32 driver bootstrap functions */ - -static int -WIN_Available(void) -{ - return (1); -} - -static void -WIN_DeleteDevice(SDL_VideoDevice * device) -{ - SDL_VideoData *data = (SDL_VideoData *) device->driverdata; - - SDL_UnregisterApp(); -#if SDL_VIDEO_RENDER_D3D - if (data->d3d) { - IDirect3D9_Release(data->d3d); - FreeLibrary(data->d3dDLL); - } -#endif -#if SDL_VIDEO_RENDER_DDRAW - if (data->ddraw) { - data->ddraw->lpVtbl->Release(data->ddraw); - FreeLibrary(data->ddrawDLL); - } -#endif - SDL_free(device->driverdata); - SDL_free(device); -} - -static SDL_VideoDevice * -WIN_CreateDevice(int devindex) -{ - SDL_VideoDevice *device; - SDL_VideoData *data; - - SDL_RegisterApp(NULL, 0, NULL); - - /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); - if (device) { - data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); - } else { - data = NULL; - } - if (!data) { - SDL_OutOfMemory(); - if (device) { - SDL_free(device); - } - return NULL; - } - device->driverdata = data; - -#if SDL_VIDEO_RENDER_D3D - data->d3dDLL = LoadLibrary(TEXT("D3D9.DLL")); - if (data->d3dDLL) { - IDirect3D9 *(WINAPI * D3DCreate) (UINT SDKVersion); - - D3DCreate = - (IDirect3D9 * (WINAPI *) (UINT)) GetProcAddress(data->d3dDLL, - "Direct3DCreate9"); - if (D3DCreate) { - data->d3d = D3DCreate(D3D_SDK_VERSION); - } - if (!data->d3d) { - FreeLibrary(data->d3dDLL); - data->d3dDLL = NULL; - } - } -#endif /* SDL_VIDEO_RENDER_D3D */ -#if SDL_VIDEO_RENDER_DDRAW - data->ddrawDLL = LoadLibrary(TEXT("ddraw.dll")); - if (data->ddrawDLL) { - IDirectDraw *(WINAPI * DDCreate) (GUID FAR * lpGUID, - LPDIRECTDRAW FAR * lplpDD, - IUnknown FAR * pUnkOuter); - - DDCreate = - (IDirectDraw * - (WINAPI *) (GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *)) - GetProcAddress(data->ddrawDLL, TEXT("DirectDrawCreate")); - if (!DDCreate || DDCreate(NULL, &data->ddraw, NULL) != DD_OK) { - FreeLibrary(data->ddrawDLL); - data->ddrawDLL = NULL; - data->ddraw = NULL; - } - } -#endif /* SDL_VIDEO_RENDER_DDRAW */ - - /* Set the function pointers */ - device->VideoInit = WIN_VideoInit; - device->VideoQuit = WIN_VideoQuit; - device->GetDisplayBounds = WIN_GetDisplayBounds; - device->GetDisplayModes = WIN_GetDisplayModes; - device->SetDisplayMode = WIN_SetDisplayMode; - device->SetDisplayGammaRamp = WIN_SetDisplayGammaRamp; - device->GetDisplayGammaRamp = WIN_GetDisplayGammaRamp; - device->PumpEvents = WIN_PumpEvents; - -#undef CreateWindow - device->CreateWindow = WIN_CreateWindow; - device->CreateWindowFrom = WIN_CreateWindowFrom; - device->SetWindowTitle = WIN_SetWindowTitle; - device->SetWindowIcon = WIN_SetWindowIcon; - device->SetWindowPosition = WIN_SetWindowPosition; - device->SetWindowSize = WIN_SetWindowSize; - device->ShowWindow = WIN_ShowWindow; - device->HideWindow = WIN_HideWindow; - device->RaiseWindow = WIN_RaiseWindow; - device->MaximizeWindow = WIN_MaximizeWindow; - device->MinimizeWindow = WIN_MinimizeWindow; - device->RestoreWindow = WIN_RestoreWindow; - device->SetWindowGrab = WIN_SetWindowGrab; - device->DestroyWindow = WIN_DestroyWindow; - device->GetWindowWMInfo = WIN_GetWindowWMInfo; -#ifdef SDL_VIDEO_OPENGL_WGL - device->GL_LoadLibrary = WIN_GL_LoadLibrary; - device->GL_GetProcAddress = WIN_GL_GetProcAddress; - device->GL_UnloadLibrary = WIN_GL_UnloadLibrary; - device->GL_CreateContext = WIN_GL_CreateContext; - device->GL_MakeCurrent = WIN_GL_MakeCurrent; - device->GL_SetSwapInterval = WIN_GL_SetSwapInterval; - device->GL_GetSwapInterval = WIN_GL_GetSwapInterval; - 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; - device->HasClipboardText = WIN_HasClipboardText; - - device->free = WIN_DeleteDevice; - - return device; -} - -VideoBootStrap WIN32_bootstrap = { - "win32", "SDL Win32/64 video driver", WIN_Available, WIN_CreateDevice -}; - - -int -WIN_VideoInit(_THIS) -{ - if (WIN_InitModes(_this) < 0) { - return -1; - } - -#if SDL_VIDEO_RENDER_D3D - D3D_AddRenderDriver(_this); -#endif -#if SDL_VIDEO_RENDER_DDRAW - DDRAW_AddRenderDriver(_this); -#endif -#if SDL_VIDEO_RENDER_GDI - GDI_AddRenderDriver(_this); -#endif -#if SDL_VIDEO_RENDER_GAPI - GAPI_AddRenderDriver(_this); -#endif - - WIN_InitKeyboard(_this); - WIN_InitMouse(_this); - - return 0; -} - -void -WIN_VideoQuit(_THIS) -{ - WIN_QuitModes(_this); - WIN_QuitKeyboard(_this); - WIN_QuitMouse(_this); -} - -/* vim: set ts=4 sw=4 expandtab: */ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_main.h" +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" + +#include "SDL_win32video.h" +#include "SDL_d3drender.h" +#include "SDL_gdirender.h" + +/* Initialization/Query functions */ +static int WIN_VideoInit(_THIS); +static void WIN_VideoQuit(_THIS); + +/* Sets an error message based on GetLastError() */ +void +WIN_SetError(const char *prefix) +{ + TCHAR buffer[1024]; + char *message; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, + buffer, SDL_arraysize(buffer), NULL); + message = WIN_StringToUTF8(buffer); + SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ": " : "", message); + SDL_free(message); +} + +/* WIN32 driver bootstrap functions */ + +static int +WIN_Available(void) +{ + return (1); +} + +static void +WIN_DeleteDevice(SDL_VideoDevice * device) +{ + SDL_VideoData *data = (SDL_VideoData *) device->driverdata; + + SDL_UnregisterApp(); +#if SDL_VIDEO_RENDER_D3D + if (data->d3d) { + IDirect3D9_Release(data->d3d); + FreeLibrary(data->d3dDLL); + } +#endif +#if SDL_VIDEO_RENDER_DDRAW + if (data->ddraw) { + data->ddraw->lpVtbl->Release(data->ddraw); + FreeLibrary(data->ddrawDLL); + } +#endif + SDL_free(device->driverdata); + SDL_free(device); +} + +static SDL_VideoDevice * +WIN_CreateDevice(int devindex) +{ + SDL_VideoDevice *device; + SDL_VideoData *data; + + SDL_RegisterApp(NULL, 0, NULL); + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (device) { + data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); + } else { + data = NULL; + } + if (!data) { + SDL_OutOfMemory(); + if (device) { + SDL_free(device); + } + return NULL; + } + device->driverdata = data; + +#if SDL_VIDEO_RENDER_D3D + data->d3dDLL = LoadLibrary(TEXT("D3D9.DLL")); + if (data->d3dDLL) { + IDirect3D9 *(WINAPI * D3DCreate) (UINT SDKVersion); + + D3DCreate = + (IDirect3D9 * (WINAPI *) (UINT)) GetProcAddress(data->d3dDLL, + "Direct3DCreate9"); + if (D3DCreate) { + data->d3d = D3DCreate(D3D_SDK_VERSION); + } + if (!data->d3d) { + FreeLibrary(data->d3dDLL); + data->d3dDLL = NULL; + } + } +#endif /* SDL_VIDEO_RENDER_D3D */ +#if SDL_VIDEO_RENDER_DDRAW + data->ddrawDLL = LoadLibrary(TEXT("ddraw.dll")); + if (data->ddrawDLL) { + IDirectDraw *(WINAPI * DDCreate) (GUID FAR * lpGUID, + LPDIRECTDRAW FAR * lplpDD, + IUnknown FAR * pUnkOuter); + + DDCreate = + (IDirectDraw * + (WINAPI *) (GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *)) + GetProcAddress(data->ddrawDLL, TEXT("DirectDrawCreate")); + if (!DDCreate || DDCreate(NULL, &data->ddraw, NULL) != DD_OK) { + FreeLibrary(data->ddrawDLL); + data->ddrawDLL = NULL; + data->ddraw = NULL; + } + } +#endif /* SDL_VIDEO_RENDER_DDRAW */ + + /* Set the function pointers */ + device->VideoInit = WIN_VideoInit; + device->VideoQuit = WIN_VideoQuit; + device->GetDisplayBounds = WIN_GetDisplayBounds; + device->GetDisplayModes = WIN_GetDisplayModes; + device->SetDisplayMode = WIN_SetDisplayMode; + device->SetDisplayGammaRamp = WIN_SetDisplayGammaRamp; + device->GetDisplayGammaRamp = WIN_GetDisplayGammaRamp; + device->PumpEvents = WIN_PumpEvents; + +#undef CreateWindow + device->CreateWindow = WIN_CreateWindow; + device->CreateWindowFrom = WIN_CreateWindowFrom; + device->SetWindowTitle = WIN_SetWindowTitle; + device->SetWindowIcon = WIN_SetWindowIcon; + device->SetWindowPosition = WIN_SetWindowPosition; + device->SetWindowSize = WIN_SetWindowSize; + device->ShowWindow = WIN_ShowWindow; + device->HideWindow = WIN_HideWindow; + device->RaiseWindow = WIN_RaiseWindow; + device->MaximizeWindow = WIN_MaximizeWindow; + device->MinimizeWindow = WIN_MinimizeWindow; + device->RestoreWindow = WIN_RestoreWindow; + device->SetWindowGrab = WIN_SetWindowGrab; + device->DestroyWindow = WIN_DestroyWindow; + device->GetWindowWMInfo = WIN_GetWindowWMInfo; +#ifdef SDL_VIDEO_OPENGL_WGL + device->GL_LoadLibrary = WIN_GL_LoadLibrary; + device->GL_GetProcAddress = WIN_GL_GetProcAddress; + device->GL_UnloadLibrary = WIN_GL_UnloadLibrary; + device->GL_CreateContext = WIN_GL_CreateContext; + device->GL_MakeCurrent = WIN_GL_MakeCurrent; + device->GL_SetSwapInterval = WIN_GL_SetSwapInterval; + device->GL_GetSwapInterval = WIN_GL_GetSwapInterval; + 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; + device->HasClipboardText = WIN_HasClipboardText; + + device->free = WIN_DeleteDevice; + + return device; +} + +VideoBootStrap WIN32_bootstrap = { + "win32", "SDL Win32/64 video driver", WIN_Available, WIN_CreateDevice +}; + + +int +WIN_VideoInit(_THIS) +{ + if (WIN_InitModes(_this) < 0) { + return -1; + } + +#if SDL_VIDEO_RENDER_D3D + D3D_AddRenderDriver(_this); +#endif +#if SDL_VIDEO_RENDER_DDRAW + DDRAW_AddRenderDriver(_this); +#endif +#if SDL_VIDEO_RENDER_GDI + GDI_AddRenderDriver(_this); +#endif +#if SDL_VIDEO_RENDER_GAPI + GAPI_AddRenderDriver(_this); +#endif + + WIN_InitKeyboard(_this); + WIN_InitMouse(_this); + + return 0; +} + +void +WIN_VideoQuit(_THIS) +{ + WIN_QuitModes(_this); + WIN_QuitKeyboard(_this); + WIN_QuitMouse(_this); +} + +/* vim: set ts=4 sw=4 expandtab: */