user32: Implement SPI_[SG]ETCARETWIDTH.
[wine] / dlls / user / misc.c
1 /*
2  * Misc USER functions
3  *
4  * Copyright 1995 Thomas Sandford
5  * Copyright 1997 Marcus Meissner
6  * Copyright 1998 Turchanov Sergey
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include <stdarg.h>
24
25 #include "windef.h"
26 #include "wine/windef16.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "winnls.h"
31 #include "winternl.h"
32
33 #include "wine/unicode.h"
34 #include "wine/debug.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(win);
37
38 /* USER signal proc flags and codes */
39 /* See UserSignalProc for comments */
40 #define USIG_FLAGS_WIN32          0x0001
41 #define USIG_FLAGS_GUI            0x0002
42 #define USIG_FLAGS_FEEDBACK       0x0004
43 #define USIG_FLAGS_FAULT          0x0008
44
45 #define USIG_DLL_UNLOAD_WIN16     0x0001
46 #define USIG_DLL_UNLOAD_WIN32     0x0002
47 #define USIG_FAULT_DIALOG_PUSH    0x0003
48 #define USIG_FAULT_DIALOG_POP     0x0004
49 #define USIG_DLL_UNLOAD_ORPHANS   0x0005
50 #define USIG_THREAD_INIT          0x0010
51 #define USIG_THREAD_EXIT          0x0020
52 #define USIG_PROCESS_CREATE       0x0100
53 #define USIG_PROCESS_INIT         0x0200
54 #define USIG_PROCESS_EXIT         0x0300
55 #define USIG_PROCESS_DESTROY      0x0400
56 #define USIG_PROCESS_RUNNING      0x0500
57 #define USIG_PROCESS_LOADED       0x0600
58
59 #define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
60
61 /***********************************************************************
62  *              SignalProc32 (USER.391)
63  *              UserSignalProc (USER32.@)
64  *
65  * The exact meaning of the USER signals is undocumented, but this
66  * should cover the basic idea:
67  *
68  * USIG_DLL_UNLOAD_WIN16
69  *     This is sent when a 16-bit module is unloaded.
70  *
71  * USIG_DLL_UNLOAD_WIN32
72  *     This is sent when a 32-bit module is unloaded.
73  *
74  * USIG_DLL_UNLOAD_ORPHANS
75  *     This is sent after the last Win3.1 module is unloaded,
76  *     to allow removal of orphaned menus.
77  *
78  * USIG_FAULT_DIALOG_PUSH
79  * USIG_FAULT_DIALOG_POP
80  *     These are called to allow USER to prepare for displaying a
81  *     fault dialog, even though the fault might have happened while
82  *     inside a USER critical section.
83  *
84  * USIG_THREAD_INIT
85  *     This is called from the context of a new thread, as soon as it
86  *     has started to run.
87  *
88  * USIG_THREAD_EXIT
89  *     This is called, still in its context, just before a thread is
90  *     about to terminate.
91  *
92  * USIG_PROCESS_CREATE
93  *     This is called, in the parent process context, after a new process
94  *     has been created.
95  *
96  * USIG_PROCESS_INIT
97  *     This is called in the new process context, just after the main thread
98  *     has started execution (after the main thread's USIG_THREAD_INIT has
99  *     been sent).
100  *
101  * USIG_PROCESS_LOADED
102  *     This is called after the executable file has been loaded into the
103  *     new process context.
104  *
105  * USIG_PROCESS_RUNNING
106  *     This is called immediately before the main entry point is called.
107  *
108  * USIG_PROCESS_EXIT
109  *     This is called in the context of a process that is about to
110  *     terminate (but before the last thread's USIG_THREAD_EXIT has
111  *     been sent).
112  *
113  * USIG_PROCESS_DESTROY
114  *     This is called after a process has terminated.
115  *
116  *
117  * The meaning of the dwFlags bits is as follows:
118  *
119  * USIG_FLAGS_WIN32
120  *     Current process is 32-bit.
121  *
122  * USIG_FLAGS_GUI
123  *     Current process is a (Win32) GUI process.
124  *
125  * USIG_FLAGS_FEEDBACK
126  *     Current process needs 'feedback' (determined from the STARTUPINFO
127  *     flags STARTF_FORCEONFEEDBACK / STARTF_FORCEOFFFEEDBACK).
128  *
129  * USIG_FLAGS_FAULT
130  *     The signal is being sent due to a fault.
131  */
132 WORD WINAPI UserSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
133                             DWORD dwFlags, HMODULE16 hModule )
134 {
135     FIXME("(%04x, %08lx, %04lx, %04x)\n",
136           uCode, dwThreadOrProcessID, dwFlags, hModule );
137     /* FIXME: Should chain to GdiSignalProc now. */
138     return 0;
139 }
140
141
142 /**********************************************************************
143  * SetLastErrorEx [USER32.@]
144  *
145  * Sets the last-error code.
146  *
147  * RETURNS
148  *    None.
149  */
150 void WINAPI SetLastErrorEx(
151     DWORD error, /* [in] Per-thread error code */
152     DWORD type)  /* [in] Error type */
153 {
154     TRACE("(0x%08lx, 0x%08lx)\n", error,type);
155     switch(type) {
156         case 0:
157             break;
158         case SLE_ERROR:
159         case SLE_MINORERROR:
160         case SLE_WARNING:
161             /* Fall through for now */
162         default:
163             FIXME("(error=%08lx, type=%08lx): Unhandled type\n", error,type);
164             break;
165     }
166     SetLastError( error );
167 }
168
169 /******************************************************************************
170  * GetAltTabInfoA [USER32.@]
171  */
172 BOOL WINAPI GetAltTabInfoA(HWND hwnd, int iItem, PALTTABINFO pati, LPSTR pszItemText, UINT cchItemText)
173 {
174     FIXME("(%p, 0x%08x, %p, %p, 0x%08x)\n", hwnd, iItem, pati, pszItemText, cchItemText);
175     return FALSE;
176 }
177
178 /******************************************************************************
179  * GetAltTabInfoW [USER32.@]
180  */
181 BOOL WINAPI GetAltTabInfoW(HWND hwnd, int iItem, PALTTABINFO pati, LPWSTR pszItemText, UINT cchItemText)
182 {
183     FIXME("(%p, 0x%08x, %p, %p, 0x%08x)\n", hwnd, iItem, pati, pszItemText, cchItemText);
184     return FALSE;
185 }
186
187 /******************************************************************************
188  * SetDebugErrorLevel [USER32.@]
189  * Sets the minimum error level for generating debugging events
190  *
191  * PARAMS
192  *    dwLevel [I] Debugging error level
193  *
194  * RETURNS
195  *    Nothing.
196  */
197 VOID WINAPI SetDebugErrorLevel( DWORD dwLevel )
198 {
199     FIXME("(%ld): stub\n", dwLevel);
200 }
201
202
203 /******************************************************************************
204  *                    GetProcessDefaultLayout [USER32.@]
205  *
206  * Gets the default layout for parentless windows.
207  * Right now, just returns 0 (left-to-right).
208  *
209  * RETURNS
210  *    Success: Nonzero
211  *    Failure: Zero
212  *
213  * BUGS
214  *    No RTL
215  */
216 BOOL WINAPI GetProcessDefaultLayout( DWORD *pdwDefaultLayout )
217 {
218     if ( !pdwDefaultLayout ) {
219         SetLastError( ERROR_INVALID_PARAMETER );
220         return FALSE;
221      }
222     FIXME( "( %p ): No BiDi\n", pdwDefaultLayout );
223     *pdwDefaultLayout = 0;
224     return TRUE;
225 }
226
227
228 /******************************************************************************
229  *                    SetProcessDefaultLayout [USER32.@]
230  *
231  * Sets the default layout for parentless windows.
232  * Right now, only accepts 0 (left-to-right).
233  *
234  * RETURNS
235  *    Success: Nonzero
236  *    Failure: Zero
237  *
238  * BUGS
239  *    No RTL
240  */
241 BOOL WINAPI SetProcessDefaultLayout( DWORD dwDefaultLayout )
242 {
243     if ( dwDefaultLayout == 0 )
244         return TRUE;
245     FIXME( "( %08lx ): No BiDi\n", dwDefaultLayout );
246     SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
247     return FALSE;
248 }
249
250
251 /***********************************************************************
252  *              SetWindowStationUser (USER32.@)
253  */
254 DWORD WINAPI SetWindowStationUser(DWORD x1,DWORD x2)
255 {
256     FIXME("(0x%08lx,0x%08lx),stub!\n",x1,x2);
257     return 1;
258 }
259
260 /***********************************************************************
261  *              RegisterLogonProcess (USER32.@)
262  */
263 DWORD WINAPI RegisterLogonProcess(HANDLE hprocess,BOOL x)
264 {
265     FIXME("(%p,%d),stub!\n",hprocess,x);
266     return 1;
267 }
268
269 /***********************************************************************
270  *              SetLogonNotifyWindow (USER32.@)
271  */
272 DWORD WINAPI SetLogonNotifyWindow(HWINSTA hwinsta,HWND hwnd)
273 {
274     FIXME("(%p,%p),stub!\n",hwinsta,hwnd);
275     return 1;
276 }
277
278 static const WCHAR primary_device_name[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0};
279 static const WCHAR primary_device_string[] = {'X','1','1',' ','W','i','n','d','o','w','i','n','g',' ',
280                                               'S','y','s','t','e','m',0};
281
282 /***********************************************************************
283  *              EnumDisplayDevicesA (USER32.@)
284  */
285 BOOL WINAPI EnumDisplayDevicesA( LPCSTR lpDevice, DWORD i, LPDISPLAY_DEVICEA lpDispDev,
286                                  DWORD dwFlags )
287 {
288     UNICODE_STRING deviceW;
289     DISPLAY_DEVICEW ddW;
290     BOOL ret;
291
292     if(lpDevice)
293         RtlCreateUnicodeStringFromAsciiz(&deviceW, lpDevice); 
294     else
295         deviceW.Buffer = NULL;
296
297     ddW.cb = sizeof(ddW);
298     ret = EnumDisplayDevicesW(deviceW.Buffer, i, &ddW, dwFlags);
299     RtlFreeUnicodeString(&deviceW);
300
301     if(!ret) return ret;
302
303     WideCharToMultiByte(CP_ACP, 0, ddW.DeviceName, -1, lpDispDev->DeviceName, sizeof(lpDispDev->DeviceName), NULL, NULL);
304     WideCharToMultiByte(CP_ACP, 0, ddW.DeviceString, -1, lpDispDev->DeviceString, sizeof(lpDispDev->DeviceString), NULL, NULL);
305     lpDispDev->StateFlags = ddW.StateFlags;
306
307     if(lpDispDev->cb >= offsetof(DISPLAY_DEVICEA, DeviceID) + sizeof(lpDispDev->DeviceID))
308         WideCharToMultiByte(CP_ACP, 0, ddW.DeviceID, -1, lpDispDev->DeviceID, sizeof(lpDispDev->DeviceID), NULL, NULL);
309     if(lpDispDev->cb >= offsetof(DISPLAY_DEVICEA, DeviceKey) + sizeof(lpDispDev->DeviceKey))
310         WideCharToMultiByte(CP_ACP, 0, ddW.DeviceKey, -1, lpDispDev->DeviceKey, sizeof(lpDispDev->DeviceKey), NULL, NULL);
311
312     return TRUE;
313 }
314
315 /***********************************************************************
316  *              EnumDisplayDevicesW (USER32.@)
317  */
318 BOOL WINAPI EnumDisplayDevicesW( LPCWSTR lpDevice, DWORD i, LPDISPLAY_DEVICEW lpDisplayDevice,
319                                  DWORD dwFlags )
320 {
321     FIXME("(%s,%ld,%p,0x%08lx), stub!\n",debugstr_w(lpDevice),i,lpDisplayDevice,dwFlags);
322
323     if (i)
324         return FALSE;
325
326     memcpy(lpDisplayDevice->DeviceName, primary_device_name, sizeof(primary_device_name));
327     memcpy(lpDisplayDevice->DeviceString, primary_device_string, sizeof(primary_device_string));
328   
329     lpDisplayDevice->StateFlags =
330         DISPLAY_DEVICE_ATTACHED_TO_DESKTOP |
331         DISPLAY_DEVICE_PRIMARY_DEVICE |
332         DISPLAY_DEVICE_VGA_COMPATIBLE;
333
334     if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(lpDisplayDevice->DeviceID))
335         lpDisplayDevice->DeviceID[0] = 0;
336     if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(lpDisplayDevice->DeviceKey))
337         lpDisplayDevice->DeviceKey[0] = 0;
338
339     return TRUE;
340 }
341
342 /***********************************************************************
343  *              MonitorFromPoint (USER32.@)
344  */
345 HMONITOR WINAPI MonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
346 {
347     if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
348         ((ptScreenCoords.x >= 0) &&
349         (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
350         (ptScreenCoords.y >= 0) &&
351         (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
352     {
353         return xPRIMARY_MONITOR;
354     }
355     return NULL;
356 }
357
358 /***********************************************************************
359  *              MonitorFromRect (USER32.@)
360  */
361 HMONITOR WINAPI MonitorFromRect(LPRECT lprcScreenCoords, DWORD dwFlags)
362 {
363     if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
364         ((lprcScreenCoords->right > 0) &&
365         (lprcScreenCoords->bottom > 0) &&
366         (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
367         (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
368     {
369         return xPRIMARY_MONITOR;
370     }
371     return NULL;
372 }
373
374 /***********************************************************************
375  *              MonitorFromWindow (USER32.@)
376  */
377 HMONITOR WINAPI MonitorFromWindow(HWND hWnd, DWORD dwFlags)
378 {
379     WINDOWPLACEMENT wp;
380
381     if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
382         return xPRIMARY_MONITOR;
383
384     if (IsIconic(hWnd) ?
385             GetWindowPlacement(hWnd, &wp) :
386             GetWindowRect(hWnd, &wp.rcNormalPosition)) {
387
388         return MonitorFromRect(&wp.rcNormalPosition, dwFlags);
389     }
390
391     return NULL;
392 }
393
394 /***********************************************************************
395  *              GetMonitorInfoA (USER32.@)
396  */
397 BOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
398 {
399     MONITORINFOEXW miW;
400     MONITORINFOEXA *miA = (MONITORINFOEXA*)lpMonitorInfo;
401     BOOL ret;
402
403     miW.cbSize = sizeof(miW);
404
405     ret = GetMonitorInfoW(hMonitor, (MONITORINFO*)&miW);
406     if(!ret) return ret;
407
408     miA->rcMonitor = miW.rcMonitor;
409     miA->rcWork = miW.rcWork;
410     miA->dwFlags = miW.dwFlags;
411     if(miA->cbSize >= offsetof(MONITORINFOEXA, szDevice) + sizeof(miA->szDevice))
412         WideCharToMultiByte(CP_ACP, 0, miW.szDevice, -1, miA->szDevice, sizeof(miA->szDevice), NULL, NULL);
413     return ret;
414 }
415
416 /***********************************************************************
417  *              GetMonitorInfoW (USER32.@)
418  */
419 BOOL WINAPI GetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
420 {
421     RECT rcWork;
422
423     if ((hMonitor == xPRIMARY_MONITOR) &&
424         lpMonitorInfo &&
425         (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
426         SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcWork, 0))
427     {
428         SetRect( &lpMonitorInfo->rcMonitor, 0, 0,
429                  GetSystemMetrics(SM_CXSCREEN),
430                  GetSystemMetrics(SM_CYSCREEN) );
431         lpMonitorInfo->rcWork = rcWork;
432         lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
433
434         if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXW))
435             strcpyW(((MONITORINFOEXW*)lpMonitorInfo)->szDevice, primary_device_name);
436
437         return TRUE;
438     }
439
440     return FALSE;
441 }
442
443 /***********************************************************************
444  *              EnumDisplayMonitors (USER32.@)
445  */
446 BOOL WINAPI EnumDisplayMonitors(
447         HDC             hdcOptionalForPainting,
448         LPRECT         lprcEnumMonitorsThatIntersect,
449         MONITORENUMPROC lpfnEnumProc,
450         LPARAM          dwData)
451 {
452     RECT rcLimit;
453     SetRect( &rcLimit, 0, 0, GetSystemMetrics(SM_CXSCREEN),
454              GetSystemMetrics(SM_CYSCREEN) );
455
456     if (!lpfnEnumProc)
457         return FALSE;
458
459     if (hdcOptionalForPainting)
460     {
461         RECT    rcClip;
462         POINT   ptOrg;
463
464         switch (GetClipBox(hdcOptionalForPainting, &rcClip))
465         {
466         default:
467             if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
468                 return FALSE;
469
470             OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
471             if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
472                 (!lprcEnumMonitorsThatIntersect ||
473                      IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
474
475                 break;
476             }
477             /* fall through */
478         case NULLREGION:
479              return TRUE;
480         case ERROR:
481              return FALSE;
482         }
483     } else {
484         if (    lprcEnumMonitorsThatIntersect &&
485                 !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
486
487             return TRUE;
488         }
489     }
490
491     return lpfnEnumProc(
492             xPRIMARY_MONITOR,
493             hdcOptionalForPainting,
494             &rcLimit,
495             dwData);
496 }
497
498 /***********************************************************************
499  *              RegisterSystemThread (USER32.@)
500  */
501 void WINAPI RegisterSystemThread(DWORD flags, DWORD reserved)
502 {
503     FIXME("(%08lx, %08lx)\n", flags, reserved);
504 }
505
506 /***********************************************************************
507  *           RegisterShellHookWindow                    [USER32.@]
508  */
509 BOOL WINAPI RegisterShellHookWindow ( HWND hWnd )
510 {
511     FIXME("(%p): stub\n", hWnd);
512     return 0;
513 }
514
515
516 /***********************************************************************
517  *           DeregisterShellHookWindow                  [USER32.@]
518  */
519 HRESULT WINAPI DeregisterShellHookWindow ( DWORD u )
520 {
521     FIXME("0x%08lx stub\n",u);
522     return 0;
523
524 }
525
526
527 /***********************************************************************
528  *           RegisterTasklist                           [USER32.@]
529  */
530 DWORD WINAPI RegisterTasklist (DWORD x)
531 {
532     FIXME("0x%08lx\n",x);
533     return TRUE;
534 }
535
536
537 /***********************************************************************
538  *              RegisterDeviceNotificationA (USER32.@)
539  *
540  * See RegisterDeviceNotificationW.
541  */
542 HDEVNOTIFY WINAPI RegisterDeviceNotificationA(HANDLE hnd, LPVOID notifyfilter, DWORD flags)
543 {
544     FIXME("(hwnd=%p, filter=%p,flags=0x%08lx), STUB!\n", hnd,notifyfilter,flags );
545     return 0;
546 }
547
548 /***********************************************************************
549  *              RegisterDeviceNotificationW (USER32.@)
550  *
551  * Registers a window with the system so that it will receive
552  * notifications about a device.
553  *
554  * PARAMS
555  *     hRecepient           [I] Window or service status handle that
556  *                              will receive notifications.
557  *     pNotificationFilter  [I] DEV_BROADCAST_HDR followed by some
558  *                              type-specific data.
559  *     dwFlags              [I] See notes
560  *
561  * RETURNS
562  *
563  * A handle to the device notification.
564  *
565  * NOTES
566  *
567  * The dwFlags parameter can be one of two values:
568  *| DEVICE_NOTIFY_WINDOW_HANDLE  - hRecepient is a window handle
569  *| DEVICE_NOTIFY_SERVICE_HANDLE - hRecepient is a service status handle
570  */
571 HDEVNOTIFY WINAPI RegisterDeviceNotificationW(HANDLE hRecepient, LPVOID pNotificationFilter, DWORD dwFlags)
572 {
573     FIXME("(hwnd=%p, filter=%p,flags=0x%08lx), STUB!\n", hRecepient,pNotificationFilter,dwFlags );
574     return 0;
575 }
576
577 /***********************************************************************
578  *              UnregisterDeviceNotification (USER32.@)
579  *
580  */
581 BOOL  WINAPI UnregisterDeviceNotification(HDEVNOTIFY hnd)
582 {
583     FIXME("(handle=%p), STUB!\n", hnd);
584     return TRUE;
585 }
586
587 /***********************************************************************
588  *           GetAppCompatFlags   (USER32.@)
589  */
590 DWORD WINAPI GetAppCompatFlags( HTASK hTask )
591 {
592     FIXME("stub\n");
593     return 0;
594 }
595
596
597 /***********************************************************************
598  *           AlignRects   (USER32.@)
599  */
600 BOOL WINAPI AlignRects(LPRECT rect, DWORD b, DWORD c, DWORD d)
601 {
602     FIXME("(%p, %ld, %ld, %ld): stub\n", rect, b, c, d);
603     if (rect)
604         FIXME("rect: [[%ld, %ld], [%ld, %ld]]\n", rect->left, rect->top, rect->right, rect->bottom);
605     /* Calls OffsetRect */
606     return FALSE;
607 }
608
609
610 /***********************************************************************
611  *              LoadLocalFonts (USER32.@)
612  */
613 VOID WINAPI LoadLocalFonts(VOID)
614 {
615     /* are loaded. */
616     return;
617 }
618
619
620 /***********************************************************************
621  *              USER_489 (USER.489)
622  */
623 LONG WINAPI stub_USER_489(void) { FIXME("stub\n"); return 0; }
624
625 /***********************************************************************
626  *              USER_490 (USER.490)
627  */
628 LONG WINAPI stub_USER_490(void) { FIXME("stub\n"); return 0; }
629
630 /***********************************************************************
631  *              USER_492 (USER.492)
632  */
633 LONG WINAPI stub_USER_492(void) { FIXME("stub\n"); return 0; }
634
635 /***********************************************************************
636  *              USER_496 (USER.496)
637  */
638 LONG WINAPI stub_USER_496(void) { FIXME("stub\n"); return 0; }
639
640 /***********************************************************************
641  *              User32InitializeImmEntryTable
642  */
643 BOOL WINAPI User32InitializeImmEntryTable(LPVOID ptr)
644 {
645   FIXME("(%p): stub\n", ptr);
646   return TRUE;
647 }
648
649 /**********************************************************************
650  * WINNLSGetIMEHotkey [USER32.@]
651  *
652  */
653 UINT WINAPI WINNLSGetIMEHotkey(HWND hUnknown1)
654 {
655     FIXME("hUnknown1 %p: stub!\n", hUnknown1);
656     return 0; /* unknown */
657 }
658
659 /**********************************************************************
660  * WINNLSEnableIME [USER32.@]
661  *
662  */
663 BOOL WINAPI WINNLSEnableIME(HWND hUnknown1, BOOL bUnknown2)
664 {
665     FIXME("hUnknown1 %p bUnknown2 %d: stub!\n", hUnknown1, bUnknown2);
666     return TRUE; /* success (?) */
667 }
668
669 /**********************************************************************
670  * WINNLSGetEnableStatus [USER32.@]
671  *
672  */
673 BOOL WINAPI WINNLSGetEnableStatus(HWND hUnknown1)
674 {
675     FIXME("hUnknown1 %p: stub!\n", hUnknown1);
676     return TRUE; /* success (?) */
677 }
678
679 /**********************************************************************
680  * SendIMEMessageExA [USER32.@]
681  *
682  */
683 LRESULT WINAPI SendIMEMessageExA(HWND p1, LPARAM p2)
684 {
685   FIXME("(%p,%lx): stub\n", p1, p2);
686   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
687   return 0;
688 }
689
690 /**********************************************************************
691  * SendIMEMessageExW [USER32.@]
692  *
693  */
694 LRESULT WINAPI SendIMEMessageExW(HWND p1, LPARAM p2)
695 {
696   FIXME("(%p,%lx): stub\n", p1, p2);
697   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
698   return 0;
699 }