forked from hajimehoshi/ebiten
-
Notifications
You must be signed in to change notification settings - Fork 0
/
api_windows.go
154 lines (130 loc) · 4.34 KB
/
api_windows.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Copyright 2024 The Ebitengine Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package textinput
import (
"fmt"
"runtime"
"unsafe"
"golang.org/x/sys/windows"
)
const (
_ATTR_TARGET_CONVERTED = 0x01
_ATTR_TARGET_NOTCONVERTED = 0x03
_CFS_CANDIDATEPOS = 0x0040
_GCS_COMPATTR = 0x0010
_GCS_COMPCLAUSE = 0x0020
_GCS_COMPSTR = 0x0008
_GCS_RESULTSTR = 0x0800
_GWL_WNDPROC = -4
_ISC_SHOWUICOMPOSITIONWINDOW = 0x80000000
_UNICODE_NOCHAR = 0xffff
_WM_CHAR = 0x0102
_WM_IME_COMPOSITION = 0x010F
_WM_IME_SETCONTEXT = 0x0281
_WM_SYSCHAR = 0x0106
_WM_UNICHAR = 0x0109
)
type (
_HIMC uintptr
)
type _CANDIDATEFORM struct {
dwIndex uint32
dwStyle uint32
ptCurrentPos _POINT
rcArea _RECT
}
type _POINT struct {
x int32
y int32
}
type _RECT struct {
left int32
top int32
right int32
bottom int32
}
var (
imm32 = windows.NewLazySystemDLL("imm32.dll")
user32 = windows.NewLazySystemDLL("user32.dll")
procImmGetCompositionStringW = imm32.NewProc("ImmGetCompositionStringW")
procImmGetContext = imm32.NewProc("ImmGetContext")
procImmReleaseContext = imm32.NewProc("ImmReleaseContext")
procImmSetCandidateWindow = imm32.NewProc("ImmSetCandidateWindow")
procCallWindowProcW = user32.NewProc("CallWindowProcW")
procGetActiveWindow = user32.NewProc("GetActiveWindow")
procSetWindowLongW = user32.NewProc("SetWindowLongW") // 32-Bit Windows version.
procSetWindowLongPtrW = user32.NewProc("SetWindowLongPtrW") // 64-Bit Windows version.
)
func _CallWindowProcW(lpPrevWndFunc uintptr, hWnd uintptr, msg uint32, wParam, lParam uintptr) uintptr {
r, _, _ := procCallWindowProcW.Call(lpPrevWndFunc, hWnd, uintptr(msg), wParam, lParam)
return r
}
func _GetActiveWindow() windows.HWND {
r, _, _ := procGetActiveWindow.Call()
return windows.HWND(r)
}
func _ImmGetCompositionStringW(unnamedParam1 _HIMC, unnamedParam2 uint32, lpBuf unsafe.Pointer, dwBufLen uint32) (uint32, error) {
r, _, e := procImmGetCompositionStringW.Call(uintptr(unnamedParam1), uintptr(unnamedParam2), uintptr(lpBuf), uintptr(dwBufLen))
runtime.KeepAlive(lpBuf)
if r < 0 {
return 0, fmt.Errorf("textinput: ImmGetCompositionStringW failed: %d", r)
}
if e != nil && e != windows.ERROR_SUCCESS {
return 0, fmt.Errorf("textinput: ImmGetCompositionStringW failed: %w", e)
}
return uint32(r), nil
}
func _ImmGetContext(unnamedParam1 windows.HWND) _HIMC {
r, _, _ := procImmGetContext.Call(uintptr(unnamedParam1))
return _HIMC(r)
}
func _ImmReleaseContext(unnamedParam1 windows.HWND, unnamedParam2 _HIMC) error {
r, _, e := procImmReleaseContext.Call(uintptr(unnamedParam1), uintptr(unnamedParam2))
if int32(r) == 0 {
if e != nil && e != windows.ERROR_SUCCESS {
return fmt.Errorf("textinput: ImmReleaseContext failed: %w", e)
}
return fmt.Errorf("textinput: ImmReleaseContext returned 0")
}
return nil
}
func _ImmSetCandidateWindow(unnamedParam1 _HIMC, lpCandidate *_CANDIDATEFORM) error {
r, _, e := procImmSetCandidateWindow.Call(uintptr(unnamedParam1), uintptr(unsafe.Pointer(lpCandidate)))
runtime.KeepAlive(lpCandidate)
if int32(r) == 0 {
if e != nil && e != windows.ERROR_SUCCESS {
return fmt.Errorf("textinput: ImmSetCandidateWindow failed: %w", e)
}
return fmt.Errorf("textinput: ImmSetCandidateWindow returned 0")
}
return nil
}
func _SetWindowLongPtrW(hWnd windows.HWND, nIndex int32, dwNewLong uintptr) (uintptr, error) {
var p *windows.LazyProc
if procSetWindowLongPtrW.Find() == nil {
// 64-Bit Windows.
p = procSetWindowLongPtrW
} else {
// 32-Bit Windows.
p = procSetWindowLongW
}
h, _, e := p.Call(uintptr(hWnd), uintptr(nIndex), dwNewLong)
if h == 0 {
if e != nil && e != windows.ERROR_SUCCESS {
return 0, fmt.Errorf("textinput: SetWindowLongPtrW failed: %w", e)
}
return 0, fmt.Errorf("textinput: SetWindowLongPtrW returned 0")
}
return h, nil
}