Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libSDL
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PocketInsanity
libSDL
Commits
aa7b525b
Commit
aa7b525b
authored
Aug 03, 2010
by
dewyatt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Large commit with initial reading string support, TSF UILess code, etc.
parent
12881b42
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
947 additions
and
160 deletions
+947
-160
SDL_win32keyboard.c
src/video/win32/SDL_win32keyboard.c
+797
-65
SDL_win32video.h
src/video/win32/SDL_win32video.h
+150
-95
No files found.
src/video/win32/SDL_win32keyboard.c
View file @
aa7b525b
...
...
@@ -26,8 +26,13 @@
#include "../../events/SDL_keyboard_c.h"
#include "../../events/scancodes_win32.h"
#include <msctf.h>
#include <imm.h>
#include <oleauto.h>
static
void
IME_Init
(
SDL_VideoData
*
videodata
,
HWND
hwnd
);
static
void
IME_Enable
(
SDL_VideoData
*
videodata
,
HWND
hwnd
);
static
void
IME_Disable
(
SDL_VideoData
*
videodata
,
HWND
hwnd
);
static
void
IME_Quit
(
SDL_VideoData
*
videodata
);
#ifndef MAPVK_VK_TO_VSC
#define MAPVK_VK_TO_VSC 0
...
...
@@ -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,35 +189,56 @@ WIN_SetTextInputRect(_THIS, SDL_Rect *rect)
}
void
IME_Disable
(
SDL_VideoData
*
videodata
,
HWND
hwnd
)
{
if
(
!
videodata
->
ime_initialized
||
!
videodata
->
ime_hwnd_current
)
return
;
#define LANG_CHT MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)
#define LANG_CHS MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)
if
(
videodata
->
ime_hwnd_current
==
videodata
->
ime_hwnd_main
)
ImmAssociateContext
(
videodata
->
ime_hwnd_current
,
NULL
);
#define MAKEIMEVERSION(major,minor) ((DWORD) (((BYTE)(major) << 24) | ((BYTE)(minor) << 16) ))
#define IMEID_VER(id) ((id) & 0xffff0000)
#define IMEID_LANG(id) ((id) & 0x0000ffff)
videodata
->
ime_enabled
=
SDL_FALSE
;
}
#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))
void
IME_Enable
(
SDL_VideoData
*
videodata
,
HWND
hwnd
)
{
if
(
!
videodata
->
ime_initialized
||
!
videodata
->
ime_hwnd_current
)
return
;
#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))
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
);
#define LANG() LOWORD((videodata->ime_hkl))
#define PRIMLANG() ((WORD)PRIMARYLANGID(LANG()))
#define SUBLANG() SUBLANGID(LANG())
videodata
->
ime_enabled
=
SDL_TRUE
;
}
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)))
void
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
)
...
...
@@ -209,17 +247,20 @@ IME_Init(SDL_VideoData *videodata, HWND hwnd)
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
);
CoCreateInstance
(
&
CLSID_TF_ThreadMgr
,
NULL
,
CLSCTX_INPROC_SERVER
,
&
IID_ITfThreadMgr
,
&
videodata
->
ime_threadmgr
);
}
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_himm32
=
LoadLibraryA
(
"imm32.dll"
);
if
(
!
videodata
->
ime_himm32
)
{
videodata
->
ime_available
=
SDL_FALSE
;
return
;
}
videodata
->
ImmLockIMC
=
(
LPINPUTCONTEXT2
(
WINAPI
*
)(
HIMC
))
GetProcAddress
(
videodata
->
ime_himm32
,
"ImmLockIMC"
);
videodata
->
ImmUnlockIMC
=
(
BOOL
(
WINAPI
*
)(
HIMC
))
GetProcAddress
(
videodata
->
ime_himm32
,
"ImmUnlockIMC"
);
videodata
->
ImmLockIMCC
=
(
LPVOID
(
WINAPI
*
)(
HIMCC
))
GetProcAddress
(
videodata
->
ime_himm32
,
"ImmLockIMCC"
);
videodata
->
ImmUnlockIMCC
=
(
BOOL
(
WINAPI
*
)(
HIMCC
))
GetProcAddress
(
videodata
->
ime_himm32
,
"ImmUnlockIMCC"
);
IME_SetWindow
(
videodata
,
hwnd
);
videodata
->
ime_himc
=
ImmGetContext
(
hwnd
);
ImmReleaseContext
(
hwnd
,
videodata
->
ime_himc
);
if
(
!
videodata
->
ime_himc
)
{
...
...
@@ -228,24 +269,66 @@ IME_Init(SDL_VideoData *videodata, HWND 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
)
return
;
if
(
!
videodata
->
ime_available
)
{
IME_Disable
(
videodata
,
hwnd
);
return
;
}
if
(
videodata
->
ime_hwnd_current
==
videodata
->
ime_hwnd_main
)
ImmAssociateContext
(
videodata
->
ime_hwnd_current
,
videodata
->
ime_himc
);
videodata
->
ime_enabled
=
SDL_TRUE
;
IME_UpdateInputLocale
(
videodata
);
UILess_EnableUIUpdates
(
videodata
);
}
static
void
IME_Disable
(
SDL_VideoData
*
videodata
,
HWND
hwnd
)
{
if
(
!
videodata
->
ime_initialized
||
!
videodata
->
ime_hwnd_current
)
return
;
IME_ClearComposition
(
videodata
);
if
(
videodata
->
ime_hwnd_current
==
videodata
->
ime_hwnd_main
)
ImmAssociateContext
(
videodata
->
ime_hwnd_current
,
NULL
);
videodata
->
ime_enabled
=
SDL_FALSE
;
UILess_DisableUIUpdates
(
videodata
);
}
static
void
IME_Quit
(
SDL_VideoData
*
videodata
)
{
if
(
!
videodata
->
ime_initialized
)
return
;
UILess_ReleaseSinks
(
videodata
);
if
(
videodata
->
ime_hwnd_main
)
ImmAssociateContext
(
videodata
->
ime_hwnd_main
,
videodata
->
ime_himc
);
videodata
->
ime_hwnd_main
=
0
;
videodata
->
ime_himc
=
0
;
if
(
videodata
->
ime_
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: */
src/video/win32/SDL_win32video.h
View file @
aa7b525b
/*
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 <windows.h>
#if SDL_VIDEO_RENDER_D3D
//#include <d3d9.h>
#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 <objbase.h>
#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 <windows.h>
#include <msctf.h>
#if SDL_VIDEO_RENDER_D3D
//#include <d3d9.h>
#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 <objbase.h>
#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: */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment