Documentation ordinal fixes.
[wine] / dlls / imm32 / imewnd.c
1 /*
2  *      Implementation of the 'IME window' class
3  *
4  *      Copyright 2000 Hidenori Takeshima
5  *
6  *
7  * FIXME:
8  *      - handle all messages.
9  *      - handle all notifications.
10  */
11
12 #include "config.h"
13
14 #include "winbase.h"
15 #include "windef.h"
16 #include "wingdi.h"
17 #include "winuser.h"
18 #include "winerror.h"
19 #include "immddk.h"
20
21 #include "debugtools.h"
22 DEFAULT_DEBUG_CHANNEL(imm);
23
24 #include "imm_private.h"
25
26 #define IMM32_CONVERSION_BUFSIZE                200
27
28 static CHAR IMM32_szIMEClass[] = "IME";
29 static CHAR IMM32_szIMEWindowName[] = "Default IME";
30
31 typedef struct
32 {
33         HWND    hwndSelf;
34         HWND    hwndActive;
35         DWORD   dwBufUsed;
36         union
37         {
38                 CHAR    A[IMM32_CONVERSION_BUFSIZE];
39                 WCHAR   W[IMM32_CONVERSION_BUFSIZE];
40         }               buf;
41 } IMM32_IMEWNDPARAM;
42
43
44 static BOOL IMM32_IsUIMessage( UINT nMsg );
45
46 static
47 LRESULT IMM32_IMEWnd_WM_KEYDOWN( IMM32_IMEWNDPARAM* pParam,
48                                  WPARAM wParam, LPARAM lParam )
49 {
50         BYTE                    bKeyState[ 256 ];
51         DWORD                   dwTransBufSize;
52         UINT                    nNumOfMsg;
53         LRESULT                 lr;
54         HIMC                    hIMC;
55         IMM32_IMC*              pIMC;
56         const IMM32_IMEKL*      pkl;
57
58         if ( pParam->hwndActive == (HWND)NULL )
59                 return 0;
60
61         /* get context -> get pkl. */
62         hIMC = ImmGetContext( pParam->hwndActive );
63         if ( hIMC == NULLIMC )
64                 return 0;
65         pIMC = IMM32_LockIMC( hIMC );
66         if ( pIMC == NULL )
67         {
68                 ImmReleaseContext( pParam->hwndActive, hIMC );
69                 return 0;
70         }
71         pkl = pIMC->pkl;
72
73         GetKeyboardState( bKeyState );
74         if ( !pkl->handlers.pImeProcessKey
75                 ( hIMC, wParam, lParam, bKeyState ) )
76         {
77                 lr = SendMessageA( pParam->hwndActive, WM_IME_KEYDOWN,
78                                    wParam, lParam );
79                 goto end;
80         }
81
82         dwTransBufSize = 0;
83         nNumOfMsg = pkl->handlers.pImeToAsciiEx
84                 ( wParam, (lParam>>16)&0xff, 
85                   bKeyState, &dwTransBufSize,
86                   0, /* FIXME!!! - 1 if a menu is active */
87                   hIMC );
88
89         /* FIXME - process generated messages */
90         /* I cannot use ImmGenerateMessage() since
91          * the IME window must handle generated messages. */
92
93         /* NOTE - I must check pkl->fUnicode. */
94         FIXME( "%d messages generated.\n", nNumOfMsg );
95
96         lr = 0;
97 end:
98         IMM32_UnlockIMC( hIMC );
99         ImmReleaseContext( pParam->hwndActive, hIMC );
100
101         return lr;
102 }
103
104 static
105 LRESULT IMM32_IMEWnd_WM_KEYUP( IMM32_IMEWNDPARAM* pParam,
106                                WPARAM wParam, LPARAM lParam )
107 {
108         BYTE                    bKeyState[ 256 ];
109         LRESULT                 lr;
110         HIMC                    hIMC;
111         IMM32_IMC*              pIMC;
112         const IMM32_IMEKL*      pkl;
113
114         if ( pParam->hwndActive == (HWND)NULL )
115                 return 0;
116
117         /* get context -> get pkl. */
118         hIMC = ImmGetContext( pParam->hwndActive );
119         if ( hIMC == NULLIMC )
120                 return 0;
121         pIMC = IMM32_LockIMC( hIMC );
122         if ( pIMC == NULL )
123         {
124                 ImmReleaseContext( pParam->hwndActive, hIMC );
125                 return 0;
126         }
127         pkl = pIMC->pkl;
128
129         GetKeyboardState( bKeyState );
130         if ( !pkl->handlers.pImeProcessKey
131                 ( hIMC, wParam, lParam, bKeyState ) )
132         {
133                 lr = SendMessageA( pParam->hwndActive, WM_IME_KEYUP,
134                                    wParam, lParam );
135                 goto end;
136         }
137
138         lr = 0;
139 end:
140         IMM32_UnlockIMC( hIMC );
141         ImmReleaseContext( pParam->hwndActive, hIMC );
142
143         return lr;
144 }
145
146
147 static
148 LRESULT CALLBACK IMM32_IMEWndProc( HWND hwnd, UINT nMsg,
149                                    WPARAM wParam, LPARAM lParam )
150 {
151         IMM32_IMEWNDPARAM* pParam =
152                 (IMM32_IMEWNDPARAM*)GetWindowLongA( hwnd, 0L );
153
154         if ( nMsg == WM_CREATE )
155         {
156                 pParam = (IMM32_IMEWNDPARAM*)IMM32_HeapAlloc(
157                                 HEAP_ZERO_MEMORY, sizeof(IMM32_IMEWNDPARAM) );
158                 if ( pParam == NULL )
159                         return -1L;
160                 SetWindowLongA( hwnd, 0L, (LONG)pParam );
161
162                 /* Initialize pParam. */
163                 pParam->hwndSelf = hwnd;
164                 pParam->hwndActive = (HWND)NULL;
165                 pParam->dwBufUsed = 0;
166
167                 return 0;
168         }
169         else if ( nMsg == WM_DESTROY )
170         {
171                 /* Uninitialize pParam. */
172
173                 IMM32_HeapFree( pParam );
174                 SetWindowLongA( hwnd, 0L, (LONG)NULL );
175                 return 0;
176         }
177
178         if ( pParam == NULL )
179         {
180                 if ( IMM32_IsUIMessage( nMsg ) )
181                         return 0;
182                 return DefWindowProcA( hwnd, nMsg, wParam, lParam );
183         }
184
185         /* FIXME - handle all messages. */
186         /* FIXME - handle all notifications. */
187         switch ( nMsg )
188         {
189         case WM_KEYDOWN:
190                 return IMM32_IMEWnd_WM_KEYDOWN( pParam, wParam, lParam );
191         case WM_KEYUP:
192                 return IMM32_IMEWnd_WM_KEYUP( pParam, wParam, lParam );
193         case WM_IME_KEYDOWN:
194                 ERR( "Why WM_IME_KEYDOWN is generated?" );
195                 return 0;
196         case WM_IME_KEYUP:
197                 ERR( "Why WM_IME_KEYUP is generated?" );
198                 return 0;
199         case WM_IME_CHAR:
200                 FIXME( "ignore WM_IME_CHAR - wParam %08x, lParam %08lx.\n",
201                        wParam, lParam );
202                 return 0;
203         case WM_CHAR:
204                 /* TranslateMessage don't support IME HKL. - FIXME? */
205                 FIXME( "ignore WM_CHAR - wParam %08x, lParam %08lx.\n",
206                        wParam, lParam );
207                 return 0;
208         case WM_IME_CONTROL:
209         case WM_IME_REQUEST:
210         case WM_IME_STARTCOMPOSITION:
211         case WM_IME_ENDCOMPOSITION:
212         case WM_IME_COMPOSITION:
213         case WM_IME_SETCONTEXT:
214         case WM_IME_NOTIFY:
215         case WM_IME_COMPOSITIONFULL:
216         case WM_IME_SELECT:
217         case 0x287: /* What is this message? IMM32.DLL returns TRUE. */
218                 FIXME( "handle message %08x\n", nMsg );
219                 return 0;
220         }
221
222         return DefWindowProcA( hwnd, nMsg, wParam, lParam );
223 }
224
225
226 /***********************************************************************
227  *              IMM32_RegisterClass (internal)
228  */
229 BOOL IMM32_RegisterIMEWndClass( HINSTANCE hInstDLL )
230 {
231         WNDCLASSA       wc;
232
233         /* SDK says the "IME" window class is a system global class. */
234         wc.style                = CS_GLOBALCLASS;
235         wc.lpfnWndProc          = IMM32_IMEWndProc;
236         wc.cbClsExtra           = 0;
237         wc.cbWndExtra           = sizeof(LONG);
238         wc.hInstance            = hInstDLL;
239         wc.hIcon                = (HICON)NULL;
240         wc.hCursor              = LoadCursorA((HINSTANCE)NULL,IDC_ARROWA);
241         wc.hbrBackground        = (HBRUSH)NULL;
242         wc.lpszMenuName         = NULL;
243         wc.lpszClassName        = IMM32_szIMEClass;
244         if ( !RegisterClassA( &wc ) )
245                 return FALSE;
246
247         return TRUE;
248 }
249
250 /***********************************************************************
251  *              IMM32_UnregisterClass (internal)
252  */
253 void IMM32_UnregisterIMEWndClass( HINSTANCE hInstDLL )
254 {
255         (void)UnregisterClassA( IMM32_szIMEClass, hInstDLL );
256 }
257
258 /***********************************************************************
259  *              IMM32_CreateDefaultIMEWnd (internal)
260  */
261
262 HWND IMM32_CreateDefaultIMEWnd( void )
263 {
264         return CreateWindowExA( 0L,
265                                 IMM32_szIMEClass,
266                                 IMM32_szIMEWindowName,
267                                 WS_POPUP | WS_CLIPSIBLINGS | WS_OVERLAPPED,
268                                 0, 0, 0, 0,
269                                 (HWND)NULL,
270                                 (HMENU)NULL,
271                                 (HINSTANCE)GetModuleHandleA(NULL),
272                                 NULL );
273 }
274
275 static BOOL IMM32_IsUIMessage( UINT nMsg )
276 {
277         switch ( nMsg )
278         {
279         case WM_IME_STARTCOMPOSITION:
280         case WM_IME_ENDCOMPOSITION:
281         case WM_IME_COMPOSITION:
282         case WM_IME_SETCONTEXT:
283         case WM_IME_NOTIFY:
284         case WM_IME_COMPOSITIONFULL:
285         case WM_IME_SELECT:
286         case 0x287: /* What is this message? IMM32.DLL returns TRUE. */
287                 return TRUE;
288         }
289
290         return FALSE;
291 }
292
293
294 /***********************************************************************
295  *              ImmIsUIMessageA (IMM32.@)
296  */
297 BOOL WINAPI ImmIsUIMessageA(
298         HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
299 {
300         TRACE("(0x%08x, %d, %d, %ld)\n",
301               hwndIME, msg, wParam, lParam);
302
303         if ( !IMM32_IsUIMessage( msg ) )
304                 return FALSE;
305         if ( hwndIME == (HWND)NULL )
306                 return TRUE;
307
308         switch ( msg )
309         {
310         case WM_IME_STARTCOMPOSITION:
311         case WM_IME_ENDCOMPOSITION:
312         case WM_IME_COMPOSITION:
313         case WM_IME_SETCONTEXT:
314         case WM_IME_NOTIFY:
315         case WM_IME_COMPOSITIONFULL:
316         case WM_IME_SELECT:
317                 SendMessageA( hwndIME, msg, wParam, lParam );
318                 break;
319         case 0x287: /* What is this message? */
320                 FIXME("(0x%08x, %d, %d, %ld) - unknown message 0x287.\n",
321                       hwndIME, msg, wParam, lParam);
322                 SendMessageA( hwndIME, msg, wParam, lParam );
323                 break;
324         }
325
326         return TRUE;
327 }
328
329 /***********************************************************************
330  *              ImmIsUIMessageW (IMM32.@)
331  */
332 BOOL WINAPI ImmIsUIMessageW(
333         HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
334 {
335         TRACE("(0x%08x, %d, %d, %ld)\n",
336               hwndIME, msg, wParam, lParam);
337
338         if ( !IMM32_IsUIMessage( msg ) )
339                 return FALSE;
340         if ( hwndIME == (HWND)NULL )
341                 return TRUE;
342
343         switch ( msg )
344         {
345         case WM_IME_STARTCOMPOSITION:
346         case WM_IME_ENDCOMPOSITION:
347         case WM_IME_COMPOSITION:
348         case WM_IME_SETCONTEXT:
349         case WM_IME_NOTIFY:
350         case WM_IME_COMPOSITIONFULL:
351         case WM_IME_SELECT:
352                 SendMessageW( hwndIME, msg, wParam, lParam );
353                 break;
354         case 0x287: /* What is this message? */
355                 FIXME("(0x%08x, %d, %d, %ld) - unknown message 0x287.\n",
356                       hwndIME, msg, wParam, lParam);
357                 SendMessageW( hwndIME, msg, wParam, lParam );
358                 break;
359         }
360
361         return TRUE;
362 }