gdi32: Pre-allocate the points array in CreatePolyPolygonRgn.
[wine.git] / dlls / user.exe16 / user.c
blob27b92793836ae24732a3e619639be3ce6fb1dc21
1 /*
2 * Misc 16-bit USER functions
4 * Copyright 1993, 1996 Alexandre Julliard
5 * Copyright 2002 Patrik Stridvall
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
27 #define OEMRESOURCE
29 #include "wine/winuser16.h"
30 #include "windef.h"
31 #include "winbase.h"
32 #include "wownt32.h"
33 #include "user_private.h"
34 #include "wine/list.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(user);
39 /* handle to handle 16 conversions */
40 #define HANDLE_16(h32) (LOWORD(h32))
41 #define HGDIOBJ_16(h32) (LOWORD(h32))
43 /* handle16 to handle conversions */
44 #define HANDLE_32(h16) ((HANDLE)(ULONG_PTR)(h16))
45 #define HGDIOBJ_32(h16) ((HGDIOBJ)(ULONG_PTR)(h16))
47 #define IS_MENU_STRING_ITEM(flags) \
48 (((flags) & (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR)) == MF_STRING)
50 /* UserSeeUserDo parameters */
51 #define USUD_LOCALALLOC 0x0001
52 #define USUD_LOCALFREE 0x0002
53 #define USUD_LOCALCOMPACT 0x0003
54 #define USUD_LOCALHEAP 0x0004
55 #define USUD_FIRSTCLASS 0x0005
57 #define CID_RESOURCE 0x0001
58 #define CID_WIN32 0x0004
59 #define CID_NONSHARED 0x0008
61 WORD USER_HeapSel = 0; /* USER heap selector */
63 static HINSTANCE16 gdi_inst;
65 struct gray_string_info
67 GRAYSTRINGPROC16 proc;
68 LPARAM param;
69 char str[1];
72 /* callback for 16-bit gray string proc with opaque pointer */
73 static BOOL CALLBACK gray_string_callback( HDC hdc, LPARAM param, INT len )
75 const struct gray_string_info *info = (struct gray_string_info *)param;
76 WORD args[4];
77 DWORD ret;
79 args[3] = HDC_16(hdc);
80 args[2] = HIWORD(info->param);
81 args[1] = LOWORD(info->param);
82 args[0] = len;
83 WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
84 return LOWORD(ret);
87 /* callback for 16-bit gray string proc with string pointer */
88 static BOOL CALLBACK gray_string_callback_ptr( HDC hdc, LPARAM param, INT len )
90 const struct gray_string_info *info = CONTAINING_RECORD( (void *)param, struct gray_string_info, str );
91 return gray_string_callback( hdc, (LPARAM)info, len );
94 struct draw_state_info
96 DRAWSTATEPROC16 proc;
97 LPARAM param;
100 /* callback for 16-bit DrawState functions */
101 static BOOL CALLBACK draw_state_callback( HDC hdc, LPARAM lparam, WPARAM wparam, int cx, int cy )
103 const struct draw_state_info *info = (struct draw_state_info *)lparam;
104 WORD args[6];
105 DWORD ret;
107 args[5] = HDC_16(hdc);
108 args[4] = HIWORD(info->param);
109 args[3] = LOWORD(info->param);
110 args[2] = wparam;
111 args[1] = cx;
112 args[0] = cy;
113 WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
114 return LOWORD(ret);
117 /* This function is a copy of the one in objects/font.c */
118 static void logfont_32_to_16( const LOGFONTA* font32, LPLOGFONT16 font16 )
120 font16->lfHeight = font32->lfHeight;
121 font16->lfWidth = font32->lfWidth;
122 font16->lfEscapement = font32->lfEscapement;
123 font16->lfOrientation = font32->lfOrientation;
124 font16->lfWeight = font32->lfWeight;
125 font16->lfItalic = font32->lfItalic;
126 font16->lfUnderline = font32->lfUnderline;
127 font16->lfStrikeOut = font32->lfStrikeOut;
128 font16->lfCharSet = font32->lfCharSet;
129 font16->lfOutPrecision = font32->lfOutPrecision;
130 font16->lfClipPrecision = font32->lfClipPrecision;
131 font16->lfQuality = font32->lfQuality;
132 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
133 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
136 static int get_bitmap_width_bytes( int width, int bpp )
138 switch(bpp)
140 case 1:
141 return 2 * ((width+15) / 16);
142 case 4:
143 return 2 * ((width+3) / 4);
144 case 24:
145 width *= 3;
146 /* fall through */
147 case 8:
148 return width + (width & 1);
149 case 16:
150 case 15:
151 return width * 2;
152 case 32:
153 return width * 4;
154 default:
155 WARN("Unknown depth %d, please report.\n", bpp );
157 return -1;
160 /***********************************************************************
161 * Helper for wsprintf16
164 #define WPRINTF_LEFTALIGN 0x0001 /* Align output on the left ('-' prefix) */
165 #define WPRINTF_PREFIX_HEX 0x0002 /* Prefix hex with 0x ('#' prefix) */
166 #define WPRINTF_ZEROPAD 0x0004 /* Pad with zeros ('0' prefix) */
167 #define WPRINTF_LONG 0x0008 /* Long arg ('l' prefix) */
168 #define WPRINTF_SHORT 0x0010 /* Short arg ('h' prefix) */
169 #define WPRINTF_UPPER_HEX 0x0020 /* Upper-case hex ('X' specifier) */
171 typedef enum
173 WPR_UNKNOWN,
174 WPR_CHAR,
175 WPR_STRING,
176 WPR_SIGNED,
177 WPR_UNSIGNED,
178 WPR_HEXA
179 } WPRINTF_TYPE;
181 typedef struct
183 UINT flags;
184 UINT width;
185 UINT precision;
186 WPRINTF_TYPE type;
187 } WPRINTF_FORMAT;
189 static INT parse_format( LPCSTR format, WPRINTF_FORMAT *res )
191 LPCSTR p = format;
193 res->flags = 0;
194 res->width = 0;
195 res->precision = 0;
196 if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; }
197 if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; }
198 if (*p == '0') { res->flags |= WPRINTF_ZEROPAD; p++; }
199 while ((*p >= '0') && (*p <= '9')) /* width field */
201 res->width = res->width * 10 + *p - '0';
202 p++;
204 if (*p == '.') /* precision field */
206 p++;
207 while ((*p >= '0') && (*p <= '9'))
209 res->precision = res->precision * 10 + *p - '0';
210 p++;
213 if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; }
214 else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; }
215 switch(*p)
217 case 'c':
218 case 'C': /* no Unicode in Win16 */
219 res->type = WPR_CHAR;
220 break;
221 case 's':
222 case 'S':
223 res->type = WPR_STRING;
224 break;
225 case 'd':
226 case 'i':
227 res->type = WPR_SIGNED;
228 break;
229 case 'u':
230 res->type = WPR_UNSIGNED;
231 break;
232 case 'p':
233 res->width = 8;
234 res->flags |= WPRINTF_ZEROPAD;
235 /* fall through */
236 case 'X':
237 res->flags |= WPRINTF_UPPER_HEX;
238 /* fall through */
239 case 'x':
240 res->type = WPR_HEXA;
241 break;
242 default: /* unknown format char */
243 res->type = WPR_UNKNOWN;
244 p--; /* print format as normal char */
245 break;
247 return (INT)(p - format) + 1;
251 /**********************************************************************
252 * Management of the 16-bit cursors and icons
255 struct cache_entry
257 struct list entry;
258 HINSTANCE16 inst;
259 HRSRC16 rsrc;
260 HRSRC16 group;
261 HICON16 icon;
262 INT count;
265 static struct list icon_cache = LIST_INIT( icon_cache );
267 static const WORD ICON_HOTSPOT = 0x4242;
269 static HICON16 alloc_icon_handle( unsigned int size )
271 HGLOBAL16 handle = GlobalAlloc16( GMEM_MOVEABLE, size + sizeof(ULONG_PTR) );
272 char *ptr = GlobalLock16( handle );
273 memset( ptr + size, 0, sizeof(ULONG_PTR) );
274 GlobalUnlock16( handle );
275 FarSetOwner16( handle, 0 );
276 return handle;
279 static CURSORICONINFO *get_icon_ptr( HICON16 handle )
281 return GlobalLock16( handle );
284 static void release_icon_ptr( HICON16 handle, CURSORICONINFO *ptr )
286 GlobalUnlock16( handle );
289 static HICON store_icon_32( HICON16 icon16, HICON icon )
291 HICON ret = 0;
292 CURSORICONINFO *ptr = get_icon_ptr( icon16 );
294 if (ptr)
296 unsigned int and_size = ptr->nHeight * get_bitmap_width_bytes( ptr->nWidth, 1 );
297 unsigned int xor_size = ptr->nHeight * get_bitmap_width_bytes( ptr->nWidth, ptr->bBitsPerPixel );
298 if (GlobalSize16( icon16 ) >= sizeof(*ptr) + sizeof(ULONG_PTR) + and_size + xor_size )
300 memcpy( &ret, (char *)(ptr + 1) + and_size + xor_size, sizeof(ret) );
301 memcpy( (char *)(ptr + 1) + and_size + xor_size, &icon, sizeof(icon) );
302 wow_handlers32.set_icon_param( icon, icon16 );
304 release_icon_ptr( icon16, ptr );
306 return ret;
309 static int free_icon_handle( HICON16 handle )
311 HICON icon32;
313 if ((icon32 = store_icon_32( handle, 0 ))) DestroyIcon( icon32 );
314 return GlobalFree16( handle );
317 /* retrieve the 32-bit counterpart of a 16-bit icon, creating it if needed */
318 HICON get_icon_32( HICON16 icon16 )
320 HICON ret = 0;
321 CURSORICONINFO *ptr = get_icon_ptr( icon16 );
323 if (ptr)
325 unsigned int and_size = ptr->nHeight * get_bitmap_width_bytes( ptr->nWidth, 1 );
326 unsigned int xor_size = ptr->nHeight * get_bitmap_width_bytes( ptr->nWidth, ptr->bBitsPerPixel );
327 if (GlobalSize16( icon16 ) >= sizeof(*ptr) + sizeof(ULONG_PTR) + xor_size + and_size )
329 memcpy( &ret, (char *)(ptr + 1) + xor_size + and_size, sizeof(ret) );
330 if (!ret)
332 ICONINFO iinfo;
334 iinfo.fIcon = (ptr->ptHotSpot.x == ICON_HOTSPOT) && (ptr->ptHotSpot.y == ICON_HOTSPOT);
335 iinfo.xHotspot = ptr->ptHotSpot.x;
336 iinfo.yHotspot = ptr->ptHotSpot.y;
337 iinfo.hbmMask = CreateBitmap( ptr->nWidth, ptr->nHeight, 1, 1, ptr + 1 );
338 iinfo.hbmColor = CreateBitmap( ptr->nWidth, ptr->nHeight, ptr->bPlanes, ptr->bBitsPerPixel,
339 (char *)(ptr + 1) + and_size );
340 ret = CreateIconIndirect( &iinfo );
341 DeleteObject( iinfo.hbmMask );
342 DeleteObject( iinfo.hbmColor );
343 memcpy( (char *)(ptr + 1) + xor_size + and_size, &ret, sizeof(ret) );
344 wow_handlers32.set_icon_param( ret, icon16 );
347 release_icon_ptr( icon16, ptr );
349 return ret;
352 /* retrieve the 16-bit counterpart of a 32-bit icon, creating it if needed */
353 HICON16 get_icon_16( HICON icon )
355 HICON16 ret = wow_handlers32.get_icon_param( icon );
357 if (!ret)
359 ICONINFO info;
360 BITMAP bm;
361 UINT and_size, xor_size;
362 void *xor_bits = NULL, *and_bits;
363 CURSORICONINFO cinfo;
365 if (!(GetIconInfo( icon, &info ))) return 0;
366 GetObjectW( info.hbmMask, sizeof(bm), &bm );
367 and_size = bm.bmHeight * bm.bmWidthBytes;
368 if (!(and_bits = HeapAlloc( GetProcessHeap(), 0, and_size ))) goto done;
369 GetBitmapBits( info.hbmMask, and_size, and_bits );
370 if (info.hbmColor)
372 GetObjectW( info.hbmColor, sizeof(bm), &bm );
373 xor_size = bm.bmHeight * bm.bmWidthBytes;
374 if (!(xor_bits = HeapAlloc( GetProcessHeap(), 0, xor_size ))) goto done;
375 GetBitmapBits( info.hbmColor, xor_size, xor_bits );
377 else
379 bm.bmHeight /= 2;
380 xor_bits = (char *)and_bits + and_size / 2;
382 if (!info.fIcon)
384 cinfo.ptHotSpot.x = info.xHotspot;
385 cinfo.ptHotSpot.y = info.yHotspot;
387 else cinfo.ptHotSpot.x = cinfo.ptHotSpot.y = ICON_HOTSPOT;
389 cinfo.nWidth = bm.bmWidth;
390 cinfo.nHeight = bm.bmHeight;
391 cinfo.nWidthBytes = bm.bmWidthBytes;
392 cinfo.bPlanes = bm.bmPlanes;
393 cinfo.bBitsPerPixel = bm.bmBitsPixel;
395 if ((ret = CreateCursorIconIndirect16( 0, &cinfo, and_bits, xor_bits )))
396 store_icon_32( ret, icon );
398 done:
399 if (info.hbmColor)
401 HeapFree( GetProcessHeap(), 0, xor_bits );
402 DeleteObject( info.hbmColor );
404 HeapFree( GetProcessHeap(), 0, and_bits );
405 DeleteObject( info.hbmMask );
407 return ret;
410 static void add_shared_icon( HINSTANCE16 inst, HRSRC16 rsrc, HRSRC16 group, HICON16 icon )
412 struct cache_entry *cache = HeapAlloc( GetProcessHeap(), 0, sizeof(*cache) );
414 if (!cache) return;
415 cache->inst = inst;
416 cache->rsrc = rsrc;
417 cache->group = group;
418 cache->icon = icon;
419 cache->count = 1;
420 list_add_tail( &icon_cache, &cache->entry );
423 static HICON16 find_shared_icon( HINSTANCE16 inst, HRSRC16 rsrc )
425 struct cache_entry *cache;
427 LIST_FOR_EACH_ENTRY( cache, &icon_cache, struct cache_entry, entry )
429 if (cache->inst != inst || cache->rsrc != rsrc) continue;
430 cache->count++;
431 return cache->icon;
433 return 0;
436 static int release_shared_icon( HICON16 icon )
438 struct cache_entry *cache;
440 LIST_FOR_EACH_ENTRY( cache, &icon_cache, struct cache_entry, entry )
442 if (cache->icon != icon) continue;
443 if (!cache->count) return 0;
444 return --cache->count;
446 return -1;
449 static void free_module_icons( HINSTANCE16 inst )
451 struct cache_entry *cache, *next;
453 LIST_FOR_EACH_ENTRY_SAFE( cache, next, &icon_cache, struct cache_entry, entry )
455 if (cache->inst != inst) continue;
456 list_remove( &cache->entry );
457 free_icon_handle( cache->icon );
458 HeapFree( GetProcessHeap(), 0, cache );
462 /**********************************************************************
463 * Management of the 16-bit clipboard formats
466 struct clipboard_format
468 struct list entry;
469 UINT format;
470 HANDLE16 data;
473 static struct list clipboard_formats = LIST_INIT( clipboard_formats );
475 static void set_clipboard_format( UINT format, HANDLE16 data )
477 struct clipboard_format *fmt;
479 /* replace it if it exists already */
480 LIST_FOR_EACH_ENTRY( fmt, &clipboard_formats, struct clipboard_format, entry )
482 if (fmt->format != format) continue;
483 GlobalFree16( fmt->data );
484 fmt->data = data;
485 return;
488 if ((fmt = HeapAlloc( GetProcessHeap(), 0, sizeof(*fmt) )))
490 fmt->format = format;
491 fmt->data = data;
492 list_add_tail( &clipboard_formats, &fmt->entry );
496 static void free_clipboard_formats(void)
498 struct list *head;
500 while ((head = list_head( &clipboard_formats )))
502 struct clipboard_format *fmt = LIST_ENTRY( head, struct clipboard_format, entry );
503 list_remove( &fmt->entry );
504 GlobalFree16( fmt->data );
505 HeapFree( GetProcessHeap(), 0, fmt );
510 /***********************************************************************
511 * OldExitWindows (USER.2)
513 void WINAPI OldExitWindows16(void)
515 ExitWindows16(0, 0);
519 /**********************************************************************
520 * InitApp (USER.5)
522 INT16 WINAPI InitApp16( HINSTANCE16 hInstance )
524 /* Create task message queue */
525 return (InitThreadInput16( 0, 0 ) != 0);
529 /***********************************************************************
530 * ExitWindows (USER.7)
532 BOOL16 WINAPI ExitWindows16( DWORD dwReturnCode, UINT16 wReserved )
534 return ExitWindowsEx( EWX_LOGOFF, 0xffffffff );
538 /***********************************************************************
539 * GetTimerResolution (USER.14)
541 LONG WINAPI GetTimerResolution16(void)
543 return (1000);
547 /***********************************************************************
548 * ClipCursor (USER.16)
550 BOOL16 WINAPI ClipCursor16( const RECT16 *rect )
552 RECT rect32;
554 if (!rect) return ClipCursor( NULL );
555 rect32.left = rect->left;
556 rect32.top = rect->top;
557 rect32.right = rect->right;
558 rect32.bottom = rect->bottom;
559 return ClipCursor( &rect32 );
563 /***********************************************************************
564 * GetCursorPos (USER.17)
566 BOOL16 WINAPI GetCursorPos16( POINT16 *pt )
568 POINT pos;
569 if (!pt) return FALSE;
570 GetCursorPos(&pos);
571 pt->x = pos.x;
572 pt->y = pos.y;
573 return TRUE;
577 /*******************************************************************
578 * AnyPopup (USER.52)
580 BOOL16 WINAPI AnyPopup16(void)
582 return AnyPopup();
586 /***********************************************************************
587 * SetCursor (USER.69)
589 HCURSOR16 WINAPI SetCursor16(HCURSOR16 hCursor)
591 return get_icon_16( SetCursor( get_icon_32(hCursor) ));
595 /***********************************************************************
596 * SetCursorPos (USER.70)
598 void WINAPI SetCursorPos16( INT16 x, INT16 y )
600 SetCursorPos( x, y );
604 /***********************************************************************
605 * ShowCursor (USER.71)
607 INT16 WINAPI ShowCursor16(BOOL16 bShow)
609 return ShowCursor(bShow);
613 /***********************************************************************
614 * SetRect (USER.72)
616 void WINAPI SetRect16( LPRECT16 rect, INT16 left, INT16 top, INT16 right, INT16 bottom )
618 rect->left = left;
619 rect->right = right;
620 rect->top = top;
621 rect->bottom = bottom;
625 /***********************************************************************
626 * SetRectEmpty (USER.73)
628 void WINAPI SetRectEmpty16( LPRECT16 rect )
630 rect->left = rect->right = rect->top = rect->bottom = 0;
634 /***********************************************************************
635 * CopyRect (USER.74)
637 BOOL16 WINAPI CopyRect16( RECT16 *dest, const RECT16 *src )
639 *dest = *src;
640 return TRUE;
644 /***********************************************************************
645 * IsRectEmpty (USER.75)
647 * Bug compat: Windows checks for 0 or negative width/height.
649 BOOL16 WINAPI IsRectEmpty16( const RECT16 *rect )
651 return ((rect->left >= rect->right) || (rect->top >= rect->bottom));
655 /***********************************************************************
656 * PtInRect (USER.76)
658 BOOL16 WINAPI PtInRect16( const RECT16 *rect, POINT16 pt )
660 return ((pt.x >= rect->left) && (pt.x < rect->right) &&
661 (pt.y >= rect->top) && (pt.y < rect->bottom));
665 /***********************************************************************
666 * OffsetRect (USER.77)
668 void WINAPI OffsetRect16( LPRECT16 rect, INT16 x, INT16 y )
670 rect->left += x;
671 rect->right += x;
672 rect->top += y;
673 rect->bottom += y;
677 /***********************************************************************
678 * InflateRect (USER.78)
680 void WINAPI InflateRect16( LPRECT16 rect, INT16 x, INT16 y )
682 rect->left -= x;
683 rect->top -= y;
684 rect->right += x;
685 rect->bottom += y;
689 /***********************************************************************
690 * IntersectRect (USER.79)
692 BOOL16 WINAPI IntersectRect16( LPRECT16 dest, const RECT16 *src1,
693 const RECT16 *src2 )
695 if (IsRectEmpty16(src1) || IsRectEmpty16(src2) ||
696 (src1->left >= src2->right) || (src2->left >= src1->right) ||
697 (src1->top >= src2->bottom) || (src2->top >= src1->bottom))
699 SetRectEmpty16( dest );
700 return FALSE;
702 dest->left = max( src1->left, src2->left );
703 dest->right = min( src1->right, src2->right );
704 dest->top = max( src1->top, src2->top );
705 dest->bottom = min( src1->bottom, src2->bottom );
706 return TRUE;
710 /***********************************************************************
711 * UnionRect (USER.80)
713 BOOL16 WINAPI UnionRect16( LPRECT16 dest, const RECT16 *src1,
714 const RECT16 *src2 )
716 if (IsRectEmpty16(src1))
718 if (IsRectEmpty16(src2))
720 SetRectEmpty16( dest );
721 return FALSE;
723 else *dest = *src2;
725 else
727 if (IsRectEmpty16(src2)) *dest = *src1;
728 else
730 dest->left = min( src1->left, src2->left );
731 dest->right = max( src1->right, src2->right );
732 dest->top = min( src1->top, src2->top );
733 dest->bottom = max( src1->bottom, src2->bottom );
736 return TRUE;
740 /***********************************************************************
741 * FillRect (USER.81)
742 * NOTE
743 * The Win16 variant doesn't support special color brushes like
744 * the Win32 one, despite the fact that Win16, as well as Win32,
745 * supports special background brushes for a window class.
747 INT16 WINAPI FillRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
749 HBRUSH prevBrush;
751 /* coordinates are logical so we cannot fast-check 'rect',
752 * it will be done later in the PatBlt().
755 if (!(prevBrush = SelectObject( HDC_32(hdc), HBRUSH_32(hbrush) ))) return 0;
756 PatBlt( HDC_32(hdc), rect->left, rect->top,
757 rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
758 SelectObject( HDC_32(hdc), prevBrush );
759 return 1;
763 /***********************************************************************
764 * InvertRect (USER.82)
766 void WINAPI InvertRect16( HDC16 hdc, const RECT16 *rect )
768 PatBlt( HDC_32(hdc), rect->left, rect->top,
769 rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
773 /***********************************************************************
774 * FrameRect (USER.83)
776 INT16 WINAPI FrameRect16( HDC16 hdc, const RECT16 *rect16, HBRUSH16 hbrush )
778 RECT rect;
780 rect.left = rect16->left;
781 rect.top = rect16->top;
782 rect.right = rect16->right;
783 rect.bottom = rect16->bottom;
784 return FrameRect( HDC_32(hdc), &rect, HBRUSH_32(hbrush) );
788 /***********************************************************************
789 * DrawIcon (USER.84)
791 BOOL16 WINAPI DrawIcon16(HDC16 hdc, INT16 x, INT16 y, HICON16 hIcon)
793 return DrawIcon(HDC_32(hdc), x, y, get_icon_32(hIcon) );
797 /***********************************************************************
798 * DrawText (USER.85)
800 INT16 WINAPI DrawText16( HDC16 hdc, LPCSTR str, INT16 count, LPRECT16 rect, UINT16 flags )
802 INT16 ret;
804 if (rect)
806 RECT rect32;
808 rect32.left = rect->left;
809 rect32.top = rect->top;
810 rect32.right = rect->right;
811 rect32.bottom = rect->bottom;
812 ret = DrawTextA( HDC_32(hdc), str, count, &rect32, flags );
813 rect->left = rect32.left;
814 rect->top = rect32.top;
815 rect->right = rect32.right;
816 rect->bottom = rect32.bottom;
818 else ret = DrawTextA( HDC_32(hdc), str, count, NULL, flags);
819 return ret;
823 /***********************************************************************
824 * IconSize (USER.86)
826 * See "Undocumented Windows". Used by W2.0 paint.exe.
828 DWORD WINAPI IconSize16(void)
830 return MAKELONG(GetSystemMetrics(SM_CYICON), GetSystemMetrics(SM_CXICON));
834 /***********************************************************************
835 * AdjustWindowRect (USER.102)
837 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
839 return AdjustWindowRectEx16( rect, style, menu, 0 );
843 /***********************************************************************
844 * MessageBeep (USER.104)
846 void WINAPI MessageBeep16( UINT16 i )
848 MessageBeep( i );
852 /**************************************************************************
853 * CloseClipboard (USER.138)
855 BOOL16 WINAPI CloseClipboard16(void)
857 BOOL ret = CloseClipboard();
858 if (ret) free_clipboard_formats();
859 return ret;
863 /**************************************************************************
864 * EmptyClipboard (USER.139)
866 BOOL16 WINAPI EmptyClipboard16(void)
868 BOOL ret = EmptyClipboard();
869 if (ret) free_clipboard_formats();
870 return ret;
874 /**************************************************************************
875 * SetClipboardData (USER.141)
877 HANDLE16 WINAPI SetClipboardData16( UINT16 format, HANDLE16 data16 )
879 HANDLE data32 = 0;
881 switch (format)
883 case CF_BITMAP:
884 case CF_PALETTE:
885 data32 = HGDIOBJ_32( data16 );
886 break;
888 case CF_METAFILEPICT:
890 METAHEADER *header;
891 METAFILEPICT *pict32;
892 METAFILEPICT16 *pict16 = GlobalLock16( data16 );
894 if (pict16)
896 if (!(data32 = GlobalAlloc( GMEM_MOVEABLE, sizeof(*pict32) ))) return 0;
897 pict32 = GlobalLock( data32 );
898 pict32->mm = pict16->mm;
899 pict32->xExt = pict16->xExt;
900 pict32->yExt = pict16->yExt;
901 header = GlobalLock16( pict16->hMF );
902 pict32->hMF = SetMetaFileBitsEx( header->mtSize * 2, (BYTE *)header );
903 GlobalUnlock16( pict16->hMF );
904 GlobalUnlock( data32 );
906 set_clipboard_format( format, data16 );
907 break;
910 case CF_ENHMETAFILE:
911 FIXME( "enhmetafile not supported in 16-bit\n" );
912 return 0;
914 default:
915 if (format >= CF_GDIOBJFIRST && format <= CF_GDIOBJLAST)
916 data32 = HGDIOBJ_32( data16 );
917 else if (format >= CF_PRIVATEFIRST && format <= CF_PRIVATELAST)
918 data32 = HANDLE_32( data16 );
919 else
921 UINT size = GlobalSize16( data16 );
922 void *ptr32, *ptr16 = GlobalLock16( data16 );
923 if (ptr16)
925 if (!(data32 = GlobalAlloc( GMEM_MOVEABLE, size ))) return 0;
926 ptr32 = GlobalLock( data32 );
927 memcpy( ptr32, ptr16, size );
928 GlobalUnlock( data32 );
930 set_clipboard_format( format, data16 );
932 break;
935 if (!SetClipboardData( format, data32 )) return 0;
936 return data16;
940 /**************************************************************************
941 * GetClipboardData (USER.142)
943 HANDLE16 WINAPI GetClipboardData16( UINT16 format )
945 HANDLE data32 = GetClipboardData( format );
946 HANDLE16 data16 = 0;
947 UINT size;
948 void *ptr;
950 if (!data32) return 0;
952 switch (format)
954 case CF_BITMAP:
955 case CF_PALETTE:
956 data16 = HGDIOBJ_16( data32 );
957 break;
959 case CF_METAFILEPICT:
961 METAFILEPICT16 *pict16;
962 METAFILEPICT *pict32 = GlobalLock( data32 );
964 if (pict32)
966 if (!(data16 = GlobalAlloc16( GMEM_MOVEABLE, sizeof(*pict16) ))) return 0;
967 pict16 = GlobalLock16( data16 );
968 pict16->mm = pict32->mm;
969 pict16->xExt = pict32->xExt;
970 pict16->yExt = pict32->yExt;
971 size = GetMetaFileBitsEx( pict32->hMF, 0, NULL );
972 pict16->hMF = GlobalAlloc16( GMEM_MOVEABLE, size );
973 ptr = GlobalLock16( pict16->hMF );
974 GetMetaFileBitsEx( pict32->hMF, size, ptr );
975 GlobalUnlock16( pict16->hMF );
976 GlobalUnlock16( data16 );
977 set_clipboard_format( format, data16 );
979 break;
982 case CF_ENHMETAFILE:
983 FIXME( "enhmetafile not supported in 16-bit\n" );
984 return 0;
986 default:
987 if (format >= CF_GDIOBJFIRST && format <= CF_GDIOBJLAST)
988 data16 = HGDIOBJ_16( data32 );
989 else if (format >= CF_PRIVATEFIRST && format <= CF_PRIVATELAST)
990 data16 = HANDLE_16( data32 );
991 else
993 void *ptr16, *ptr32 = GlobalLock( data32 );
994 if (ptr32)
996 size = GlobalSize( data32 );
997 if (!(data16 = GlobalAlloc16( GMEM_MOVEABLE, size ))) return 0;
998 ptr16 = GlobalLock16( data16 );
999 memcpy( ptr16, ptr32, size );
1000 GlobalUnlock16( data16 );
1001 set_clipboard_format( format, data16 );
1004 break;
1006 return data16;
1010 /**************************************************************************
1011 * CountClipboardFormats (USER.143)
1013 INT16 WINAPI CountClipboardFormats16(void)
1015 return CountClipboardFormats();
1019 /**************************************************************************
1020 * EnumClipboardFormats (USER.144)
1022 UINT16 WINAPI EnumClipboardFormats16( UINT16 id )
1024 return EnumClipboardFormats( id );
1028 /**************************************************************************
1029 * RegisterClipboardFormat (USER.145)
1031 UINT16 WINAPI RegisterClipboardFormat16( LPCSTR name )
1033 return RegisterClipboardFormatA( name );
1037 /**************************************************************************
1038 * GetClipboardFormatName (USER.146)
1040 INT16 WINAPI GetClipboardFormatName16( UINT16 id, LPSTR buffer, INT16 maxlen )
1042 return GetClipboardFormatNameA( id, buffer, maxlen );
1046 /**********************************************************************
1047 * LoadMenu (USER.150)
1049 HMENU16 WINAPI LoadMenu16( HINSTANCE16 instance, LPCSTR name )
1051 HRSRC16 hRsrc;
1052 HGLOBAL16 handle;
1053 HMENU16 hMenu;
1055 if (HIWORD(name) && name[0] == '#') name = ULongToPtr(atoi( name + 1 ));
1056 if (!name) return 0;
1058 instance = GetExePtr( instance );
1059 if (!(hRsrc = FindResource16( instance, name, (LPSTR)RT_MENU ))) return 0;
1060 if (!(handle = LoadResource16( instance, hRsrc ))) return 0;
1061 hMenu = LoadMenuIndirect16(LockResource16(handle));
1062 FreeResource16( handle );
1063 return hMenu;
1067 /**********************************************************************
1068 * CreateMenu (USER.151)
1070 HMENU16 WINAPI CreateMenu16(void)
1072 return HMENU_16( CreateMenu() );
1076 /**********************************************************************
1077 * DestroyMenu (USER.152)
1079 BOOL16 WINAPI DestroyMenu16( HMENU16 hMenu )
1081 return DestroyMenu( HMENU_32(hMenu) );
1085 /*******************************************************************
1086 * ChangeMenu (USER.153)
1088 BOOL16 WINAPI ChangeMenu16( HMENU16 hMenu, UINT16 pos, SEGPTR data,
1089 UINT16 id, UINT16 flags )
1091 if (flags & MF_APPEND) return AppendMenu16( hMenu, flags & ~MF_APPEND, id, data );
1093 /* FIXME: Word passes the item id in 'pos' and 0 or 0xffff as id */
1094 /* for MF_DELETE. We should check the parameters for all others */
1095 /* MF_* actions also (anybody got a doc on ChangeMenu?). */
1097 if (flags & MF_DELETE) return DeleteMenu16(hMenu, pos, flags & ~MF_DELETE);
1098 if (flags & MF_CHANGE) return ModifyMenu16(hMenu, pos, flags & ~MF_CHANGE, id, data );
1099 if (flags & MF_REMOVE) return RemoveMenu16(hMenu, flags & MF_BYPOSITION ? pos : id,
1100 flags & ~MF_REMOVE );
1101 /* Default: MF_INSERT */
1102 return InsertMenu16( hMenu, pos, flags, id, data );
1106 /*******************************************************************
1107 * CheckMenuItem (USER.154)
1109 BOOL16 WINAPI CheckMenuItem16( HMENU16 hMenu, UINT16 id, UINT16 flags )
1111 return CheckMenuItem( HMENU_32(hMenu), id, flags );
1115 /**********************************************************************
1116 * EnableMenuItem (USER.155)
1118 BOOL16 WINAPI EnableMenuItem16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
1120 return EnableMenuItem( HMENU_32(hMenu), wItemID, wFlags );
1124 /**********************************************************************
1125 * GetSubMenu (USER.159)
1127 HMENU16 WINAPI GetSubMenu16( HMENU16 hMenu, INT16 nPos )
1129 return HMENU_16( GetSubMenu( HMENU_32(hMenu), nPos ) );
1133 /*******************************************************************
1134 * GetMenuString (USER.161)
1136 INT16 WINAPI GetMenuString16( HMENU16 hMenu, UINT16 wItemID,
1137 LPSTR str, INT16 nMaxSiz, UINT16 wFlags )
1139 return GetMenuStringA( HMENU_32(hMenu), wItemID, str, nMaxSiz, wFlags );
1143 /**********************************************************************
1144 * WinHelp (USER.171)
1146 BOOL16 WINAPI WinHelp16( HWND16 hWnd, LPCSTR lpHelpFile, UINT16 wCommand,
1147 DWORD dwData )
1149 BOOL ret;
1150 DWORD mutex_count;
1152 /* We might call WinExec() */
1153 ReleaseThunkLock(&mutex_count);
1155 ret = WinHelpA(WIN_Handle32(hWnd), lpHelpFile, wCommand, (DWORD)MapSL(dwData));
1157 RestoreThunkLock(mutex_count);
1158 return ret;
1162 /***********************************************************************
1163 * LoadCursor (USER.173)
1165 HCURSOR16 WINAPI LoadCursor16(HINSTANCE16 hInstance, LPCSTR name)
1167 return LoadImage16( hInstance, name, IMAGE_CURSOR, 0, 0, LR_SHARED | LR_DEFAULTSIZE );
1171 /***********************************************************************
1172 * LoadIcon (USER.174)
1174 HICON16 WINAPI LoadIcon16(HINSTANCE16 hInstance, LPCSTR name)
1176 return LoadImage16( hInstance, name, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE );
1179 /**********************************************************************
1180 * LoadBitmap (USER.175)
1182 HBITMAP16 WINAPI LoadBitmap16(HINSTANCE16 hInstance, LPCSTR name)
1184 return LoadImage16( hInstance, name, IMAGE_BITMAP, 0, 0, 0 );
1187 /**********************************************************************
1188 * LoadString (USER.176)
1190 INT16 WINAPI LoadString16( HINSTANCE16 instance, UINT16 resource_id, LPSTR buffer, INT16 buflen )
1192 HGLOBAL16 hmem;
1193 HRSRC16 hrsrc;
1194 unsigned char *p;
1195 int string_num;
1196 int ret;
1198 TRACE("inst=%04x id=%04x buff=%p len=%d\n", instance, resource_id, buffer, buflen);
1200 hrsrc = FindResource16( instance, MAKEINTRESOURCEA((resource_id>>4)+1), (LPSTR)RT_STRING );
1201 if (!hrsrc) return 0;
1202 hmem = LoadResource16( instance, hrsrc );
1203 if (!hmem) return 0;
1205 p = LockResource16(hmem);
1206 string_num = resource_id & 0x000f;
1207 while (string_num--) p += *p + 1;
1209 if (buffer == NULL) ret = *p;
1210 else
1212 ret = min(buflen - 1, *p);
1213 if (ret > 0)
1215 memcpy(buffer, p + 1, ret);
1216 buffer[ret] = '\0';
1218 else if (buflen > 1)
1220 buffer[0] = '\0';
1221 ret = 0;
1223 TRACE( "%s loaded\n", debugstr_a(buffer));
1225 FreeResource16( hmem );
1226 return ret;
1229 /**********************************************************************
1230 * LoadAccelerators (USER.177)
1232 HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, LPCSTR lpTableName)
1234 HRSRC16 hRsrc;
1235 HGLOBAL16 hMem;
1236 ACCEL16 *table16;
1237 HACCEL ret = 0;
1239 TRACE("%04x %s\n", instance, debugstr_a(lpTableName) );
1241 if (!(hRsrc = FindResource16( instance, lpTableName, (LPSTR)RT_ACCELERATOR )) ||
1242 !(hMem = LoadResource16(instance,hRsrc)))
1244 WARN("couldn't find %04x %s\n", instance, debugstr_a(lpTableName));
1245 return 0;
1247 if ((table16 = LockResource16( hMem )))
1249 DWORD i, count = SizeofResource16( instance, hRsrc ) / sizeof(*table16);
1250 ACCEL *table = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*table) );
1251 if (table)
1253 for (i = 0; i < count; i++)
1255 table[i].fVirt = table16[i].fVirt & 0x7f;
1256 table[i].key = table16[i].key;
1257 table[i].cmd = table16[i].cmd;
1259 ret = CreateAcceleratorTableA( table, count );
1260 HeapFree( GetProcessHeap(), 0, table );
1263 FreeResource16( hMem );
1264 return HACCEL_16(ret);
1267 /***********************************************************************
1268 * GetSystemMetrics (USER.179)
1270 INT16 WINAPI GetSystemMetrics16( INT16 index )
1272 return GetSystemMetrics( index );
1276 /*************************************************************************
1277 * GetSysColor (USER.180)
1279 COLORREF WINAPI GetSysColor16( INT16 index )
1281 return GetSysColor( index );
1285 /*************************************************************************
1286 * SetSysColors (USER.181)
1288 VOID WINAPI SetSysColors16( INT16 count, const INT16 *list16, const COLORREF *values )
1290 INT i, *list;
1292 if ((list = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*list) )))
1294 for (i = 0; i < count; i++) list[i] = list16[i];
1295 SetSysColors( count, list, values );
1296 HeapFree( GetProcessHeap(), 0, list );
1301 /***********************************************************************
1302 * GrayString (USER.185)
1304 BOOL16 WINAPI GrayString16( HDC16 hdc, HBRUSH16 hbr, GRAYSTRINGPROC16 gsprc,
1305 LPARAM lParam, INT16 cch, INT16 x, INT16 y,
1306 INT16 cx, INT16 cy )
1308 BOOL ret;
1310 if (!gsprc) return GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), NULL,
1311 (LPARAM)MapSL(lParam), cch, x, y, cx, cy );
1313 if (cch == -1 || (cch && cx && cy))
1315 /* lParam can be treated as an opaque pointer */
1316 struct gray_string_info info;
1318 info.proc = gsprc;
1319 info.param = lParam;
1320 ret = GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), gray_string_callback,
1321 (LPARAM)&info, cch, x, y, cx, cy );
1323 else /* here we need some string conversions */
1325 char *str16 = MapSL(lParam);
1326 struct gray_string_info *info;
1328 if (!cch) cch = strlen(str16);
1329 info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( struct gray_string_info, str[cch] ));
1330 if (!info) return FALSE;
1331 info->proc = gsprc;
1332 info->param = lParam;
1333 memcpy( info->str, str16, cch );
1334 ret = GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), gray_string_callback_ptr,
1335 (LPARAM)info->str, cch, x, y, cx, cy );
1336 HeapFree( GetProcessHeap(), 0, info );
1338 return ret;
1342 /***********************************************************************
1343 * SwapMouseButton (USER.186)
1345 BOOL16 WINAPI SwapMouseButton16( BOOL16 fSwap )
1347 return SwapMouseButton( fSwap );
1351 /**************************************************************************
1352 * IsClipboardFormatAvailable (USER.193)
1354 BOOL16 WINAPI IsClipboardFormatAvailable16( UINT16 wFormat )
1356 return IsClipboardFormatAvailable( wFormat );
1360 /***********************************************************************
1361 * TabbedTextOut (USER.196)
1363 LONG WINAPI TabbedTextOut16( HDC16 hdc, INT16 x, INT16 y, LPCSTR lpstr,
1364 INT16 count, INT16 nb_tabs, const INT16 *tabs16, INT16 tab_org )
1366 LONG ret;
1367 INT i, *tabs = HeapAlloc( GetProcessHeap(), 0, nb_tabs * sizeof(*tabs) );
1368 if (!tabs) return 0;
1369 for (i = 0; i < nb_tabs; i++) tabs[i] = tabs16[i];
1370 ret = TabbedTextOutA( HDC_32(hdc), x, y, lpstr, count, nb_tabs, tabs, tab_org );
1371 HeapFree( GetProcessHeap(), 0, tabs );
1372 return ret;
1376 /***********************************************************************
1377 * GetTabbedTextExtent (USER.197)
1379 DWORD WINAPI GetTabbedTextExtent16( HDC16 hdc, LPCSTR lpstr, INT16 count,
1380 INT16 nb_tabs, const INT16 *tabs16 )
1382 LONG ret;
1383 INT i, *tabs = HeapAlloc( GetProcessHeap(), 0, nb_tabs * sizeof(*tabs) );
1384 if (!tabs) return 0;
1385 for (i = 0; i < nb_tabs; i++) tabs[i] = tabs16[i];
1386 ret = GetTabbedTextExtentA( HDC_32(hdc), lpstr, count, nb_tabs, tabs );
1387 HeapFree( GetProcessHeap(), 0, tabs );
1388 return ret;
1392 /***********************************************************************
1393 * UserSeeUserDo (USER.216)
1395 DWORD WINAPI UserSeeUserDo16(WORD wReqType, WORD wParam1, WORD wParam2, WORD wParam3)
1397 STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
1398 HANDLE16 oldDS = stack16->ds;
1399 DWORD ret = (DWORD)-1;
1401 stack16->ds = USER_HeapSel;
1402 switch (wReqType)
1404 case USUD_LOCALALLOC:
1405 ret = LocalAlloc16(wParam1, wParam3);
1406 break;
1407 case USUD_LOCALFREE:
1408 ret = LocalFree16(wParam1);
1409 break;
1410 case USUD_LOCALCOMPACT:
1411 ret = LocalCompact16(wParam3);
1412 break;
1413 case USUD_LOCALHEAP:
1414 ret = USER_HeapSel;
1415 break;
1416 case USUD_FIRSTCLASS:
1417 FIXME("return a pointer to the first window class.\n");
1418 break;
1419 default:
1420 WARN("wReqType %04x (unknown)\n", wReqType);
1422 stack16->ds = oldDS;
1423 return ret;
1427 /***********************************************************************
1428 * LookupMenuHandle (USER.217)
1430 HMENU16 WINAPI LookupMenuHandle16( HMENU16 hmenu, INT16 id )
1432 FIXME( "%04x %04x: stub\n", hmenu, id );
1433 return hmenu;
1437 static LPCSTR parse_menu_resource( LPCSTR res, HMENU hMenu, BOOL oldFormat )
1439 WORD flags, id = 0;
1440 LPCSTR str;
1441 BOOL end_flag;
1445 /* Windows 3.00 and later use a WORD for the flags, whereas 1.x and 2.x use a BYTE. */
1446 if (oldFormat)
1448 flags = GET_BYTE(res);
1449 res += sizeof(BYTE);
1451 else
1453 flags = GET_WORD(res);
1454 res += sizeof(WORD);
1457 end_flag = flags & MF_END;
1458 /* Remove MF_END because it has the same value as MF_HILITE */
1459 flags &= ~MF_END;
1460 if (!(flags & MF_POPUP))
1462 id = GET_WORD(res);
1463 res += sizeof(WORD);
1465 str = res;
1466 res += strlen(str) + 1;
1467 if (flags & MF_POPUP)
1469 HMENU hSubMenu = CreatePopupMenu();
1470 if (!hSubMenu) return NULL;
1471 if (!(res = parse_menu_resource( res, hSubMenu, oldFormat ))) return NULL;
1472 AppendMenuA( hMenu, flags, (UINT_PTR)hSubMenu, str );
1474 else /* Not a popup */
1476 AppendMenuA( hMenu, flags, id, *str ? str : NULL );
1478 } while (!end_flag);
1479 return res;
1482 /**********************************************************************
1483 * LoadMenuIndirect (USER.220)
1485 HMENU16 WINAPI LoadMenuIndirect16( LPCVOID template )
1487 BOOL oldFormat;
1488 HMENU hMenu;
1489 WORD version, offset;
1490 LPCSTR p = template;
1492 TRACE("(%p)\n", template );
1494 /* Windows 1.x and 2.x menus have a slightly different menu format from 3.x menus */
1495 oldFormat = (GetExeVersion16() < 0x0300);
1497 /* Windows 3.00 and later menu items are preceded by a MENUITEMTEMPLATEHEADER structure */
1498 if (!oldFormat)
1500 version = GET_WORD(p);
1501 p += sizeof(WORD);
1502 if (version)
1504 WARN("version must be 0 for Win16 >= 3.00 applications\n" );
1505 return 0;
1507 offset = GET_WORD(p);
1508 p += sizeof(WORD) + offset;
1511 if (!(hMenu = CreateMenu())) return 0;
1512 if (!parse_menu_resource( p, hMenu, oldFormat ))
1514 DestroyMenu( hMenu );
1515 return 0;
1517 return HMENU_16(hMenu);
1521 /*************************************************************************
1522 * ScrollDC (USER.221)
1524 BOOL16 WINAPI ScrollDC16( HDC16 hdc, INT16 dx, INT16 dy, const RECT16 *rect,
1525 const RECT16 *cliprc, HRGN16 hrgnUpdate,
1526 LPRECT16 rcUpdate )
1528 RECT rect32, clipRect32, rcUpdate32;
1529 BOOL16 ret;
1531 if (rect)
1533 rect32.left = rect->left;
1534 rect32.top = rect->top;
1535 rect32.right = rect->right;
1536 rect32.bottom = rect->bottom;
1538 if (cliprc)
1540 clipRect32.left = cliprc->left;
1541 clipRect32.top = cliprc->top;
1542 clipRect32.right = cliprc->right;
1543 clipRect32.bottom = cliprc->bottom;
1545 ret = ScrollDC( HDC_32(hdc), dx, dy, rect ? &rect32 : NULL,
1546 cliprc ? &clipRect32 : NULL, HRGN_32(hrgnUpdate),
1547 &rcUpdate32 );
1548 if (rcUpdate)
1550 rcUpdate->left = rcUpdate32.left;
1551 rcUpdate->top = rcUpdate32.top;
1552 rcUpdate->right = rcUpdate32.right;
1553 rcUpdate->bottom = rcUpdate32.bottom;
1555 return ret;
1559 /***********************************************************************
1560 * GetSystemDebugState (USER.231)
1562 WORD WINAPI GetSystemDebugState16(void)
1564 return 0; /* FIXME */
1568 /***********************************************************************
1569 * EqualRect (USER.244)
1571 BOOL16 WINAPI EqualRect16( const RECT16* rect1, const RECT16* rect2 )
1573 return ((rect1->left == rect2->left) && (rect1->right == rect2->right) &&
1574 (rect1->top == rect2->top) && (rect1->bottom == rect2->bottom));
1578 /***********************************************************************
1579 * ExitWindowsExec (USER.246)
1581 BOOL16 WINAPI ExitWindowsExec16( LPCSTR lpszExe, LPCSTR lpszParams )
1583 TRACE("Should run the following in DOS-mode: \"%s %s\"\n",
1584 lpszExe, lpszParams);
1585 return ExitWindowsEx( EWX_LOGOFF, 0xffffffff );
1589 /***********************************************************************
1590 * GetCursor (USER.247)
1592 HCURSOR16 WINAPI GetCursor16(void)
1594 return get_icon_16( GetCursor() );
1598 /**********************************************************************
1599 * GetAsyncKeyState (USER.249)
1601 INT16 WINAPI GetAsyncKeyState16( INT16 key )
1603 return GetAsyncKeyState( key );
1607 /**********************************************************************
1608 * GetMenuState (USER.250)
1610 UINT16 WINAPI GetMenuState16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
1612 return GetMenuState( HMENU_32(hMenu), wItemID, wFlags );
1616 /**************************************************************************
1617 * SendDriverMessage (USER.251)
1619 LRESULT WINAPI SendDriverMessage16(HDRVR16 hDriver, UINT16 msg, LPARAM lParam1,
1620 LPARAM lParam2)
1622 FIXME("(%04x, %04x, %08lx, %08lx): stub\n", hDriver, msg, lParam1, lParam2);
1623 return 0;
1627 /**************************************************************************
1628 * OpenDriver (USER.252)
1630 HDRVR16 WINAPI OpenDriver16(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam2)
1632 FIXME( "(%s, %s, %08lx): stub\n", debugstr_a(lpDriverName), debugstr_a(lpSectionName), lParam2);
1633 return 0;
1637 /**************************************************************************
1638 * CloseDriver (USER.253)
1640 LRESULT WINAPI CloseDriver16(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
1642 FIXME( "(%04x, %08lx, %08lx): stub\n", hDrvr, lParam1, lParam2);
1643 return FALSE;
1647 /**************************************************************************
1648 * GetDriverModuleHandle (USER.254)
1650 HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDrvr)
1652 FIXME("(%04x): stub\n", hDrvr);
1653 return 0;
1657 /**************************************************************************
1658 * DefDriverProc (USER.255)
1660 LRESULT WINAPI DefDriverProc16(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg,
1661 LPARAM lParam1, LPARAM lParam2)
1663 FIXME( "devID=0x%08x hDrv=0x%04x wMsg=%04x lP1=0x%08lx lP2=0x%08lx: stub\n",
1664 dwDevID, hDriv, wMsg, lParam1, lParam2);
1665 return 0;
1669 /**************************************************************************
1670 * GetDriverInfo (USER.256)
1672 struct DRIVERINFOSTRUCT16;
1673 BOOL16 WINAPI GetDriverInfo16(HDRVR16 hDrvr, struct DRIVERINFOSTRUCT16 *lpDrvInfo)
1675 FIXME( "(%04x, %p): stub\n", hDrvr, lpDrvInfo);
1676 return FALSE;
1680 /**************************************************************************
1681 * GetNextDriver (USER.257)
1683 HDRVR16 WINAPI GetNextDriver16(HDRVR16 hDrvr, DWORD dwFlags)
1685 FIXME( "(%04x, %08x): stub\n", hDrvr, dwFlags);
1686 return 0;
1690 /**********************************************************************
1691 * GetMenuItemCount (USER.263)
1693 INT16 WINAPI GetMenuItemCount16( HMENU16 hMenu )
1695 return GetMenuItemCount( HMENU_32(hMenu) );
1699 /**********************************************************************
1700 * GetMenuItemID (USER.264)
1702 UINT16 WINAPI GetMenuItemID16( HMENU16 hMenu, INT16 nPos )
1704 return GetMenuItemID( HMENU_32(hMenu), nPos );
1708 /***********************************************************************
1709 * GlobalAddAtom (USER.268)
1711 ATOM WINAPI GlobalAddAtom16(LPCSTR lpString)
1713 return GlobalAddAtomA(lpString);
1716 /***********************************************************************
1717 * GlobalDeleteAtom (USER.269)
1719 ATOM WINAPI GlobalDeleteAtom16(ATOM nAtom)
1721 return GlobalDeleteAtom(nAtom);
1724 /***********************************************************************
1725 * GlobalFindAtom (USER.270)
1727 ATOM WINAPI GlobalFindAtom16(LPCSTR lpString)
1729 return GlobalFindAtomA(lpString);
1732 /***********************************************************************
1733 * GlobalGetAtomName (USER.271)
1735 UINT16 WINAPI GlobalGetAtomName16(ATOM nAtom, LPSTR lpBuffer, INT16 nSize)
1737 return GlobalGetAtomNameA(nAtom, lpBuffer, nSize);
1741 /***********************************************************************
1742 * ControlPanelInfo (USER.273)
1744 void WINAPI ControlPanelInfo16( INT16 nInfoType, WORD wData, LPSTR lpBuffer )
1746 FIXME("(%d, %04x, %p): stub.\n", nInfoType, wData, lpBuffer);
1750 /***********************************************************************
1751 * OldSetDeskPattern (USER.279)
1753 BOOL16 WINAPI SetDeskPattern16(void)
1755 return SystemParametersInfoA( SPI_SETDESKPATTERN, -1, NULL, FALSE );
1759 /***********************************************************************
1760 * GetSysColorBrush (USER.281)
1762 HBRUSH16 WINAPI GetSysColorBrush16( INT16 index )
1764 return HBRUSH_16( GetSysColorBrush(index) );
1768 /***********************************************************************
1769 * SelectPalette (USER.282)
1771 HPALETTE16 WINAPI SelectPalette16( HDC16 hdc, HPALETTE16 hpal, BOOL16 bForceBackground )
1773 return HPALETTE_16( SelectPalette( HDC_32(hdc), HPALETTE_32(hpal), bForceBackground ));
1776 /***********************************************************************
1777 * RealizePalette (USER.283)
1779 UINT16 WINAPI RealizePalette16( HDC16 hdc )
1781 return UserRealizePalette( HDC_32(hdc) );
1785 /***********************************************************************
1786 * GetFreeSystemResources (USER.284)
1788 WORD WINAPI GetFreeSystemResources16( WORD resType )
1790 STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
1791 HANDLE16 oldDS = stack16->ds;
1792 int userPercent, gdiPercent;
1794 switch(resType)
1796 case GFSR_USERRESOURCES:
1797 stack16->ds = USER_HeapSel;
1798 userPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1799 gdiPercent = 100;
1800 stack16->ds = oldDS;
1801 break;
1803 case GFSR_GDIRESOURCES:
1804 stack16->ds = gdi_inst;
1805 gdiPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1806 userPercent = 100;
1807 stack16->ds = oldDS;
1808 break;
1810 case GFSR_SYSTEMRESOURCES:
1811 stack16->ds = USER_HeapSel;
1812 userPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1813 stack16->ds = gdi_inst;
1814 gdiPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1815 stack16->ds = oldDS;
1816 break;
1818 default:
1819 userPercent = gdiPercent = 0;
1820 break;
1822 TRACE("<- userPercent %d, gdiPercent %d\n", userPercent, gdiPercent);
1823 return (WORD)min( userPercent, gdiPercent );
1827 /***********************************************************************
1828 * SetDeskWallPaper (USER.285)
1830 BOOL16 WINAPI SetDeskWallPaper16( LPCSTR filename )
1832 return SetDeskWallPaper( filename );
1836 /***********************************************************************
1837 * keybd_event (USER.289)
1839 void WINAPI keybd_event16( CONTEXT *context )
1841 DWORD dwFlags = 0;
1843 if (HIBYTE(context->Eax) & 0x80) dwFlags |= KEYEVENTF_KEYUP;
1844 if (HIBYTE(context->Ebx) & 0x01) dwFlags |= KEYEVENTF_EXTENDEDKEY;
1846 keybd_event( LOBYTE(context->Eax), LOBYTE(context->Ebx),
1847 dwFlags, MAKELONG(LOWORD(context->Esi), LOWORD(context->Edi)) );
1851 /***********************************************************************
1852 * mouse_event (USER.299)
1854 void WINAPI mouse_event16( CONTEXT *context )
1856 mouse_event( LOWORD(context->Eax), LOWORD(context->Ebx), LOWORD(context->Ecx),
1857 LOWORD(context->Edx), MAKELONG(context->Esi, context->Edi) );
1861 /***********************************************************************
1862 * GetClipCursor (USER.309)
1864 void WINAPI GetClipCursor16( RECT16 *rect )
1866 if (rect)
1868 RECT rect32;
1869 GetClipCursor( &rect32 );
1870 rect->left = rect32.left;
1871 rect->top = rect32.top;
1872 rect->right = rect32.right;
1873 rect->bottom = rect32.bottom;
1878 /***********************************************************************
1879 * SignalProc (USER.314)
1881 void WINAPI SignalProc16( HANDLE16 hModule, UINT16 code,
1882 UINT16 uExitFn, HINSTANCE16 hInstance, HQUEUE16 hQueue )
1884 if (code == USIG16_DLL_UNLOAD)
1886 hModule = GetExePtr(hModule);
1887 /* HOOK_FreeModuleHooks( hModule ); */
1888 free_module_classes( hModule );
1889 free_module_icons( hModule );
1894 /***********************************************************************
1895 * SetEventHook (USER.321)
1897 * Used by Turbo Debugger for Windows
1899 FARPROC16 WINAPI SetEventHook16(FARPROC16 lpfnEventHook)
1901 FIXME("(lpfnEventHook=%p): stub\n", lpfnEventHook);
1902 return 0;
1906 /**********************************************************************
1907 * EnableHardwareInput (USER.331)
1909 BOOL16 WINAPI EnableHardwareInput16(BOOL16 bEnable)
1911 FIXME("(%d) - stub\n", bEnable);
1912 return TRUE;
1916 /**********************************************************************
1917 * LoadCursorIconHandler (USER.336)
1919 * Supposed to load resources of Windows 2.x applications.
1921 HGLOBAL16 WINAPI LoadCursorIconHandler16( HGLOBAL16 hResource, HMODULE16 hModule, HRSRC16 hRsrc )
1923 FIXME("(%04x,%04x,%04x): old 2.x resources are not supported!\n", hResource, hModule, hRsrc);
1924 return 0;
1928 /***********************************************************************
1929 * GetMouseEventProc (USER.337)
1931 FARPROC16 WINAPI GetMouseEventProc16(void)
1933 HMODULE16 hmodule = GetModuleHandle16("USER");
1934 return GetProcAddress16( hmodule, "mouse_event" );
1938 /***********************************************************************
1939 * IsUserIdle (USER.333)
1941 BOOL16 WINAPI IsUserIdle16(void)
1943 if ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
1944 return FALSE;
1945 if ( GetAsyncKeyState( VK_RBUTTON ) & 0x8000 )
1946 return FALSE;
1947 if ( GetAsyncKeyState( VK_MBUTTON ) & 0x8000 )
1948 return FALSE;
1949 /* Should check for screen saver activation here ... */
1950 return TRUE;
1954 /**********************************************************************
1955 * LoadDIBIconHandler (USER.357)
1957 * RT_ICON resource loader, installed by USER_SignalProc when module
1958 * is initialized.
1960 HGLOBAL16 WINAPI LoadDIBIconHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc )
1962 /* If hResource is zero we must allocate a new memory block, if it's
1963 * non-zero but GlobalLock() returns NULL then it was discarded and
1964 * we have to recommit some memory, otherwise we just need to check
1965 * the block size. See LoadProc() in 16-bit SDK for more.
1967 FIXME( "%x %x %x: stub, not supported anymore\n", hMemObj, hModule, hRsrc );
1968 return 0;
1971 /**********************************************************************
1972 * LoadDIBCursorHandler (USER.356)
1974 * RT_CURSOR resource loader. Same as above.
1976 HGLOBAL16 WINAPI LoadDIBCursorHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc )
1978 FIXME( "%x %x %x: stub, not supported anymore\n", hMemObj, hModule, hRsrc );
1979 return 0;
1983 /**********************************************************************
1984 * IsMenu (USER.358)
1986 BOOL16 WINAPI IsMenu16( HMENU16 hmenu )
1988 return IsMenu( HMENU_32(hmenu) );
1992 /***********************************************************************
1993 * DCHook (USER.362)
1995 BOOL16 WINAPI DCHook16( HDC16 hdc, WORD code, DWORD data, LPARAM lParam )
1997 FIXME( "hDC = %x, %i: stub\n", hdc, code );
1998 return FALSE;
2002 /**********************************************************************
2003 * LookupIconIdFromDirectoryEx (USER.364)
2005 * FIXME: exact parameter sizes
2007 INT16 WINAPI LookupIconIdFromDirectoryEx16( LPBYTE dir, BOOL16 bIcon,
2008 INT16 width, INT16 height, UINT16 cFlag )
2010 return LookupIconIdFromDirectoryEx( dir, bIcon, width, height, cFlag );
2014 /***********************************************************************
2015 * CopyIcon (USER.368)
2017 HICON16 WINAPI CopyIcon16( HINSTANCE16 hInstance, HICON16 hIcon )
2019 CURSORICONINFO *info = get_icon_ptr( hIcon );
2020 void *and_bits = info + 1;
2021 void *xor_bits = (BYTE *)and_bits + info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
2022 HGLOBAL16 ret = CreateCursorIconIndirect16( hInstance, info, and_bits, xor_bits );
2023 release_icon_ptr( hIcon, info );
2024 return ret;
2028 /***********************************************************************
2029 * CopyCursor (USER.369)
2031 HCURSOR16 WINAPI CopyCursor16( HINSTANCE16 hInstance, HCURSOR16 hCursor )
2033 CURSORICONINFO *info = get_icon_ptr( hCursor );
2034 void *and_bits = info + 1;
2035 void *xor_bits = (BYTE *)and_bits + info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
2036 HGLOBAL16 ret = CreateCursorIconIndirect16( hInstance, info, and_bits, xor_bits );
2037 release_icon_ptr( hCursor, info );
2038 return ret;
2042 /***********************************************************************
2043 * SubtractRect (USER.373)
2045 BOOL16 WINAPI SubtractRect16( LPRECT16 dest, const RECT16 *src1,
2046 const RECT16 *src2 )
2048 RECT16 tmp;
2050 if (IsRectEmpty16( src1 ))
2052 SetRectEmpty16( dest );
2053 return FALSE;
2055 *dest = *src1;
2056 if (IntersectRect16( &tmp, src1, src2 ))
2058 if (EqualRect16( &tmp, dest ))
2060 SetRectEmpty16( dest );
2061 return FALSE;
2063 if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom))
2065 if (tmp.left == dest->left) dest->left = tmp.right;
2066 else if (tmp.right == dest->right) dest->right = tmp.left;
2068 else if ((tmp.left == dest->left) && (tmp.right == dest->right))
2070 if (tmp.top == dest->top) dest->top = tmp.bottom;
2071 else if (tmp.bottom == dest->bottom) dest->bottom = tmp.top;
2074 return TRUE;
2078 /**********************************************************************
2079 * DllEntryPoint (USER.374)
2081 BOOL WINAPI DllEntryPoint( DWORD reason, HINSTANCE16 inst, WORD ds,
2082 WORD heap, DWORD reserved1, WORD reserved2 )
2084 if (reason != DLL_PROCESS_ATTACH) return TRUE;
2085 if (USER_HeapSel) return TRUE; /* already called */
2087 USER_HeapSel = ds;
2088 register_wow_handlers();
2089 gdi_inst = LoadLibrary16( "gdi.exe" );
2090 LoadLibrary16( "display.drv" );
2091 LoadLibrary16( "keyboard.drv" );
2092 LoadLibrary16( "mouse.drv" );
2093 LoadLibrary16( "user.exe" ); /* make sure it never gets unloaded */
2094 return TRUE;
2098 /**********************************************************************
2099 * SetMenuContextHelpId (USER.384)
2101 BOOL16 WINAPI SetMenuContextHelpId16( HMENU16 hMenu, DWORD dwContextHelpID)
2103 return SetMenuContextHelpId( HMENU_32(hMenu), dwContextHelpID );
2107 /**********************************************************************
2108 * GetMenuContextHelpId (USER.385)
2110 DWORD WINAPI GetMenuContextHelpId16( HMENU16 hMenu )
2112 return GetMenuContextHelpId( HMENU_32(hMenu) );
2116 /***********************************************************************
2117 * LoadImage (USER.389)
2119 HANDLE16 WINAPI LoadImage16(HINSTANCE16 hinst, LPCSTR name, UINT16 type, INT16 cx, INT16 cy, UINT16 flags)
2121 HGLOBAL16 handle;
2122 HRSRC16 hRsrc, hGroupRsrc;
2123 DWORD size;
2125 if (!hinst || (flags & LR_LOADFROMFILE))
2127 if (type == IMAGE_BITMAP)
2128 return HBITMAP_16( LoadImageA( 0, name, type, cx, cy, flags ));
2129 else
2130 return get_icon_16( LoadImageA( 0, name, type, cx, cy, flags ));
2133 hinst = GetExePtr( hinst );
2135 if (flags & LR_DEFAULTSIZE)
2137 if (type == IMAGE_ICON)
2139 if (!cx) cx = GetSystemMetrics(SM_CXICON);
2140 if (!cy) cy = GetSystemMetrics(SM_CYICON);
2142 else if (type == IMAGE_CURSOR)
2144 if (!cx) cx = GetSystemMetrics(SM_CXCURSOR);
2145 if (!cy) cy = GetSystemMetrics(SM_CYCURSOR);
2149 switch (type)
2151 case IMAGE_BITMAP:
2153 HBITMAP ret = 0;
2154 char *ptr;
2155 static const WCHAR prefixW[] = {'b','m','p',0};
2156 BITMAPFILEHEADER header;
2157 WCHAR path[MAX_PATH], filename[MAX_PATH];
2158 HANDLE file;
2160 filename[0] = 0;
2161 if (!(hRsrc = FindResource16( hinst, name, (LPCSTR)RT_BITMAP ))) return 0;
2162 if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
2163 if (!(ptr = LockResource16( handle ))) goto done;
2164 size = SizeofResource16( hinst, hRsrc );
2166 header.bfType = 0x4d42; /* 'BM' */
2167 header.bfReserved1 = 0;
2168 header.bfReserved2 = 0;
2169 header.bfSize = sizeof(header) + size;
2170 header.bfOffBits = 0; /* not used by the 32-bit loading code */
2172 if (!GetTempPathW( MAX_PATH, path )) goto done;
2173 if (!GetTempFileNameW( path, prefixW, 0, filename )) goto done;
2175 file = CreateFileW( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
2176 if (file != INVALID_HANDLE_VALUE)
2178 DWORD written;
2179 BOOL ok;
2180 ok = WriteFile( file, &header, sizeof(header), &written, NULL ) && (written == sizeof(header));
2181 if (ok) ok = WriteFile( file, ptr, size, &written, NULL ) && (written == size);
2182 CloseHandle( file );
2183 if (ok) ret = LoadImageW( 0, filename, IMAGE_BITMAP, cx, cy, flags | LR_LOADFROMFILE );
2185 done:
2186 if (filename[0]) DeleteFileW( filename );
2187 FreeResource16( handle );
2188 return HBITMAP_16( ret );
2191 case IMAGE_ICON:
2192 case IMAGE_CURSOR:
2194 HICON16 hIcon = 0;
2195 BYTE *dir, *bits;
2196 INT id = 0;
2198 if (!(hRsrc = FindResource16( hinst, name,
2199 (LPCSTR)(type == IMAGE_ICON ? RT_GROUP_ICON : RT_GROUP_CURSOR ))))
2200 return 0;
2201 hGroupRsrc = hRsrc;
2203 if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
2204 if ((dir = LockResource16( handle ))) id = LookupIconIdFromDirectory( dir, type == IMAGE_ICON );
2205 FreeResource16( handle );
2206 if (!id) return 0;
2208 if (!(hRsrc = FindResource16( hinst, MAKEINTRESOURCEA(id),
2209 (LPCSTR)(type == IMAGE_ICON ? RT_ICON : RT_CURSOR) ))) return 0;
2211 if ((flags & LR_SHARED) && (hIcon = find_shared_icon( hinst, hRsrc ) ) != 0) return hIcon;
2213 if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
2214 bits = LockResource16( handle );
2215 size = SizeofResource16( hinst, hRsrc );
2216 hIcon = CreateIconFromResourceEx16( bits, size, type == IMAGE_ICON, 0x00030000, cx, cy, flags );
2217 FreeResource16( handle );
2219 if (hIcon && (flags & LR_SHARED)) add_shared_icon( hinst, hRsrc, hGroupRsrc, hIcon );
2220 return hIcon;
2222 default:
2223 return 0;
2227 /******************************************************************************
2228 * CopyImage (USER.390) Creates new image and copies attributes to it
2231 HICON16 WINAPI CopyImage16(HANDLE16 hnd, UINT16 type, INT16 desiredx,
2232 INT16 desiredy, UINT16 flags)
2234 if (flags & LR_COPYFROMRESOURCE) FIXME( "LR_COPYFROMRESOURCE not supported\n" );
2236 switch (type)
2238 case IMAGE_BITMAP:
2239 return HBITMAP_16( CopyImage( HBITMAP_32(hnd), type, desiredx, desiredy, flags ));
2240 case IMAGE_ICON:
2241 case IMAGE_CURSOR:
2242 return CopyIcon16( FarGetOwner16(hnd), hnd );
2243 default:
2244 return 0;
2248 /**********************************************************************
2249 * DrawIconEx (USER.394)
2251 BOOL16 WINAPI DrawIconEx16(HDC16 hdc, INT16 xLeft, INT16 yTop, HICON16 hIcon,
2252 INT16 cxWidth, INT16 cyWidth, UINT16 istep,
2253 HBRUSH16 hbr, UINT16 flags)
2255 return DrawIconEx(HDC_32(hdc), xLeft, yTop, get_icon_32(hIcon), cxWidth, cyWidth,
2256 istep, HBRUSH_32(hbr), flags);
2259 /**********************************************************************
2260 * GetIconInfo (USER.395)
2262 BOOL16 WINAPI GetIconInfo16(HICON16 hIcon, LPICONINFO16 iconinfo)
2264 CURSORICONINFO *info = get_icon_ptr( hIcon );
2265 INT height;
2267 if (!info) return FALSE;
2269 if ((info->ptHotSpot.x == ICON_HOTSPOT) && (info->ptHotSpot.y == ICON_HOTSPOT))
2271 iconinfo->fIcon = TRUE;
2272 iconinfo->xHotspot = info->nWidth / 2;
2273 iconinfo->yHotspot = info->nHeight / 2;
2275 else
2277 iconinfo->fIcon = FALSE;
2278 iconinfo->xHotspot = info->ptHotSpot.x;
2279 iconinfo->yHotspot = info->ptHotSpot.y;
2282 height = info->nHeight;
2284 if (info->bBitsPerPixel > 1)
2286 iconinfo->hbmColor = HBITMAP_16( CreateBitmap( info->nWidth, info->nHeight,
2287 info->bPlanes, info->bBitsPerPixel,
2288 (char *)(info + 1)
2289 + info->nHeight *
2290 get_bitmap_width_bytes(info->nWidth,1) ));
2292 else
2294 iconinfo->hbmColor = 0;
2295 height *= 2;
2298 iconinfo->hbmMask = HBITMAP_16( CreateBitmap( info->nWidth, height, 1, 1, info + 1 ));
2299 release_icon_ptr( hIcon, info );
2300 return TRUE;
2304 /***********************************************************************
2305 * FinalUserInit (USER.400)
2307 void WINAPI FinalUserInit16( void )
2309 /* FIXME: Should chain to FinalGdiInit */
2313 /***********************************************************************
2314 * CreateCursor (USER.406)
2316 HCURSOR16 WINAPI CreateCursor16(HINSTANCE16 hInstance,
2317 INT16 xHotSpot, INT16 yHotSpot,
2318 INT16 nWidth, INT16 nHeight,
2319 LPCVOID lpANDbits, LPCVOID lpXORbits)
2321 CURSORICONINFO info;
2323 info.ptHotSpot.x = xHotSpot;
2324 info.ptHotSpot.y = yHotSpot;
2325 info.nWidth = nWidth;
2326 info.nHeight = nHeight;
2327 info.nWidthBytes = 0;
2328 info.bPlanes = 1;
2329 info.bBitsPerPixel = 1;
2331 return CreateCursorIconIndirect16(hInstance, &info, lpANDbits, lpXORbits);
2335 /***********************************************************************
2336 * CreateIcon (USER.407)
2338 HICON16 WINAPI CreateIcon16( HINSTANCE16 hInstance, INT16 nWidth,
2339 INT16 nHeight, BYTE bPlanes, BYTE bBitsPixel,
2340 LPCVOID lpANDbits, LPCVOID lpXORbits )
2342 CURSORICONINFO info;
2344 info.ptHotSpot.x = ICON_HOTSPOT;
2345 info.ptHotSpot.y = ICON_HOTSPOT;
2346 info.nWidth = nWidth;
2347 info.nHeight = nHeight;
2348 info.nWidthBytes = 0;
2349 info.bPlanes = bPlanes;
2350 info.bBitsPerPixel = bBitsPixel;
2352 return CreateCursorIconIndirect16( hInstance, &info, lpANDbits, lpXORbits );
2356 /***********************************************************************
2357 * CreateCursorIconIndirect (USER.408)
2359 HGLOBAL16 WINAPI CreateCursorIconIndirect16( HINSTANCE16 hInstance,
2360 CURSORICONINFO *info,
2361 LPCVOID lpANDbits,
2362 LPCVOID lpXORbits )
2364 HICON16 handle;
2365 CURSORICONINFO *ptr;
2366 int sizeAnd, sizeXor;
2368 hInstance = GetExePtr( hInstance ); /* Make it a module handle */
2369 if (!lpXORbits || !lpANDbits || info->bPlanes != 1) return 0;
2370 info->nWidthBytes = get_bitmap_width_bytes(info->nWidth,info->bBitsPerPixel);
2371 sizeXor = info->nHeight * info->nWidthBytes;
2372 sizeAnd = info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
2373 if (!(handle = alloc_icon_handle( sizeof(CURSORICONINFO) + sizeXor + sizeAnd )))
2374 return 0;
2375 FarSetOwner16( handle, hInstance );
2376 ptr = get_icon_ptr( handle );
2377 memcpy( ptr, info, sizeof(*info) );
2378 memcpy( ptr + 1, lpANDbits, sizeAnd );
2379 memcpy( (char *)(ptr + 1) + sizeAnd, lpXORbits, sizeXor );
2380 release_icon_ptr( handle, ptr );
2381 return handle;
2385 /***********************************************************************
2386 * InitThreadInput (USER.409)
2388 HQUEUE16 WINAPI InitThreadInput16( WORD unknown, WORD flags )
2390 /* nothing to do here */
2391 return 0xbeef;
2395 /*******************************************************************
2396 * InsertMenu (USER.410)
2398 BOOL16 WINAPI InsertMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
2399 UINT16 id, SEGPTR data )
2401 UINT pos32 = (UINT)pos;
2402 if ((pos == (UINT16)-1) && (flags & MF_BYPOSITION)) pos32 = (UINT)-1;
2403 if (IS_MENU_STRING_ITEM(flags) && data)
2404 return InsertMenuA( HMENU_32(hMenu), pos32, flags, id, MapSL(data) );
2406 /* If "data" is an HBITMAP, the high WORD will contain the application's DGROUP selector if the
2407 * application cast (LPSTR)hBitmap rather than (LPSTR)(LONG)hBitmap. */
2408 if (flags & MF_BITMAP) data = (SEGPTR)HBITMAP_32(LOWORD(data));
2409 return InsertMenuA( HMENU_32(hMenu), pos32, flags, id, (LPSTR)data );
2413 /*******************************************************************
2414 * AppendMenu (USER.411)
2416 BOOL16 WINAPI AppendMenu16(HMENU16 hMenu, UINT16 flags, UINT16 id, SEGPTR data)
2418 return InsertMenu16( hMenu, -1, flags | MF_BYPOSITION, id, data );
2422 /**********************************************************************
2423 * RemoveMenu (USER.412)
2425 BOOL16 WINAPI RemoveMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
2427 return RemoveMenu( HMENU_32(hMenu), nPos, wFlags );
2431 /**********************************************************************
2432 * DeleteMenu (USER.413)
2434 BOOL16 WINAPI DeleteMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
2436 return DeleteMenu( HMENU_32(hMenu), nPos, wFlags );
2440 /*******************************************************************
2441 * ModifyMenu (USER.414)
2443 BOOL16 WINAPI ModifyMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
2444 UINT16 id, SEGPTR data )
2446 if (IS_MENU_STRING_ITEM(flags))
2447 return ModifyMenuA( HMENU_32(hMenu), pos, flags, id, MapSL(data) );
2448 return ModifyMenuA( HMENU_32(hMenu), pos, flags, id, (LPSTR)data );
2452 /**********************************************************************
2453 * CreatePopupMenu (USER.415)
2455 HMENU16 WINAPI CreatePopupMenu16(void)
2457 return HMENU_16( CreatePopupMenu() );
2461 /**********************************************************************
2462 * SetMenuItemBitmaps (USER.418)
2464 BOOL16 WINAPI SetMenuItemBitmaps16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags,
2465 HBITMAP16 hNewUnCheck, HBITMAP16 hNewCheck)
2467 return SetMenuItemBitmaps( HMENU_32(hMenu), nPos, wFlags,
2468 HBITMAP_32(hNewUnCheck), HBITMAP_32(hNewCheck) );
2472 /***********************************************************************
2473 * wvsprintf (USER.421)
2475 INT16 WINAPI wvsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 args )
2477 WPRINTF_FORMAT format;
2478 LPSTR p = buffer;
2479 UINT i, len, sign;
2480 CHAR number[20];
2481 CHAR char_view = 0;
2482 LPCSTR lpcstr_view = NULL;
2483 INT int_view;
2484 SEGPTR seg_str;
2486 while (*spec)
2488 if (*spec != '%') { *p++ = *spec++; continue; }
2489 spec++;
2490 if (*spec == '%') { *p++ = *spec++; continue; }
2491 spec += parse_format( spec, &format );
2492 switch(format.type)
2494 case WPR_CHAR:
2495 char_view = VA_ARG16( args, CHAR );
2496 len = format.precision = 1;
2497 break;
2498 case WPR_STRING:
2499 seg_str = VA_ARG16( args, SEGPTR );
2500 if (IsBadReadPtr16( seg_str, 1 )) lpcstr_view = "";
2501 else lpcstr_view = MapSL( seg_str );
2502 if (!lpcstr_view) lpcstr_view = "(null)";
2503 for (len = 0; !format.precision || (len < format.precision); len++)
2504 if (!lpcstr_view[len]) break;
2505 format.precision = len;
2506 break;
2507 case WPR_SIGNED:
2508 if (format.flags & WPRINTF_LONG) int_view = VA_ARG16( args, INT );
2509 else int_view = VA_ARG16( args, INT16 );
2510 len = sprintf( number, "%d", int_view );
2511 break;
2512 case WPR_UNSIGNED:
2513 if (format.flags & WPRINTF_LONG) int_view = VA_ARG16( args, UINT );
2514 else int_view = VA_ARG16( args, UINT16 );
2515 len = sprintf( number, "%u", int_view );
2516 break;
2517 case WPR_HEXA:
2518 if (format.flags & WPRINTF_LONG) int_view = VA_ARG16( args, UINT );
2519 else int_view = VA_ARG16( args, UINT16 );
2520 len = sprintf( number, (format.flags & WPRINTF_UPPER_HEX) ? "%X" : "%x", int_view);
2521 break;
2522 case WPR_UNKNOWN:
2523 continue;
2525 if (format.precision < len) format.precision = len;
2526 if (format.flags & WPRINTF_LEFTALIGN) format.flags &= ~WPRINTF_ZEROPAD;
2527 if ((format.flags & WPRINTF_ZEROPAD) && (format.width > format.precision))
2528 format.precision = format.width;
2529 if (format.flags & WPRINTF_PREFIX_HEX) len += 2;
2531 sign = 0;
2532 if (!(format.flags & WPRINTF_LEFTALIGN))
2533 for (i = format.precision; i < format.width; i++) *p++ = ' ';
2534 switch(format.type)
2536 case WPR_CHAR:
2537 *p = char_view;
2538 /* wsprintf16 ignores null characters */
2539 if (*p != '\0') p++;
2540 else if (format.width > 1) *p++ = ' ';
2541 break;
2542 case WPR_STRING:
2543 if (len) memcpy( p, lpcstr_view, len );
2544 p += len;
2545 break;
2546 case WPR_HEXA:
2547 if (format.flags & WPRINTF_PREFIX_HEX)
2549 *p++ = '0';
2550 *p++ = (format.flags & WPRINTF_UPPER_HEX) ? 'X' : 'x';
2551 len -= 2;
2553 /* fall through */
2554 case WPR_SIGNED:
2555 /* Transfer the sign now, just in case it will be zero-padded*/
2556 if (number[0] == '-')
2558 *p++ = '-';
2559 sign = 1;
2561 /* fall through */
2562 case WPR_UNSIGNED:
2563 for (i = len; i < format.precision; i++) *p++ = '0';
2564 if (len > sign) memcpy( p, number + sign, len - sign );
2565 p += len-sign;
2566 break;
2567 case WPR_UNKNOWN:
2568 continue;
2570 if (format.flags & WPRINTF_LEFTALIGN)
2571 for (i = format.precision; i < format.width; i++) *p++ = ' ';
2573 *p = 0;
2574 return p - buffer;
2578 /***********************************************************************
2579 * _wsprintf (USER.420)
2581 INT16 WINAPIV wsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 valist )
2583 return wvsprintf16( buffer, spec, valist );
2587 /***********************************************************************
2588 * lstrcmp (USER.430)
2590 INT16 WINAPI lstrcmp16( LPCSTR str1, LPCSTR str2 )
2592 int ret;
2593 /* Looks too complicated, but in optimized strcpy we might get
2594 * a 32bit wide difference and would truncate it to 16 bit, so
2595 * erroneously returning equality. */
2596 ret = strcmp( str1, str2 );
2597 if (ret < 0) return -1;
2598 if (ret > 0) return 1;
2599 return 0;
2603 /***********************************************************************
2604 * AnsiUpper (USER.431)
2606 SEGPTR WINAPI AnsiUpper16( SEGPTR strOrChar )
2608 /* uppercase only one char if strOrChar < 0x10000 */
2609 if (HIWORD(strOrChar))
2611 CharUpperA( MapSL(strOrChar) );
2612 return strOrChar;
2614 else return (SEGPTR)CharUpperA( (LPSTR)strOrChar );
2618 /***********************************************************************
2619 * AnsiLower (USER.432)
2621 SEGPTR WINAPI AnsiLower16( SEGPTR strOrChar )
2623 /* lowercase only one char if strOrChar < 0x10000 */
2624 if (HIWORD(strOrChar))
2626 CharLowerA( MapSL(strOrChar) );
2627 return strOrChar;
2629 else return (SEGPTR)CharLowerA( (LPSTR)strOrChar );
2633 /***********************************************************************
2634 * AnsiUpperBuff (USER.437)
2636 UINT16 WINAPI AnsiUpperBuff16( LPSTR str, UINT16 len )
2638 CharUpperBuffA( str, len ? len : 65536 );
2639 return len;
2643 /***********************************************************************
2644 * AnsiLowerBuff (USER.438)
2646 UINT16 WINAPI AnsiLowerBuff16( LPSTR str, UINT16 len )
2648 CharLowerBuffA( str, len ? len : 65536 );
2649 return len;
2653 /*******************************************************************
2654 * InsertMenuItem (USER.441)
2656 * FIXME: untested
2658 BOOL16 WINAPI InsertMenuItem16( HMENU16 hmenu, UINT16 pos, BOOL16 byposition,
2659 const MENUITEMINFO16 *mii )
2661 MENUITEMINFOA miia;
2663 miia.cbSize = sizeof(miia);
2664 miia.fMask = mii->fMask;
2665 miia.dwTypeData = (LPSTR)mii->dwTypeData;
2666 miia.fType = mii->fType;
2667 miia.fState = mii->fState;
2668 miia.wID = mii->wID;
2669 miia.hSubMenu = HMENU_32(mii->hSubMenu);
2670 miia.hbmpChecked = HBITMAP_32(mii->hbmpChecked);
2671 miia.hbmpUnchecked = HBITMAP_32(mii->hbmpUnchecked);
2672 miia.dwItemData = mii->dwItemData;
2673 miia.cch = mii->cch;
2674 if (IS_MENU_STRING_ITEM(miia.fType))
2675 miia.dwTypeData = MapSL(mii->dwTypeData);
2676 return InsertMenuItemA( HMENU_32(hmenu), pos, byposition, &miia );
2680 /**********************************************************************
2681 * DrawState (USER.449)
2683 BOOL16 WINAPI DrawState16( HDC16 hdc, HBRUSH16 hbr, DRAWSTATEPROC16 func, LPARAM ldata,
2684 WPARAM16 wdata, INT16 x, INT16 y, INT16 cx, INT16 cy, UINT16 flags )
2686 struct draw_state_info info;
2687 UINT opcode = flags & 0xf;
2689 if (opcode == DST_TEXT || opcode == DST_PREFIXTEXT)
2691 /* make sure DrawStateA doesn't try to use ldata as a pointer */
2692 if (!wdata) wdata = strlen( MapSL(ldata) );
2693 if (!cx || !cy)
2695 SIZE s;
2696 if (!GetTextExtentPoint32A( HDC_32(hdc), MapSL(ldata), wdata, &s )) return FALSE;
2697 if (!cx) cx = s.cx;
2698 if (!cy) cy = s.cy;
2701 info.proc = func;
2702 info.param = ldata;
2703 return DrawStateA( HDC_32(hdc), HBRUSH_32(hbr), draw_state_callback,
2704 (LPARAM)&info, wdata, x, y, cx, cy, flags );
2708 /**********************************************************************
2709 * CreateIconFromResourceEx (USER.450)
2711 * FIXME: not sure about exact parameter types
2713 HICON16 WINAPI CreateIconFromResourceEx16(LPBYTE bits, UINT16 cbSize,
2714 BOOL16 bIcon, DWORD dwVersion,
2715 INT16 width, INT16 height,
2716 UINT16 cFlag)
2718 return get_icon_16( CreateIconFromResourceEx( bits, cbSize, bIcon, dwVersion, width, height, cFlag ));
2722 /***********************************************************************
2723 * AdjustWindowRectEx (USER.454)
2725 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style, BOOL16 menu, DWORD exStyle )
2727 RECT rect32;
2728 BOOL ret;
2730 rect32.left = rect->left;
2731 rect32.top = rect->top;
2732 rect32.right = rect->right;
2733 rect32.bottom = rect->bottom;
2734 ret = AdjustWindowRectEx( &rect32, style, menu, exStyle );
2735 rect->left = rect32.left;
2736 rect->top = rect32.top;
2737 rect->right = rect32.right;
2738 rect->bottom = rect32.bottom;
2739 return ret;
2743 /**********************************************************************
2744 * GetIconID (USER.455)
2746 WORD WINAPI GetIconID16( HGLOBAL16 hResource, DWORD resType )
2748 BYTE *dir = GlobalLock16(hResource);
2750 switch (resType)
2752 case RT_CURSOR:
2753 return LookupIconIdFromDirectoryEx16( dir, FALSE, GetSystemMetrics(SM_CXCURSOR),
2754 GetSystemMetrics(SM_CYCURSOR), LR_MONOCHROME );
2755 case RT_ICON:
2756 return LookupIconIdFromDirectoryEx16( dir, TRUE, GetSystemMetrics(SM_CXICON),
2757 GetSystemMetrics(SM_CYICON), 0 );
2759 return 0;
2763 /**********************************************************************
2764 * LoadIconHandler (USER.456)
2766 HICON16 WINAPI LoadIconHandler16( HGLOBAL16 hResource, BOOL16 bNew )
2768 return CreateIconFromResourceEx16( LockResource16( hResource ), 0xffff, TRUE,
2769 bNew ? 0x00030000 : 0x00020000, 0, 0, LR_DEFAULTCOLOR );
2773 /***********************************************************************
2774 * DestroyIcon (USER.457)
2776 BOOL16 WINAPI DestroyIcon16(HICON16 hIcon)
2778 int count;
2780 TRACE("%04x\n", hIcon );
2782 count = release_shared_icon( hIcon );
2783 if (count != -1) return !count;
2784 /* assume non-shared */
2785 free_icon_handle( hIcon );
2786 return TRUE;
2789 /***********************************************************************
2790 * DestroyCursor (USER.458)
2792 BOOL16 WINAPI DestroyCursor16(HCURSOR16 hCursor)
2794 return DestroyIcon16( hCursor );
2798 /***********************************************************************
2799 * DumpIcon (USER.459)
2801 DWORD WINAPI DumpIcon16( SEGPTR pInfo, WORD *lpLen,
2802 SEGPTR *lpXorBits, SEGPTR *lpAndBits )
2804 CURSORICONINFO *info = MapSL( pInfo );
2805 int sizeAnd, sizeXor;
2807 if (!info) return 0;
2808 sizeXor = info->nHeight * info->nWidthBytes;
2809 sizeAnd = info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
2810 if (lpAndBits) *lpAndBits = pInfo + sizeof(CURSORICONINFO);
2811 if (lpXorBits) *lpXorBits = pInfo + sizeof(CURSORICONINFO) + sizeAnd;
2812 if (lpLen) *lpLen = sizeof(CURSORICONINFO) + sizeAnd + sizeXor;
2813 return MAKELONG( sizeXor, sizeXor );
2817 /*******************************************************************
2818 * DRAG_QueryUpdate16
2820 * Recursively find a child that contains spDragInfo->pt point
2821 * and send WM_QUERYDROPOBJECT. Helper for DragObject16.
2823 static BOOL DRAG_QueryUpdate16( HWND hQueryWnd, SEGPTR spDragInfo )
2825 BOOL bResult;
2826 WPARAM wParam;
2827 POINT pt, old_pt;
2828 LPDRAGINFO16 ptrDragInfo = MapSL(spDragInfo);
2829 RECT tempRect;
2830 HWND child;
2832 if (!IsWindowEnabled(hQueryWnd)) return FALSE;
2834 old_pt.x = ptrDragInfo->pt.x;
2835 old_pt.y = ptrDragInfo->pt.y;
2836 pt = old_pt;
2837 ScreenToClient( hQueryWnd, &pt );
2838 child = ChildWindowFromPointEx( hQueryWnd, pt, CWP_SKIPINVISIBLE );
2839 if (!child) return FALSE;
2841 if (child != hQueryWnd)
2843 wParam = 0;
2844 if (DRAG_QueryUpdate16( child, spDragInfo )) return TRUE;
2846 else
2848 GetClientRect( hQueryWnd, &tempRect );
2849 wParam = !PtInRect( &tempRect, pt );
2852 ptrDragInfo->pt.x = pt.x;
2853 ptrDragInfo->pt.y = pt.y;
2854 ptrDragInfo->hScope = HWND_16(hQueryWnd);
2856 bResult = SendMessage16( HWND_16(hQueryWnd), WM_QUERYDROPOBJECT, wParam, spDragInfo );
2858 if (!bResult)
2860 ptrDragInfo->pt.x = old_pt.x;
2861 ptrDragInfo->pt.y = old_pt.y;
2863 return bResult;
2867 /******************************************************************************
2868 * DragObject (USER.464)
2870 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2871 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2873 MSG msg;
2874 LPDRAGINFO16 lpDragInfo;
2875 SEGPTR spDragInfo;
2876 HCURSOR hOldCursor=0, hBummer=0, hCursor32;
2877 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO16));
2878 HCURSOR hCurrentCursor = 0;
2879 HWND16 hCurrentWnd = 0;
2881 lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo);
2882 spDragInfo = WOWGlobalLock16(hDragInfo);
2884 if( !lpDragInfo || !spDragInfo ) return 0L;
2886 if (!(hBummer = LoadCursorA(0, MAKEINTRESOURCEA(OCR_NO))))
2888 GlobalFree16(hDragInfo);
2889 return 0L;
2892 if ((hCursor32 = get_icon_32( hCursor ))) SetCursor( hCursor32 );
2894 lpDragInfo->hWnd = hWnd;
2895 lpDragInfo->hScope = 0;
2896 lpDragInfo->wFlags = wObj;
2897 lpDragInfo->hList = szList; /* near pointer! */
2898 lpDragInfo->hOfStruct = hOfStruct;
2899 lpDragInfo->l = 0L;
2901 SetCapture( HWND_32(hWnd) );
2902 ShowCursor( TRUE );
2906 GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST );
2908 *(lpDragInfo+1) = *lpDragInfo;
2910 lpDragInfo->pt.x = msg.pt.x;
2911 lpDragInfo->pt.y = msg.pt.y;
2913 /* update DRAGINFO struct */
2914 if( DRAG_QueryUpdate16(WIN_Handle32(hwndScope), spDragInfo) > 0 )
2915 hCurrentCursor = hCursor32;
2916 else
2918 hCurrentCursor = hBummer;
2919 lpDragInfo->hScope = 0;
2921 if( hCurrentCursor )
2922 SetCursor(hCurrentCursor);
2924 /* send WM_DRAGLOOP */
2925 SendMessage16( hWnd, WM_DRAGLOOP, hCurrentCursor != hBummer, spDragInfo );
2926 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2927 if( hCurrentWnd != lpDragInfo->hScope )
2929 if( hCurrentWnd )
2930 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2931 MAKELPARAM(LOWORD(spDragInfo)+sizeof(DRAGINFO16),
2932 HIWORD(spDragInfo)) );
2933 hCurrentWnd = lpDragInfo->hScope;
2934 if( hCurrentWnd )
2935 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, spDragInfo);
2937 else
2938 if( hCurrentWnd )
2939 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, spDragInfo);
2941 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2943 ReleaseCapture();
2944 ShowCursor( FALSE );
2946 if( hCursor ) SetCursor(hOldCursor);
2948 if( hCurrentCursor != hBummer )
2949 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2950 hWnd, spDragInfo );
2951 else
2952 msg.lParam = 0;
2953 GlobalFree16(hDragInfo);
2955 return (DWORD)(msg.lParam);
2959 /***********************************************************************
2960 * DrawFocusRect (USER.466)
2962 void WINAPI DrawFocusRect16( HDC16 hdc, const RECT16* rc )
2964 RECT rect32;
2966 rect32.left = rc->left;
2967 rect32.top = rc->top;
2968 rect32.right = rc->right;
2969 rect32.bottom = rc->bottom;
2970 DrawFocusRect( HDC_32(hdc), &rect32 );
2974 /***********************************************************************
2975 * AnsiNext (USER.472)
2977 SEGPTR WINAPI AnsiNext16(SEGPTR current)
2979 char *ptr = MapSL(current);
2980 return current + (CharNextA(ptr) - ptr);
2984 /***********************************************************************
2985 * AnsiPrev (USER.473)
2987 SEGPTR WINAPI AnsiPrev16( LPCSTR start, SEGPTR current )
2989 char *ptr = MapSL(current);
2990 return current - (ptr - CharPrevA( start, ptr ));
2994 /****************************************************************************
2995 * GetKeyboardLayoutName (USER.477)
2997 INT16 WINAPI GetKeyboardLayoutName16( LPSTR name )
2999 return GetKeyboardLayoutNameA( name );
3003 /***********************************************************************
3004 * SystemParametersInfo (USER.483)
3006 BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
3007 LPVOID lpvParam, UINT16 fuWinIni )
3009 BOOL16 ret;
3011 TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
3013 switch (uAction)
3015 case SPI_GETBEEP:
3016 case SPI_GETSCREENSAVEACTIVE:
3017 case SPI_GETICONTITLEWRAP:
3018 case SPI_GETMENUDROPALIGNMENT:
3019 case SPI_GETFASTTASKSWITCH:
3020 case SPI_GETDRAGFULLWINDOWS:
3022 BOOL tmp;
3023 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
3024 if (ret && lpvParam) *(BOOL16 *)lpvParam = tmp;
3025 break;
3028 case SPI_GETBORDER:
3029 case SPI_ICONHORIZONTALSPACING:
3030 case SPI_GETSCREENSAVETIMEOUT:
3031 case SPI_GETGRIDGRANULARITY:
3032 case SPI_GETKEYBOARDDELAY:
3033 case SPI_ICONVERTICALSPACING:
3035 INT tmp;
3036 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
3037 if (ret && lpvParam) *(INT16 *)lpvParam = tmp;
3038 break;
3041 case SPI_GETKEYBOARDSPEED:
3042 case SPI_GETMOUSEHOVERWIDTH:
3043 case SPI_GETMOUSEHOVERHEIGHT:
3044 case SPI_GETMOUSEHOVERTIME:
3046 DWORD tmp;
3047 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
3048 if (ret && lpvParam) *(WORD *)lpvParam = tmp;
3049 break;
3052 case SPI_GETICONTITLELOGFONT:
3054 LOGFONTA tmp;
3055 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
3056 if (ret && lpvParam) logfont_32_to_16( &tmp, (LPLOGFONT16)lpvParam );
3057 break;
3060 case SPI_GETNONCLIENTMETRICS:
3062 NONCLIENTMETRICSA tmp;
3063 LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
3064 if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
3066 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
3067 ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
3068 if (ret)
3070 lpnm16->iBorderWidth = tmp.iBorderWidth;
3071 lpnm16->iScrollWidth = tmp.iScrollWidth;
3072 lpnm16->iScrollHeight = tmp.iScrollHeight;
3073 lpnm16->iCaptionWidth = tmp.iCaptionWidth;
3074 lpnm16->iCaptionHeight = tmp.iCaptionHeight;
3075 lpnm16->iSmCaptionWidth = tmp.iSmCaptionWidth;
3076 lpnm16->iSmCaptionHeight = tmp.iSmCaptionHeight;
3077 lpnm16->iMenuWidth = tmp.iMenuWidth;
3078 lpnm16->iMenuHeight = tmp.iMenuHeight;
3079 logfont_32_to_16( &tmp.lfCaptionFont, &lpnm16->lfCaptionFont );
3080 logfont_32_to_16( &tmp.lfSmCaptionFont, &lpnm16->lfSmCaptionFont );
3081 logfont_32_to_16( &tmp.lfMenuFont, &lpnm16->lfMenuFont );
3082 logfont_32_to_16( &tmp.lfStatusFont, &lpnm16->lfStatusFont );
3083 logfont_32_to_16( &tmp.lfMessageFont, &lpnm16->lfMessageFont );
3086 else /* winfile 95 sets cbSize to 340 */
3087 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
3088 break;
3091 case SPI_GETWORKAREA:
3093 RECT tmp;
3094 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
3095 if (ret && lpvParam)
3097 RECT16 *r16 = lpvParam;
3098 r16->left = tmp.left;
3099 r16->top = tmp.top;
3100 r16->right = tmp.right;
3101 r16->bottom = tmp.bottom;
3103 break;
3106 default:
3107 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
3108 break;
3111 return ret;
3115 /***********************************************************************
3116 * USER_489 (USER.489)
3118 LONG WINAPI stub_USER_489(void)
3120 FIXME("stub\n");
3121 return 0;
3125 /***********************************************************************
3126 * USER_490 (USER.490)
3128 LONG WINAPI stub_USER_490(void)
3130 FIXME("stub\n");
3131 return 0;
3135 /***********************************************************************
3136 * USER_492 (USER.492)
3138 LONG WINAPI stub_USER_492(void)
3140 FIXME("stub\n");
3141 return 0;
3145 /***********************************************************************
3146 * USER_496 (USER.496)
3148 LONG WINAPI stub_USER_496(void)
3150 FIXME("stub\n");
3151 return 0;
3155 /***********************************************************************
3156 * FormatMessage (USER.606)
3158 DWORD WINAPI FormatMessage16(
3159 DWORD dwFlags,
3160 SEGPTR lpSource, /* [in] NOTE: not always a valid pointer */
3161 WORD dwMessageId,
3162 WORD dwLanguageId,
3163 LPSTR lpBuffer, /* [out] NOTE: *((HLOCAL16*)) for FORMAT_MESSAGE_ALLOCATE_BUFFER*/
3164 WORD nSize,
3165 LPDWORD args ) /* [in] NOTE: va_list *args */
3167 /* This implementation is completely dependent on the format of the va_list on x86 CPUs */
3168 LPSTR target,t;
3169 DWORD talloced;
3170 LPSTR from,f;
3171 DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
3172 BOOL eos = FALSE;
3173 LPSTR allocstring = NULL;
3175 TRACE("(0x%x,%x,%d,0x%x,%p,%d,%p)\n",
3176 dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
3177 if ((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
3178 && (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)) return 0;
3179 if ((dwFlags & FORMAT_MESSAGE_FROM_STRING)
3180 &&((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
3181 || (dwFlags & FORMAT_MESSAGE_FROM_HMODULE))) return 0;
3183 if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
3184 FIXME("line wrapping (%u) not supported.\n", width);
3185 from = NULL;
3186 if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
3188 char *source = MapSL(lpSource);
3189 from = HeapAlloc( GetProcessHeap(), 0, strlen(source)+1 );
3190 strcpy( from, source );
3192 else if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
3193 from = HeapAlloc( GetProcessHeap(),0,200 );
3194 sprintf(from,"Systemmessage, messageid = 0x%08x\n",dwMessageId);
3196 else if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
3197 INT16 bufsize;
3198 HINSTANCE16 hinst16 = ((HINSTANCE16)lpSource & 0xffff);
3200 dwMessageId &= 0xFFFF;
3201 bufsize=LoadString16(hinst16,dwMessageId,NULL,0);
3202 if (bufsize) {
3203 from = HeapAlloc( GetProcessHeap(), 0, bufsize +1);
3204 LoadString16(hinst16,dwMessageId,from,bufsize+1);
3207 target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
3208 t = target;
3209 talloced= 100;
3211 #define ADD_TO_T(c) \
3212 do { \
3213 *t++=c;\
3214 if (t-target == talloced) {\
3215 target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
3216 t = target+talloced;\
3217 talloced*=2;\
3219 } while(0)
3221 if (from) {
3222 f=from;
3223 while (*f && !eos) {
3224 if (*f=='%') {
3225 int insertnr;
3226 char *fmtstr,*x,*lastf;
3227 DWORD *argliststart;
3229 fmtstr = NULL;
3230 lastf = f;
3231 f++;
3232 if (!*f) {
3233 ADD_TO_T('%');
3234 continue;
3236 switch (*f) {
3237 case '1':case '2':case '3':case '4':case '5':
3238 case '6':case '7':case '8':case '9':
3239 insertnr=*f-'0';
3240 switch (f[1]) {
3241 case '0':case '1':case '2':case '3':
3242 case '4':case '5':case '6':case '7':
3243 case '8':case '9':
3244 f++;
3245 insertnr=insertnr*10+*f-'0';
3246 f++;
3247 break;
3248 default:
3249 f++;
3250 break;
3252 if (*f=='!') {
3253 f++;
3254 if (NULL!=(x=strchr(f,'!'))) {
3255 *x='\0';
3256 fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
3257 sprintf(fmtstr,"%%%s",f);
3258 f=x+1;
3259 } else {
3260 fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
3261 sprintf(fmtstr,"%%%s",f);
3262 f+=strlen(f); /*at \0*/
3265 else
3267 if(!args) break;
3268 fmtstr=HeapAlloc( GetProcessHeap(), 0, 3 );
3269 strcpy( fmtstr, "%s" );
3271 if (args) {
3272 int ret;
3273 int sz;
3274 LPSTR b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 100);
3276 argliststart=args+insertnr-1;
3278 /* CMF - This makes a BIG assumption about va_list */
3279 while ((ret = vsnprintf(b, sz, fmtstr, (va_list) argliststart)) < 0 || ret >= sz) {
3280 LPSTR new_b;
3281 sz = (ret == -1 ? sz + 100 : ret + 1);
3282 new_b = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, b, sz);
3283 if (!new_b) break;
3284 b = new_b;
3286 for (x=b; *x; x++) ADD_TO_T(*x);
3287 HeapFree(GetProcessHeap(), 0, b);
3288 } else {
3289 /* NULL args - copy formatstr
3290 * (probably wrong)
3292 while ((lastf<f)&&(*lastf)) {
3293 ADD_TO_T(*lastf++);
3296 HeapFree(GetProcessHeap(),0,fmtstr);
3297 break;
3298 case '0': /* Just stop processing format string */
3299 eos = TRUE;
3300 f++;
3301 break;
3302 case 'n': /* 16 bit version just outputs 'n' */
3303 default:
3304 ADD_TO_T(*f++);
3305 break;
3307 } else { /* '\n' or '\r' gets mapped to "\r\n" */
3308 if(*f == '\n' || *f == '\r') {
3309 if (width == 0) {
3310 ADD_TO_T('\r');
3311 ADD_TO_T('\n');
3312 if(*f++ == '\r' && *f == '\n')
3313 f++;
3315 } else {
3316 ADD_TO_T(*f++);
3320 *t='\0';
3322 talloced = strlen(target)+1;
3323 TRACE("-- %s\n",debugstr_a(target));
3324 if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
3325 /* nSize is the MINIMUM size */
3326 HLOCAL16 h = LocalAlloc16(LPTR,talloced);
3327 SEGPTR ptr = LocalLock16(h);
3328 allocstring = MapSL( ptr );
3329 memcpy( allocstring,target,talloced);
3330 LocalUnlock16( h );
3331 *((HLOCAL16*)lpBuffer) = h;
3332 } else
3333 lstrcpynA(lpBuffer,target,nSize);
3334 HeapFree(GetProcessHeap(),0,target);
3335 HeapFree(GetProcessHeap(),0,from);
3336 return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
3337 strlen(allocstring):
3338 strlen(lpBuffer);
3340 #undef ADD_TO_T
3343 /**********************************************************************
3344 * DestroyIcon32 (USER.610)
3346 * This routine is actually exported from Win95 USER under the name
3347 * DestroyIcon32 ... The behaviour implemented here should mimic
3348 * the Win95 one exactly, especially the return values, which
3349 * depend on the setting of various flags.
3351 WORD WINAPI DestroyIcon32( HGLOBAL16 handle, UINT16 flags )
3353 WORD retv;
3355 /* Check whether destroying active cursor */
3357 if (GetCursor16() == handle)
3359 WARN("Destroying active cursor!\n" );
3360 return FALSE;
3363 /* Try shared cursor/icon first */
3365 if (!(flags & CID_NONSHARED))
3367 INT count = release_shared_icon( handle );
3368 if (count != -1)
3369 return (flags & CID_WIN32) ? TRUE : (count == 0);
3372 /* Now assume non-shared cursor/icon */
3374 retv = free_icon_handle( handle );
3375 return (flags & CID_RESOURCE)? retv : TRUE;
3379 /***********************************************************************
3380 * ChangeDisplaySettings (USER.620)
3382 LONG WINAPI ChangeDisplaySettings16( LPDEVMODEA devmode, DWORD flags )
3384 return ChangeDisplaySettingsA( devmode, flags );
3388 /***********************************************************************
3389 * EnumDisplaySettings (USER.621)
3391 BOOL16 WINAPI EnumDisplaySettings16( LPCSTR name, DWORD n, LPDEVMODEA devmode )
3393 return EnumDisplaySettingsA( name, n, devmode );
3396 /**********************************************************************
3397 * DrawFrameControl (USER.656)
3399 BOOL16 WINAPI DrawFrameControl16( HDC16 hdc, LPRECT16 rc, UINT16 uType, UINT16 uState )
3401 RECT rect32;
3402 BOOL ret;
3404 rect32.left = rc->left;
3405 rect32.top = rc->top;
3406 rect32.right = rc->right;
3407 rect32.bottom = rc->bottom;
3408 ret = DrawFrameControl( HDC_32(hdc), &rect32, uType, uState );
3409 rc->left = rect32.left;
3410 rc->top = rect32.top;
3411 rc->right = rect32.right;
3412 rc->bottom = rect32.bottom;
3413 return ret;
3416 /**********************************************************************
3417 * DrawEdge (USER.659)
3419 BOOL16 WINAPI DrawEdge16( HDC16 hdc, LPRECT16 rc, UINT16 edge, UINT16 flags )
3421 RECT rect32;
3422 BOOL ret;
3424 rect32.left = rc->left;
3425 rect32.top = rc->top;
3426 rect32.right = rc->right;
3427 rect32.bottom = rc->bottom;
3428 ret = DrawEdge( HDC_32(hdc), &rect32, edge, flags );
3429 rc->left = rect32.left;
3430 rc->top = rect32.top;
3431 rc->right = rect32.right;
3432 rc->bottom = rect32.bottom;
3433 return ret;
3436 /**********************************************************************
3437 * CheckMenuRadioItem (USER.666)
3439 BOOL16 WINAPI CheckMenuRadioItem16(HMENU16 hMenu, UINT16 first, UINT16 last,
3440 UINT16 check, BOOL16 bypos)
3442 return CheckMenuRadioItem( HMENU_32(hMenu), first, last, check, bypos );