Get rid of the WIN_SetRectangles export from user32.
[wine] / dlls / user / user16.c
1 /*
2  * Misc 16-bit USER functions
3  *
4  * Copyright 2002 Patrik Stridvall
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdarg.h>
22 #include <stdlib.h>
23 #include "wine/winuser16.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wownt32.h"
27 #include "user.h"
28 #include "win.h"
29 #include "winproc.h"
30 #include "cursoricon.h"
31
32 /* handle to handle 16 conversions */
33 #define HANDLE_16(h32)          (LOWORD(h32))
34
35 /* handle16 to handle conversions */
36 #define HANDLE_32(h16)          ((HANDLE)(ULONG_PTR)(h16))
37 #define HINSTANCE_32(h16)       ((HINSTANCE)(ULONG_PTR)(h16))
38
39 #define IS_MENU_STRING_ITEM(flags) \
40     (((flags) & (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR)) == MF_STRING)
41
42 WORD WINAPI DestroyIcon32(HGLOBAL16, UINT16);
43
44
45 struct gray_string_info
46 {
47     GRAYSTRINGPROC16 proc;
48     LPARAM           param;
49     char             str[1];
50 };
51
52 /* callback for 16-bit gray string proc with opaque pointer */
53 static BOOL CALLBACK gray_string_callback( HDC hdc, LPARAM param, INT len )
54 {
55     const struct gray_string_info *info = (struct gray_string_info *)param;
56     WORD args[4];
57     DWORD ret;
58
59     args[3] = HDC_16(hdc);
60     args[2] = HIWORD(info->param);
61     args[1] = LOWORD(info->param);
62     args[0] = len;
63     WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
64     return LOWORD(ret);
65 }
66
67 /* callback for 16-bit gray string proc with string pointer */
68 static BOOL CALLBACK gray_string_callback_ptr( HDC hdc, LPARAM param, INT len )
69 {
70     const struct gray_string_info *info;
71     char *str = (char *)param;
72
73     info = (struct gray_string_info *)(str - offsetof( struct gray_string_info, str ));
74     return gray_string_callback( hdc, (LPARAM)info, len );
75 }
76
77 struct draw_state_info
78 {
79     DRAWSTATEPROC16 proc;
80     LPARAM          param;
81 };
82
83 /* callback for 16-bit DrawState functions */
84 static BOOL CALLBACK draw_state_callback( HDC hdc, LPARAM lparam, WPARAM wparam, int cx, int cy )
85 {
86     const struct draw_state_info *info = (struct draw_state_info *)lparam;
87     WORD args[6];
88     DWORD ret;
89
90     args[5] = HDC_16(hdc);
91     args[4] = HIWORD(info->param);
92     args[3] = LOWORD(info->param);
93     args[2] = wparam;
94     args[1] = cx;
95     args[0] = cy;
96     WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
97     return LOWORD(ret);
98 }
99
100
101 /***********************************************************************
102  *              ClipCursor (USER.16)
103  */
104 BOOL16 WINAPI ClipCursor16( const RECT16 *rect )
105 {
106     RECT rect32;
107
108     if (!rect) return ClipCursor( NULL );
109     rect32.left   = rect->left;
110     rect32.top    = rect->top;
111     rect32.right  = rect->right;
112     rect32.bottom = rect->bottom;
113     return ClipCursor( &rect32 );
114 }
115
116
117 /***********************************************************************
118  *              SetCursor (USER.69)
119  */
120 HCURSOR16 WINAPI SetCursor16(HCURSOR16 hCursor)
121 {
122   return HCURSOR_16(SetCursor(HCURSOR_32(hCursor)));
123 }
124
125 /***********************************************************************
126  *              ShowCursor (USER.71)
127  */
128 INT16 WINAPI ShowCursor16(BOOL16 bShow)
129 {
130   return ShowCursor(bShow);
131 }
132
133
134 /***********************************************************************
135  *              FillRect (USER.81)
136  * NOTE
137  *   The Win16 variant doesn't support special color brushes like
138  *   the Win32 one, despite the fact that Win16, as well as Win32,
139  *   supports special background brushes for a window class.
140  */
141 INT16 WINAPI FillRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
142 {
143     HBRUSH prevBrush;
144
145     /* coordinates are logical so we cannot fast-check 'rect',
146      * it will be done later in the PatBlt().
147      */
148
149     if (!(prevBrush = SelectObject( HDC_32(hdc), HBRUSH_32(hbrush) ))) return 0;
150     PatBlt( HDC_32(hdc), rect->left, rect->top,
151               rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
152     SelectObject( HDC_32(hdc), prevBrush );
153     return 1;
154 }
155
156
157 /***********************************************************************
158  *              InvertRect (USER.82)
159  */
160 void WINAPI InvertRect16( HDC16 hdc, const RECT16 *rect )
161 {
162     PatBlt( HDC_32(hdc), rect->left, rect->top,
163               rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
164 }
165
166
167 /***********************************************************************
168  *              FrameRect (USER.83)
169  */
170 INT16 WINAPI FrameRect16( HDC16 hdc, const RECT16 *rect16, HBRUSH16 hbrush )
171 {
172     RECT rect;
173
174     rect.left   = rect16->left;
175     rect.top    = rect16->top;
176     rect.right  = rect16->right;
177     rect.bottom = rect16->bottom;
178     return FrameRect( HDC_32(hdc), &rect, HBRUSH_32(hbrush) );
179 }
180
181
182 /***********************************************************************
183  *              DrawIcon (USER.84)
184  */
185 BOOL16 WINAPI DrawIcon16(HDC16 hdc, INT16 x, INT16 y, HICON16 hIcon)
186 {
187   return DrawIcon(HDC_32(hdc), x, y, HICON_32(hIcon));
188 }
189
190
191 /***********************************************************************
192  *           DrawText    (USER.85)
193  */
194 INT16 WINAPI DrawText16( HDC16 hdc, LPCSTR str, INT16 count, LPRECT16 rect, UINT16 flags )
195 {
196     INT16 ret;
197
198     if (rect)
199     {
200         RECT rect32;
201
202         rect32.left   = rect->left;
203         rect32.top    = rect->top;
204         rect32.right  = rect->right;
205         rect32.bottom = rect->bottom;
206         ret = DrawTextA( HDC_32(hdc), str, count, &rect32, flags );
207         rect->left   = rect32.left;
208         rect->top    = rect32.top;
209         rect->right  = rect32.right;
210         rect->bottom = rect32.bottom;
211     }
212     else ret = DrawTextA( HDC_32(hdc), str, count, NULL, flags);
213     return ret;
214 }
215
216
217 /***********************************************************************
218  *              IconSize (USER.86)
219  *
220  * See "Undocumented Windows". Used by W2.0 paint.exe.
221  */
222 DWORD WINAPI IconSize16(void)
223 {
224   return MAKELONG(GetSystemMetrics(SM_CYICON), GetSystemMetrics(SM_CXICON));
225 }
226
227
228 /***********************************************************************
229  *              AdjustWindowRect (USER.102)
230  */
231 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
232 {
233     return AdjustWindowRectEx16( rect, style, menu, 0 );
234 }
235
236
237 /**********************************************************************
238  *         CreateMenu    (USER.151)
239  */
240 HMENU16 WINAPI CreateMenu16(void)
241 {
242     return HMENU_16( CreateMenu() );
243 }
244
245
246 /**********************************************************************
247  *         DestroyMenu    (USER.152)
248  */
249 BOOL16 WINAPI DestroyMenu16( HMENU16 hMenu )
250 {
251     return DestroyMenu( HMENU_32(hMenu) );
252 }
253
254
255 /*******************************************************************
256  *         ChangeMenu    (USER.153)
257  */
258 BOOL16 WINAPI ChangeMenu16( HMENU16 hMenu, UINT16 pos, SEGPTR data,
259                             UINT16 id, UINT16 flags )
260 {
261     if (flags & MF_APPEND) return AppendMenu16( hMenu, flags & ~MF_APPEND, id, data );
262
263     /* FIXME: Word passes the item id in 'pos' and 0 or 0xffff as id */
264     /* for MF_DELETE. We should check the parameters for all others */
265     /* MF_* actions also (anybody got a doc on ChangeMenu?). */
266
267     if (flags & MF_DELETE) return DeleteMenu16(hMenu, pos, flags & ~MF_DELETE);
268     if (flags & MF_CHANGE) return ModifyMenu16(hMenu, pos, flags & ~MF_CHANGE, id, data );
269     if (flags & MF_REMOVE) return RemoveMenu16(hMenu, flags & MF_BYPOSITION ? pos : id,
270                                                flags & ~MF_REMOVE );
271     /* Default: MF_INSERT */
272     return InsertMenu16( hMenu, pos, flags, id, data );
273 }
274
275
276 /*******************************************************************
277  *         CheckMenuItem    (USER.154)
278  */
279 BOOL16 WINAPI CheckMenuItem16( HMENU16 hMenu, UINT16 id, UINT16 flags )
280 {
281     return CheckMenuItem( HMENU_32(hMenu), id, flags );
282 }
283
284
285 /**********************************************************************
286  *         EnableMenuItem    (USER.155)
287  */
288 UINT16 WINAPI EnableMenuItem16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
289 {
290     return EnableMenuItem( HMENU_32(hMenu), wItemID, wFlags );
291 }
292
293
294 /**********************************************************************
295  *         GetSubMenu    (USER.159)
296  */
297 HMENU16 WINAPI GetSubMenu16( HMENU16 hMenu, INT16 nPos )
298 {
299     return HMENU_16( GetSubMenu( HMENU_32(hMenu), nPos ) );
300 }
301
302
303 /*******************************************************************
304  *         GetMenuString    (USER.161)
305  */
306 INT16 WINAPI GetMenuString16( HMENU16 hMenu, UINT16 wItemID,
307                               LPSTR str, INT16 nMaxSiz, UINT16 wFlags )
308 {
309     return GetMenuStringA( HMENU_32(hMenu), wItemID, str, nMaxSiz, wFlags );
310 }
311
312
313 /**********************************************************************
314  *              WinHelp (USER.171)
315  */
316 BOOL16 WINAPI WinHelp16( HWND16 hWnd, LPCSTR lpHelpFile, UINT16 wCommand,
317                          DWORD dwData )
318 {
319     BOOL ret;
320     DWORD mutex_count;
321
322     /* We might call WinExec() */
323     ReleaseThunkLock(&mutex_count);
324
325     ret = WinHelpA(WIN_Handle32(hWnd), lpHelpFile, wCommand, (DWORD)MapSL(dwData));
326
327     RestoreThunkLock(mutex_count);
328     return ret;
329 }
330
331
332 /***********************************************************************
333  *              LoadCursor (USER.173)
334  */
335 HCURSOR16 WINAPI LoadCursor16(HINSTANCE16 hInstance, LPCSTR name)
336 {
337   return HCURSOR_16(LoadCursorA(HINSTANCE_32(hInstance), name));
338 }
339
340
341 /***********************************************************************
342  *              LoadIcon (USER.174)
343  */
344 HICON16 WINAPI LoadIcon16(HINSTANCE16 hInstance, LPCSTR name)
345 {
346   return HICON_16(LoadIconA(HINSTANCE_32(hInstance), name));
347 }
348
349 /**********************************************************************
350  *              LoadBitmap (USER.175)
351  */
352 HBITMAP16 WINAPI LoadBitmap16(HINSTANCE16 hInstance, LPCSTR name)
353 {
354   return HBITMAP_16(LoadBitmapA(HINSTANCE_32(hInstance), name));
355 }
356
357
358 /***********************************************************************
359  *           GrayString   (USER.185)
360  */
361 BOOL16 WINAPI GrayString16( HDC16 hdc, HBRUSH16 hbr, GRAYSTRINGPROC16 gsprc,
362                             LPARAM lParam, INT16 cch, INT16 x, INT16 y,
363                             INT16 cx, INT16 cy )
364 {
365     BOOL ret;
366
367     if (!gsprc) return GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), NULL,
368                                     (LPARAM)MapSL(lParam), cch, x, y, cx, cy );
369
370     if (cch == -1 || (cch && cx && cy))
371     {
372         /* lParam can be treated as an opaque pointer */
373         struct gray_string_info info;
374
375         info.proc  = gsprc;
376         info.param = lParam;
377         ret = GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), gray_string_callback,
378                            (LPARAM)&info, cch, x, y, cx, cy );
379     }
380     else  /* here we need some string conversions */
381     {
382         char *str16 = MapSL(lParam);
383         struct gray_string_info *info;
384
385         if (!cch) cch = strlen(str16);
386         if (!(info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info) + cch ))) return FALSE;
387         info->proc  = gsprc;
388         info->param = lParam;
389         memcpy( info->str, str16, cch );
390         ret = GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), gray_string_callback_ptr,
391                            (LPARAM)info->str, cch, x, y, cx, cy );
392         HeapFree( GetProcessHeap(), 0, info );
393     }
394     return ret;
395 }
396
397
398 /***********************************************************************
399  *           TabbedTextOut    (USER.196)
400  */
401 LONG WINAPI TabbedTextOut16( HDC16 hdc, INT16 x, INT16 y, LPCSTR lpstr,
402                              INT16 count, INT16 nb_tabs, const INT16 *tabs16, INT16 tab_org )
403 {
404     LONG ret;
405     INT i, *tabs = HeapAlloc( GetProcessHeap(), 0, nb_tabs * sizeof(tabs) );
406     if (!tabs) return 0;
407     for (i = 0; i < nb_tabs; i++) tabs[i] = tabs16[i];
408     ret = TabbedTextOutA( HDC_32(hdc), x, y, lpstr, count, nb_tabs, tabs, tab_org );
409     HeapFree( GetProcessHeap(), 0, tabs );
410     return ret;
411 }
412
413
414 /***********************************************************************
415  *           GetTabbedTextExtent    (USER.197)
416  */
417 DWORD WINAPI GetTabbedTextExtent16( HDC16 hdc, LPCSTR lpstr, INT16 count,
418                                     INT16 nb_tabs, const INT16 *tabs16 )
419 {
420     LONG ret;
421     INT i, *tabs = HeapAlloc( GetProcessHeap(), 0, nb_tabs * sizeof(tabs) );
422     if (!tabs) return 0;
423     for (i = 0; i < nb_tabs; i++) tabs[i] = tabs16[i];
424     ret = GetTabbedTextExtentA( HDC_32(hdc), lpstr, count, nb_tabs, tabs );
425     HeapFree( GetProcessHeap(), 0, tabs );
426     return ret;
427 }
428
429
430 /*************************************************************************
431  *              ScrollDC (USER.221)
432  */
433 BOOL16 WINAPI ScrollDC16( HDC16 hdc, INT16 dx, INT16 dy, const RECT16 *rect,
434                           const RECT16 *cliprc, HRGN16 hrgnUpdate,
435                           LPRECT16 rcUpdate )
436 {
437     RECT rect32, clipRect32, rcUpdate32;
438     BOOL16 ret;
439
440     if (rect)
441     {
442         rect32.left   = rect->left;
443         rect32.top    = rect->top;
444         rect32.right  = rect->right;
445         rect32.bottom = rect->bottom;
446     }
447     if (cliprc)
448     {
449         clipRect32.left   = cliprc->left;
450         clipRect32.top    = cliprc->top;
451         clipRect32.right  = cliprc->right;
452         clipRect32.bottom = cliprc->bottom;
453     }
454     ret = ScrollDC( HDC_32(hdc), dx, dy, rect ? &rect32 : NULL,
455                     cliprc ? &clipRect32 : NULL, HRGN_32(hrgnUpdate),
456                     &rcUpdate32 );
457     if (rcUpdate)
458     {
459         rcUpdate->left   = rcUpdate32.left;
460         rcUpdate->top    = rcUpdate32.top;
461         rcUpdate->right  = rcUpdate32.right;
462         rcUpdate->bottom = rcUpdate32.bottom;
463     }
464     return ret;
465 }
466
467 /***********************************************************************
468  *              GetCursor (USER.247)
469  */
470 HCURSOR16 WINAPI GetCursor16(void)
471 {
472   return HCURSOR_16(GetCursor());
473 }
474
475
476 /**********************************************************************
477  *         GetMenuState    (USER.250)
478  */
479 UINT16 WINAPI GetMenuState16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
480 {
481     return GetMenuState( HMENU_32(hMenu), wItemID, wFlags );
482 }
483
484
485 /**********************************************************************
486  *         GetMenuItemCount    (USER.263)
487  */
488 INT16 WINAPI GetMenuItemCount16( HMENU16 hMenu )
489 {
490     return GetMenuItemCount( HMENU_32(hMenu) );
491 }
492
493
494 /**********************************************************************
495  *         GetMenuItemID    (USER.264)
496  */
497 UINT16 WINAPI GetMenuItemID16( HMENU16 hMenu, INT16 nPos )
498 {
499     return GetMenuItemID( HMENU_32(hMenu), nPos );
500 }
501
502
503 /***********************************************************************
504  *              GlobalAddAtom (USER.268)
505  */
506 ATOM WINAPI GlobalAddAtom16(LPCSTR lpString)
507 {
508   return GlobalAddAtomA(lpString);
509 }
510
511 /***********************************************************************
512  *              GlobalDeleteAtom (USER.269)
513  */
514 ATOM WINAPI GlobalDeleteAtom16(ATOM nAtom)
515 {
516   return GlobalDeleteAtom(nAtom);
517 }
518
519 /***********************************************************************
520  *              GlobalFindAtom (USER.270)
521  */
522 ATOM WINAPI GlobalFindAtom16(LPCSTR lpString)
523 {
524   return GlobalFindAtomA(lpString);
525 }
526
527 /***********************************************************************
528  *              GlobalGetAtomName (USER.271)
529  */
530 UINT16 WINAPI GlobalGetAtomName16(ATOM nAtom, LPSTR lpBuffer, INT16 nSize)
531 {
532   return GlobalGetAtomNameA(nAtom, lpBuffer, nSize);
533 }
534
535
536 /***********************************************************************
537  *              GetSysColorBrush (USER.281)
538  */
539 HBRUSH16 WINAPI GetSysColorBrush16( INT16 index )
540 {
541     return HBRUSH_16( GetSysColorBrush(index) );
542 }
543
544
545 /***********************************************************************
546  *              SelectPalette (USER.282)
547  */
548 HPALETTE16 WINAPI SelectPalette16( HDC16 hdc, HPALETTE16 hpal, BOOL16 bForceBackground )
549 {
550     return HPALETTE_16( SelectPalette( HDC_32(hdc), HPALETTE_32(hpal), bForceBackground ));
551 }
552
553 /***********************************************************************
554  *              RealizePalette (USER.283)
555  */
556 UINT16 WINAPI RealizePalette16( HDC16 hdc )
557 {
558     return UserRealizePalette( HDC_32(hdc) );
559 }
560
561
562 /***********************************************************************
563  *              GetClipCursor (USER.309)
564  */
565 void WINAPI GetClipCursor16( RECT16 *rect )
566 {
567     if (rect)
568     {
569         RECT rect32;
570         GetClipCursor( &rect32 );
571         rect->left   = rect32.left;
572         rect->top    = rect32.top;
573         rect->right  = rect32.right;
574         rect->bottom = rect32.bottom;
575     }
576 }
577
578
579 /***********************************************************************
580  *              SignalProc (USER.314)
581  */
582 void WINAPI SignalProc16( HANDLE16 hModule, UINT16 code,
583                           UINT16 uExitFn, HINSTANCE16 hInstance, HQUEUE16 hQueue )
584 {
585     if (code == USIG16_DLL_UNLOAD)
586     {
587         /* HOOK_FreeModuleHooks( hModule ); */
588         CLASS_FreeModuleClasses( hModule );
589         CURSORICON_FreeModuleIcons( hModule );
590     }
591 }
592
593
594 /**********************************************************************
595  *              IsMenu    (USER.358)
596  */
597 BOOL16 WINAPI IsMenu16( HMENU16 hmenu )
598 {
599     return IsMenu( HMENU_32(hmenu) );
600 }
601
602
603 /**********************************************************************
604  *         SetMenuContextHelpId    (USER.384)
605  */
606 BOOL16 WINAPI SetMenuContextHelpId16( HMENU16 hMenu, DWORD dwContextHelpID)
607 {
608     return SetMenuContextHelpId( HMENU_32(hMenu), dwContextHelpID );
609 }
610
611
612 /**********************************************************************
613  *         GetMenuContextHelpId    (USER.385)
614  */
615 DWORD WINAPI GetMenuContextHelpId16( HMENU16 hMenu )
616 {
617     return GetMenuContextHelpId( HMENU_32(hMenu) );
618 }
619
620
621 /***********************************************************************
622  *              LoadImage (USER.389)
623  *
624  */
625 HANDLE16 WINAPI LoadImage16(HINSTANCE16 hinst, LPCSTR name, UINT16 type,
626                             INT16 desiredx, INT16 desiredy, UINT16 loadflags)
627 {
628   return HANDLE_16(LoadImageA(HINSTANCE_32(hinst), name, type, desiredx,
629                               desiredy, loadflags));
630 }
631
632 /******************************************************************************
633  *              CopyImage (USER.390) Creates new image and copies attributes to it
634  *
635  */
636 HICON16 WINAPI CopyImage16(HANDLE16 hnd, UINT16 type, INT16 desiredx,
637                            INT16 desiredy, UINT16 flags)
638 {
639   return HICON_16(CopyImage(HANDLE_32(hnd), (UINT)type, (INT)desiredx,
640                             (INT)desiredy, (UINT)flags));
641 }
642
643 /**********************************************************************
644  *              DrawIconEx (USER.394)
645  */
646 BOOL16 WINAPI DrawIconEx16(HDC16 hdc, INT16 xLeft, INT16 yTop, HICON16 hIcon,
647                            INT16 cxWidth, INT16 cyWidth, UINT16 istep,
648                            HBRUSH16 hbr, UINT16 flags)
649 {
650   return DrawIconEx(HDC_32(hdc), xLeft, yTop, HICON_32(hIcon), cxWidth, cyWidth,
651                     istep, HBRUSH_32(hbr), flags);
652 }
653
654 /**********************************************************************
655  *              GetIconInfo (USER.395)
656  */
657 BOOL16 WINAPI GetIconInfo16(HICON16 hIcon, LPICONINFO16 iconinfo)
658 {
659   ICONINFO ii32;
660   BOOL16 ret = GetIconInfo(HICON_32(hIcon), &ii32);
661
662   iconinfo->fIcon = ii32.fIcon;
663   iconinfo->xHotspot = ii32.xHotspot;
664   iconinfo->yHotspot = ii32.yHotspot;
665   iconinfo->hbmMask  = HBITMAP_16(ii32.hbmMask);
666   iconinfo->hbmColor = HBITMAP_16(ii32.hbmColor);
667   return ret;
668 }
669
670 /***********************************************************************
671  *              CreateCursor (USER.406)
672  */
673 HCURSOR16 WINAPI CreateCursor16(HINSTANCE16 hInstance,
674                                 INT16 xHotSpot, INT16 yHotSpot,
675                                 INT16 nWidth, INT16 nHeight,
676                                 LPCVOID lpANDbits, LPCVOID lpXORbits)
677 {
678   CURSORICONINFO info;
679
680   info.ptHotSpot.x = xHotSpot;
681   info.ptHotSpot.y = yHotSpot;
682   info.nWidth = nWidth;
683   info.nHeight = nHeight;
684   info.nWidthBytes = 0;
685   info.bPlanes = 1;
686   info.bBitsPerPixel = 1;
687
688   return CreateCursorIconIndirect16(hInstance, &info, lpANDbits, lpXORbits);
689 }
690
691
692 /*******************************************************************
693  *         InsertMenu    (USER.410)
694  */
695 BOOL16 WINAPI InsertMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
696                             UINT16 id, SEGPTR data )
697 {
698     UINT pos32 = (UINT)pos;
699     if ((pos == (UINT16)-1) && (flags & MF_BYPOSITION)) pos32 = (UINT)-1;
700     if (IS_MENU_STRING_ITEM(flags) && data)
701         return InsertMenuA( HMENU_32(hMenu), pos32, flags, id, MapSL(data) );
702     return InsertMenuA( HMENU_32(hMenu), pos32, flags, id, (LPSTR)data );
703 }
704
705
706 /*******************************************************************
707  *         AppendMenu    (USER.411)
708  */
709 BOOL16 WINAPI AppendMenu16(HMENU16 hMenu, UINT16 flags, UINT16 id, SEGPTR data)
710 {
711     return InsertMenu16( hMenu, -1, flags | MF_BYPOSITION, id, data );
712 }
713
714
715 /**********************************************************************
716  *         RemoveMenu   (USER.412)
717  */
718 BOOL16 WINAPI RemoveMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
719 {
720     return RemoveMenu( HMENU_32(hMenu), nPos, wFlags );
721 }
722
723
724 /**********************************************************************
725  *         DeleteMenu    (USER.413)
726  */
727 BOOL16 WINAPI DeleteMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
728 {
729     return DeleteMenu( HMENU_32(hMenu), nPos, wFlags );
730 }
731
732
733 /*******************************************************************
734  *         ModifyMenu    (USER.414)
735  */
736 BOOL16 WINAPI ModifyMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
737                             UINT16 id, SEGPTR data )
738 {
739     if (IS_MENU_STRING_ITEM(flags))
740         return ModifyMenuA( HMENU_32(hMenu), pos, flags, id, MapSL(data) );
741     return ModifyMenuA( HMENU_32(hMenu), pos, flags, id, (LPSTR)data );
742 }
743
744
745 /**********************************************************************
746  *         CreatePopupMenu    (USER.415)
747  */
748 HMENU16 WINAPI CreatePopupMenu16(void)
749 {
750     return HMENU_16( CreatePopupMenu() );
751 }
752
753
754 /**********************************************************************
755  *         SetMenuItemBitmaps    (USER.418)
756  */
757 BOOL16 WINAPI SetMenuItemBitmaps16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags,
758                                     HBITMAP16 hNewUnCheck, HBITMAP16 hNewCheck)
759 {
760     return SetMenuItemBitmaps( HMENU_32(hMenu), nPos, wFlags,
761                                HBITMAP_32(hNewUnCheck), HBITMAP_32(hNewCheck) );
762 }
763
764
765 /*******************************************************************
766  *              InsertMenuItem   (USER.441)
767  *
768  * FIXME: untested
769  */
770 BOOL16 WINAPI InsertMenuItem16( HMENU16 hmenu, UINT16 pos, BOOL16 byposition,
771                                 const MENUITEMINFO16 *mii )
772 {
773     MENUITEMINFOA miia;
774
775     miia.cbSize        = sizeof(miia);
776     miia.fMask         = mii->fMask;
777     miia.dwTypeData    = (LPSTR)mii->dwTypeData;
778     miia.fType         = mii->fType;
779     miia.fState        = mii->fState;
780     miia.wID           = mii->wID;
781     miia.hSubMenu      = HMENU_32(mii->hSubMenu);
782     miia.hbmpChecked   = HBITMAP_32(mii->hbmpChecked);
783     miia.hbmpUnchecked = HBITMAP_32(mii->hbmpUnchecked);
784     miia.dwItemData    = mii->dwItemData;
785     miia.cch           = mii->cch;
786     if (IS_MENU_STRING_ITEM(miia.fType))
787         miia.dwTypeData = MapSL(mii->dwTypeData);
788     return InsertMenuItemA( HMENU_32(hmenu), pos, byposition, &miia );
789 }
790
791
792 /**********************************************************************
793  *           DrawState    (USER.449)
794  */
795 BOOL16 WINAPI DrawState16( HDC16 hdc, HBRUSH16 hbr, DRAWSTATEPROC16 func, LPARAM ldata,
796                            WPARAM16 wdata, INT16 x, INT16 y, INT16 cx, INT16 cy, UINT16 flags )
797 {
798     struct draw_state_info info;
799     UINT opcode = flags & 0xf;
800
801     if (opcode == DST_TEXT || opcode == DST_PREFIXTEXT)
802     {
803         /* make sure DrawStateA doesn't try to use ldata as a pointer */
804         if (!wdata) wdata = strlen( MapSL(ldata) );
805         if (!cx || !cy)
806         {
807             SIZE s;
808             if (!GetTextExtentPoint32A( HDC_32(hdc), MapSL(ldata), wdata, &s )) return FALSE;
809             if (!cx) cx = s.cx;
810             if (!cy) cy = s.cy;
811         }
812     }
813     info.proc  = func;
814     info.param = ldata;
815     return DrawStateA( HDC_32(hdc), HBRUSH_32(hbr), draw_state_callback,
816                        (LPARAM)&info, wdata, x, y, cx, cy, flags );
817 }
818
819
820 /**********************************************************************
821  *              CreateIconFromResourceEx (USER.450)
822  *
823  * FIXME: not sure about exact parameter types
824  */
825 HICON16 WINAPI CreateIconFromResourceEx16(LPBYTE bits, UINT16 cbSize,
826                                           BOOL16 bIcon, DWORD dwVersion,
827                                           INT16 width, INT16 height,
828                                           UINT16 cFlag)
829 {
830   return HICON_16(CreateIconFromResourceEx(bits, cbSize, bIcon, dwVersion,
831                                            width, height, cFlag));
832 }
833
834
835 /***********************************************************************
836  *              AdjustWindowRectEx (USER.454)
837  */
838 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style, BOOL16 menu, DWORD exStyle )
839 {
840     RECT rect32;
841     BOOL ret;
842
843     rect32.left   = rect->left;
844     rect32.top    = rect->top;
845     rect32.right  = rect->right;
846     rect32.bottom = rect->bottom;
847     ret = AdjustWindowRectEx( &rect32, style, menu, exStyle );
848     rect->left   = rect32.left;
849     rect->top    = rect32.top;
850     rect->right  = rect32.right;
851     rect->bottom = rect32.bottom;
852     return ret;
853 }
854
855
856 /***********************************************************************
857  *              DestroyIcon (USER.457)
858  */
859 BOOL16 WINAPI DestroyIcon16(HICON16 hIcon)
860 {
861   return DestroyIcon32(hIcon, 0);
862 }
863
864 /***********************************************************************
865  *              DestroyCursor (USER.458)
866  */
867 BOOL16 WINAPI DestroyCursor16(HCURSOR16 hCursor)
868 {
869   return DestroyIcon32(hCursor, 0);
870 }
871
872 /*******************************************************************
873  *                      DRAG_QueryUpdate16
874  *
875  * Recursively find a child that contains spDragInfo->pt point
876  * and send WM_QUERYDROPOBJECT. Helper for DragObject16.
877  */
878 static BOOL DRAG_QueryUpdate16( HWND hQueryWnd, SEGPTR spDragInfo )
879 {
880     BOOL bResult = 0;
881     WPARAM wParam;
882     POINT pt, old_pt;
883     LPDRAGINFO16 ptrDragInfo = MapSL(spDragInfo);
884     RECT tempRect;
885     HWND child;
886
887     if (!IsWindowEnabled(hQueryWnd)) return FALSE;
888
889     old_pt.x = ptrDragInfo->pt.x;
890     old_pt.y = ptrDragInfo->pt.y;
891     pt = old_pt;
892     ScreenToClient( hQueryWnd, &pt );
893     child = ChildWindowFromPointEx( hQueryWnd, pt, CWP_SKIPINVISIBLE );
894     if (!child) return FALSE;
895
896     if (child != hQueryWnd)
897     {
898         wParam = 0;
899         if (DRAG_QueryUpdate16( child, spDragInfo )) return TRUE;
900     }
901     else
902     {
903         GetClientRect( hQueryWnd, &tempRect );
904         wParam = !PtInRect( &tempRect, pt );
905     }
906
907     ptrDragInfo->pt.x = pt.x;
908     ptrDragInfo->pt.y = pt.y;
909     ptrDragInfo->hScope = HWND_16(hQueryWnd);
910
911     bResult = SendMessage16( HWND_16(hQueryWnd), WM_QUERYDROPOBJECT, wParam, spDragInfo );
912
913     if (!bResult)
914     {
915         ptrDragInfo->pt.x = old_pt.x;
916         ptrDragInfo->pt.y = old_pt.y;
917     }
918     return bResult;
919 }
920
921
922 /******************************************************************************
923  *              DragObject (USER.464)
924  */
925 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
926                            HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
927 {
928     MSG msg;
929     LPDRAGINFO16 lpDragInfo;
930     SEGPTR      spDragInfo;
931     HCURSOR     hOldCursor=0, hBummer=0;
932     HGLOBAL16   hDragInfo  = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO16));
933     HCURSOR     hCurrentCursor = 0;
934     HWND16      hCurrentWnd = 0;
935
936     lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo);
937     spDragInfo = K32WOWGlobalLock16(hDragInfo);
938
939     if( !lpDragInfo || !spDragInfo ) return 0L;
940
941     if (!(hBummer = LoadCursorA(0, MAKEINTRESOURCEA(OCR_NO))))
942     {
943         GlobalFree16(hDragInfo);
944         return 0L;
945     }
946
947     if(hCursor) hOldCursor = SetCursor(HCURSOR_32(hCursor));
948
949     lpDragInfo->hWnd   = hWnd;
950     lpDragInfo->hScope = 0;
951     lpDragInfo->wFlags = wObj;
952     lpDragInfo->hList  = szList; /* near pointer! */
953     lpDragInfo->hOfStruct = hOfStruct;
954     lpDragInfo->l = 0L;
955
956     SetCapture( HWND_32(hWnd) );
957     ShowCursor( TRUE );
958
959     do
960     {
961         GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST );
962
963        *(lpDragInfo+1) = *lpDragInfo;
964
965         lpDragInfo->pt.x = msg.pt.x;
966         lpDragInfo->pt.y = msg.pt.y;
967
968         /* update DRAGINFO struct */
969         if( DRAG_QueryUpdate16(WIN_Handle32(hwndScope), spDragInfo) > 0 )
970             hCurrentCursor = HCURSOR_32(hCursor);
971         else
972         {
973             hCurrentCursor = hBummer;
974             lpDragInfo->hScope = 0;
975         }
976         if( hCurrentCursor )
977             SetCursor(hCurrentCursor);
978
979         /* send WM_DRAGLOOP */
980         SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
981                                           (LPARAM) spDragInfo );
982         /* send WM_DRAGSELECT or WM_DRAGMOVE */
983         if( hCurrentWnd != lpDragInfo->hScope )
984         {
985             if( hCurrentWnd )
986                 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
987                        (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO16),
988                                         HIWORD(spDragInfo)) );
989             hCurrentWnd = lpDragInfo->hScope;
990             if( hCurrentWnd )
991                 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
992         }
993         else
994             if( hCurrentWnd )
995                 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
996
997     } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
998
999     ReleaseCapture();
1000     ShowCursor( FALSE );
1001
1002     if( hCursor ) SetCursor(hOldCursor);
1003
1004     if( hCurrentCursor != hBummer )
1005         msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
1006                                    (WPARAM16)hWnd, (LPARAM)spDragInfo );
1007     else
1008         msg.lParam = 0;
1009     GlobalFree16(hDragInfo);
1010
1011     return (DWORD)(msg.lParam);
1012 }
1013
1014
1015 /***********************************************************************
1016  *              DrawFocusRect (USER.466)
1017  */
1018 void WINAPI DrawFocusRect16( HDC16 hdc, const RECT16* rc )
1019 {
1020     RECT rect32;
1021
1022     rect32.left   = rc->left;
1023     rect32.top    = rc->top;
1024     rect32.right  = rc->right;
1025     rect32.bottom = rc->bottom;
1026     DrawFocusRect( HDC_32(hdc), &rect32 );
1027 }
1028
1029
1030 /**********************************************************************
1031  *          DrawFrameControl  (USER.656)
1032  */
1033 BOOL16 WINAPI DrawFrameControl16( HDC16 hdc, LPRECT16 rc, UINT16 uType, UINT16 uState )
1034 {
1035     RECT rect32;
1036     BOOL ret;
1037
1038     rect32.left   = rc->left;
1039     rect32.top    = rc->top;
1040     rect32.right  = rc->right;
1041     rect32.bottom = rc->bottom;
1042     ret = DrawFrameControl( HDC_32(hdc), &rect32, uType, uState );
1043     rc->left   = rect32.left;
1044     rc->top    = rect32.top;
1045     rc->right  = rect32.right;
1046     rc->bottom = rect32.bottom;
1047     return ret;
1048 }
1049
1050 /**********************************************************************
1051  *          DrawEdge   (USER.659)
1052  */
1053 BOOL16 WINAPI DrawEdge16( HDC16 hdc, LPRECT16 rc, UINT16 edge, UINT16 flags )
1054 {
1055     RECT rect32;
1056     BOOL ret;
1057
1058     rect32.left   = rc->left;
1059     rect32.top    = rc->top;
1060     rect32.right  = rc->right;
1061     rect32.bottom = rc->bottom;
1062     ret = DrawEdge( HDC_32(hdc), &rect32, edge, flags );
1063     rc->left   = rect32.left;
1064     rc->top    = rect32.top;
1065     rc->right  = rect32.right;
1066     rc->bottom = rect32.bottom;
1067     return ret;
1068 }
1069
1070 /**********************************************************************
1071  *              CheckMenuRadioItem (USER.666)
1072  */
1073 BOOL16 WINAPI CheckMenuRadioItem16(HMENU16 hMenu, UINT16 first, UINT16 last,
1074                                    UINT16 check, BOOL16 bypos)
1075 {
1076      return CheckMenuRadioItem( HMENU_32(hMenu), first, last, check, bypos );
1077 }