usp10: Handle Ligature Substitution Subtable from GSUB.
[wine/testsucceed.git] / dlls / user.exe16 / user.c
blobba90db461099fcd3536e49668119f7da2bbf8283
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 struct gray_string_info
65 GRAYSTRINGPROC16 proc;
66 LPARAM param;
67 char str[1];
70 /* callback for 16-bit gray string proc with opaque pointer */
71 static BOOL CALLBACK gray_string_callback( HDC hdc, LPARAM param, INT len )
73 const struct gray_string_info *info = (struct gray_string_info *)param;
74 WORD args[4];
75 DWORD ret;
77 args[3] = HDC_16(hdc);
78 args[2] = HIWORD(info->param);
79 args[1] = LOWORD(info->param);
80 args[0] = len;
81 WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
82 return LOWORD(ret);
85 /* callback for 16-bit gray string proc with string pointer */
86 static BOOL CALLBACK gray_string_callback_ptr( HDC hdc, LPARAM param, INT len )
88 const struct gray_string_info *info;
89 char *str = (char *)param;
91 info = (struct gray_string_info *)(str - offsetof( struct gray_string_info, str ));
92 return gray_string_callback( hdc, (LPARAM)info, len );
95 struct draw_state_info
97 DRAWSTATEPROC16 proc;
98 LPARAM param;
101 /* callback for 16-bit DrawState functions */
102 static BOOL CALLBACK draw_state_callback( HDC hdc, LPARAM lparam, WPARAM wparam, int cx, int cy )
104 const struct draw_state_info *info = (struct draw_state_info *)lparam;
105 WORD args[6];
106 DWORD ret;
108 args[5] = HDC_16(hdc);
109 args[4] = HIWORD(info->param);
110 args[3] = LOWORD(info->param);
111 args[2] = wparam;
112 args[1] = cx;
113 args[0] = cy;
114 WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
115 return LOWORD(ret);
118 /* This function is a copy of the one in objects/font.c */
119 static void logfont_32_to_16( const LOGFONTA* font32, LPLOGFONT16 font16 )
121 font16->lfHeight = font32->lfHeight;
122 font16->lfWidth = font32->lfWidth;
123 font16->lfEscapement = font32->lfEscapement;
124 font16->lfOrientation = font32->lfOrientation;
125 font16->lfWeight = font32->lfWeight;
126 font16->lfItalic = font32->lfItalic;
127 font16->lfUnderline = font32->lfUnderline;
128 font16->lfStrikeOut = font32->lfStrikeOut;
129 font16->lfCharSet = font32->lfCharSet;
130 font16->lfOutPrecision = font32->lfOutPrecision;
131 font16->lfClipPrecision = font32->lfClipPrecision;
132 font16->lfQuality = font32->lfQuality;
133 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
134 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
137 static int get_bitmap_width_bytes( int width, int bpp )
139 switch(bpp)
141 case 1:
142 return 2 * ((width+15) / 16);
143 case 4:
144 return 2 * ((width+3) / 4);
145 case 24:
146 width *= 3;
147 /* fall through */
148 case 8:
149 return width + (width & 1);
150 case 16:
151 case 15:
152 return width * 2;
153 case 32:
154 return width * 4;
155 default:
156 WARN("Unknown depth %d, please report.\n", bpp );
158 return -1;
161 /***********************************************************************
162 * Helper for wsprintf16
165 #define WPRINTF_LEFTALIGN 0x0001 /* Align output on the left ('-' prefix) */
166 #define WPRINTF_PREFIX_HEX 0x0002 /* Prefix hex with 0x ('#' prefix) */
167 #define WPRINTF_ZEROPAD 0x0004 /* Pad with zeros ('0' prefix) */
168 #define WPRINTF_LONG 0x0008 /* Long arg ('l' prefix) */
169 #define WPRINTF_SHORT 0x0010 /* Short arg ('h' prefix) */
170 #define WPRINTF_UPPER_HEX 0x0020 /* Upper-case hex ('X' specifier) */
172 typedef enum
174 WPR_UNKNOWN,
175 WPR_CHAR,
176 WPR_STRING,
177 WPR_SIGNED,
178 WPR_UNSIGNED,
179 WPR_HEXA
180 } WPRINTF_TYPE;
182 typedef struct
184 UINT flags;
185 UINT width;
186 UINT precision;
187 WPRINTF_TYPE type;
188 } WPRINTF_FORMAT;
190 static INT parse_format( LPCSTR format, WPRINTF_FORMAT *res )
192 LPCSTR p = format;
194 res->flags = 0;
195 res->width = 0;
196 res->precision = 0;
197 if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; }
198 if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; }
199 if (*p == '0') { res->flags |= WPRINTF_ZEROPAD; p++; }
200 while ((*p >= '0') && (*p <= '9')) /* width field */
202 res->width = res->width * 10 + *p - '0';
203 p++;
205 if (*p == '.') /* precision field */
207 p++;
208 while ((*p >= '0') && (*p <= '9'))
210 res->precision = res->precision * 10 + *p - '0';
211 p++;
214 if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; }
215 else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; }
216 switch(*p)
218 case 'c':
219 case 'C': /* no Unicode in Win16 */
220 res->type = WPR_CHAR;
221 break;
222 case 's':
223 case 'S':
224 res->type = WPR_STRING;
225 break;
226 case 'd':
227 case 'i':
228 res->type = WPR_SIGNED;
229 break;
230 case 'u':
231 res->type = WPR_UNSIGNED;
232 break;
233 case 'p':
234 res->width = 8;
235 res->flags |= WPRINTF_ZEROPAD;
236 /* fall through */
237 case 'X':
238 res->flags |= WPRINTF_UPPER_HEX;
239 /* fall through */
240 case 'x':
241 res->type = WPR_HEXA;
242 break;
243 default: /* unknown format char */
244 res->type = WPR_UNKNOWN;
245 p--; /* print format as normal char */
246 break;
248 return (INT)(p - format) + 1;
252 /**********************************************************************
253 * Management of the 16-bit cursors and icons
256 struct cache_entry
258 struct list entry;
259 HINSTANCE16 inst;
260 HRSRC16 rsrc;
261 HRSRC16 group;
262 HICON16 icon;
263 INT count;
266 static struct list icon_cache = LIST_INIT( icon_cache );
268 static const WORD ICON_HOTSPOT = 0x4242;
270 static HICON16 alloc_icon_handle( unsigned int size )
272 HGLOBAL16 handle = GlobalAlloc16( GMEM_MOVEABLE, size + sizeof(ULONG_PTR) );
273 char *ptr = GlobalLock16( handle );
274 memset( ptr + size, 0, sizeof(ULONG_PTR) );
275 GlobalUnlock16( handle );
276 FarSetOwner16( handle, 0 );
277 return handle;
280 static CURSORICONINFO *get_icon_ptr( HICON16 handle )
282 return GlobalLock16( handle );
285 static void release_icon_ptr( HICON16 handle, CURSORICONINFO *ptr )
287 GlobalUnlock16( handle );
290 static HICON store_icon_32( HICON16 icon16, HICON icon )
292 HICON ret = 0;
293 CURSORICONINFO *ptr = get_icon_ptr( icon16 );
295 if (ptr)
297 unsigned int and_size = ptr->nHeight * get_bitmap_width_bytes( ptr->nWidth, 1 );
298 unsigned int xor_size = ptr->nHeight * get_bitmap_width_bytes( ptr->nWidth, ptr->bBitsPerPixel );
299 if (GlobalSize16( icon16 ) >= sizeof(*ptr) + sizeof(ULONG_PTR) + and_size + xor_size )
301 memcpy( &ret, (char *)(ptr + 1) + and_size + xor_size, sizeof(ret) );
302 memcpy( (char *)(ptr + 1) + and_size + xor_size, &icon, sizeof(icon) );
303 wow_handlers32.set_icon_param( icon, icon16 );
305 release_icon_ptr( icon16, ptr );
307 return ret;
310 static int free_icon_handle( HICON16 handle )
312 HICON icon32;
314 if ((icon32 = store_icon_32( handle, 0 ))) DestroyIcon( icon32 );
315 return GlobalFree16( handle );
318 /* retrieve the 32-bit counterpart of a 16-bit icon, creating it if needed */
319 HICON get_icon_32( HICON16 icon16 )
321 HICON ret = 0;
322 CURSORICONINFO *ptr = get_icon_ptr( icon16 );
324 if (ptr)
326 unsigned int and_size = ptr->nHeight * get_bitmap_width_bytes( ptr->nWidth, 1 );
327 unsigned int xor_size = ptr->nHeight * get_bitmap_width_bytes( ptr->nWidth, ptr->bBitsPerPixel );
328 if (GlobalSize16( icon16 ) >= sizeof(*ptr) + sizeof(ULONG_PTR) + xor_size + and_size )
330 memcpy( &ret, (char *)(ptr + 1) + xor_size + and_size, sizeof(ret) );
331 if (!ret)
333 ICONINFO iinfo;
335 iinfo.fIcon = (ptr->ptHotSpot.x == ICON_HOTSPOT) && (ptr->ptHotSpot.y == ICON_HOTSPOT);
336 iinfo.xHotspot = ptr->ptHotSpot.x;
337 iinfo.yHotspot = ptr->ptHotSpot.y;
338 iinfo.hbmMask = CreateBitmap( ptr->nWidth, ptr->nHeight, 1, 1, ptr + 1 );
339 iinfo.hbmColor = CreateBitmap( ptr->nWidth, ptr->nHeight, ptr->bPlanes, ptr->bBitsPerPixel,
340 (char *)(ptr + 1) + and_size );
341 ret = CreateIconIndirect( &iinfo );
342 DeleteObject( iinfo.hbmMask );
343 DeleteObject( iinfo.hbmColor );
344 memcpy( (char *)(ptr + 1) + xor_size + and_size, &ret, sizeof(ret) );
345 wow_handlers32.set_icon_param( ret, icon16 );
348 release_icon_ptr( icon16, ptr );
350 return ret;
353 /* retrieve the 16-bit counterpart of a 32-bit icon, creating it if needed */
354 HICON16 get_icon_16( HICON icon )
356 HICON16 ret = wow_handlers32.get_icon_param( icon );
358 if (!ret)
360 ICONINFO info;
361 BITMAP bm;
362 UINT and_size, xor_size;
363 void *xor_bits = NULL, *and_bits;
364 CURSORICONINFO cinfo;
366 if (!(GetIconInfo( icon, &info ))) return 0;
367 GetObjectW( info.hbmMask, sizeof(bm), &bm );
368 and_size = bm.bmHeight * bm.bmWidthBytes;
369 if (!(and_bits = HeapAlloc( GetProcessHeap(), 0, and_size ))) goto done;
370 GetBitmapBits( info.hbmMask, and_size, and_bits );
371 if (info.hbmColor)
373 GetObjectW( info.hbmColor, sizeof(bm), &bm );
374 xor_size = bm.bmHeight * bm.bmWidthBytes;
375 if (!(xor_bits = HeapAlloc( GetProcessHeap(), 0, xor_size ))) goto done;
376 GetBitmapBits( info.hbmColor, xor_size, xor_bits );
378 else
380 bm.bmHeight /= 2;
381 xor_bits = (char *)and_bits + and_size / 2;
383 if (!info.fIcon)
385 cinfo.ptHotSpot.x = info.xHotspot;
386 cinfo.ptHotSpot.y = info.yHotspot;
388 else cinfo.ptHotSpot.x = cinfo.ptHotSpot.y = ICON_HOTSPOT;
390 cinfo.nWidth = bm.bmWidth;
391 cinfo.nHeight = bm.bmHeight;
392 cinfo.nWidthBytes = bm.bmWidthBytes;
393 cinfo.bPlanes = bm.bmPlanes;
394 cinfo.bBitsPerPixel = bm.bmBitsPixel;
396 if ((ret = CreateCursorIconIndirect16( 0, &cinfo, and_bits, xor_bits )))
397 store_icon_32( ret, icon );
399 done:
400 if (info.hbmColor)
402 HeapFree( GetProcessHeap(), 0, xor_bits );
403 DeleteObject( info.hbmColor );
405 HeapFree( GetProcessHeap(), 0, and_bits );
406 DeleteObject( info.hbmMask );
408 return ret;
411 static void add_shared_icon( HINSTANCE16 inst, HRSRC16 rsrc, HRSRC16 group, HICON16 icon )
413 struct cache_entry *cache = HeapAlloc( GetProcessHeap(), 0, sizeof(*cache) );
415 if (!cache) return;
416 cache->inst = inst;
417 cache->rsrc = rsrc;
418 cache->group = group;
419 cache->icon = icon;
420 cache->count = 1;
421 list_add_tail( &icon_cache, &cache->entry );
424 static HICON16 find_shared_icon( HINSTANCE16 inst, HRSRC16 rsrc )
426 struct cache_entry *cache;
428 LIST_FOR_EACH_ENTRY( cache, &icon_cache, struct cache_entry, entry )
430 if (cache->inst != inst || cache->rsrc != rsrc) continue;
431 cache->count++;
432 return cache->icon;
434 return 0;
437 static int release_shared_icon( HICON16 icon )
439 struct cache_entry *cache;
441 LIST_FOR_EACH_ENTRY( cache, &icon_cache, struct cache_entry, entry )
443 if (cache->icon != icon) continue;
444 if (!cache->count) return 0;
445 return --cache->count;
447 return -1;
450 static void free_module_icons( HINSTANCE16 inst )
452 struct cache_entry *cache, *next;
454 LIST_FOR_EACH_ENTRY_SAFE( cache, next, &icon_cache, struct cache_entry, entry )
456 if (cache->inst != inst) continue;
457 list_remove( &cache->entry );
458 free_icon_handle( cache->icon );
459 HeapFree( GetProcessHeap(), 0, cache );
463 /**********************************************************************
464 * Management of the 16-bit clipboard formats
467 struct clipboard_format
469 struct list entry;
470 UINT format;
471 HANDLE16 data;
474 static struct list clipboard_formats = LIST_INIT( clipboard_formats );
476 static void set_clipboard_format( UINT format, HANDLE16 data )
478 struct clipboard_format *fmt;
480 /* replace it if it exists already */
481 LIST_FOR_EACH_ENTRY( fmt, &clipboard_formats, struct clipboard_format, entry )
483 if (fmt->format != format) continue;
484 GlobalFree16( fmt->data );
485 fmt->data = data;
486 return;
489 if ((fmt = HeapAlloc( GetProcessHeap(), 0, sizeof(*fmt) )))
491 fmt->format = format;
492 fmt->data = data;
493 list_add_tail( &clipboard_formats, &fmt->entry );
497 static void free_clipboard_formats(void)
499 struct list *head;
501 while ((head = list_head( &clipboard_formats )))
503 struct clipboard_format *fmt = LIST_ENTRY( head, struct clipboard_format, entry );
504 list_remove( &fmt->entry );
505 GlobalFree16( fmt->data );
506 HeapFree( GetProcessHeap(), 0, fmt );
511 /**********************************************************************
512 * InitApp (USER.5)
514 INT16 WINAPI InitApp16( HINSTANCE16 hInstance )
516 /* Create task message queue */
517 return (InitThreadInput16( 0, 0 ) != 0);
521 /***********************************************************************
522 * ExitWindows (USER.7)
524 BOOL16 WINAPI ExitWindows16( DWORD dwReturnCode, UINT16 wReserved )
526 return ExitWindowsEx( EWX_LOGOFF, 0xffffffff );
530 /***********************************************************************
531 * GetTimerResolution (USER.14)
533 LONG WINAPI GetTimerResolution16(void)
535 return (1000);
539 /***********************************************************************
540 * ClipCursor (USER.16)
542 BOOL16 WINAPI ClipCursor16( const RECT16 *rect )
544 RECT rect32;
546 if (!rect) return ClipCursor( NULL );
547 rect32.left = rect->left;
548 rect32.top = rect->top;
549 rect32.right = rect->right;
550 rect32.bottom = rect->bottom;
551 return ClipCursor( &rect32 );
555 /***********************************************************************
556 * GetCursorPos (USER.17)
558 BOOL16 WINAPI GetCursorPos16( POINT16 *pt )
560 POINT pos;
561 if (!pt) return 0;
562 GetCursorPos(&pos);
563 pt->x = pos.x;
564 pt->y = pos.y;
565 return 1;
569 /*******************************************************************
570 * AnyPopup (USER.52)
572 BOOL16 WINAPI AnyPopup16(void)
574 return AnyPopup();
578 /***********************************************************************
579 * SetCursor (USER.69)
581 HCURSOR16 WINAPI SetCursor16(HCURSOR16 hCursor)
583 return get_icon_16( SetCursor( get_icon_32(hCursor) ));
587 /***********************************************************************
588 * SetCursorPos (USER.70)
590 void WINAPI SetCursorPos16( INT16 x, INT16 y )
592 SetCursorPos( x, y );
596 /***********************************************************************
597 * ShowCursor (USER.71)
599 INT16 WINAPI ShowCursor16(BOOL16 bShow)
601 return ShowCursor(bShow);
605 /***********************************************************************
606 * SetRect (USER.72)
608 void WINAPI SetRect16( LPRECT16 rect, INT16 left, INT16 top, INT16 right, INT16 bottom )
610 rect->left = left;
611 rect->right = right;
612 rect->top = top;
613 rect->bottom = bottom;
617 /***********************************************************************
618 * SetRectEmpty (USER.73)
620 void WINAPI SetRectEmpty16( LPRECT16 rect )
622 rect->left = rect->right = rect->top = rect->bottom = 0;
626 /***********************************************************************
627 * CopyRect (USER.74)
629 BOOL16 WINAPI CopyRect16( RECT16 *dest, const RECT16 *src )
631 *dest = *src;
632 return TRUE;
636 /***********************************************************************
637 * IsRectEmpty (USER.75)
639 * Bug compat: Windows checks for 0 or negative width/height.
641 BOOL16 WINAPI IsRectEmpty16( const RECT16 *rect )
643 return ((rect->left >= rect->right) || (rect->top >= rect->bottom));
647 /***********************************************************************
648 * PtInRect (USER.76)
650 BOOL16 WINAPI PtInRect16( const RECT16 *rect, POINT16 pt )
652 return ((pt.x >= rect->left) && (pt.x < rect->right) &&
653 (pt.y >= rect->top) && (pt.y < rect->bottom));
657 /***********************************************************************
658 * OffsetRect (USER.77)
660 void WINAPI OffsetRect16( LPRECT16 rect, INT16 x, INT16 y )
662 rect->left += x;
663 rect->right += x;
664 rect->top += y;
665 rect->bottom += y;
669 /***********************************************************************
670 * InflateRect (USER.78)
672 void WINAPI InflateRect16( LPRECT16 rect, INT16 x, INT16 y )
674 rect->left -= x;
675 rect->top -= y;
676 rect->right += x;
677 rect->bottom += y;
681 /***********************************************************************
682 * IntersectRect (USER.79)
684 BOOL16 WINAPI IntersectRect16( LPRECT16 dest, const RECT16 *src1,
685 const RECT16 *src2 )
687 if (IsRectEmpty16(src1) || IsRectEmpty16(src2) ||
688 (src1->left >= src2->right) || (src2->left >= src1->right) ||
689 (src1->top >= src2->bottom) || (src2->top >= src1->bottom))
691 SetRectEmpty16( dest );
692 return FALSE;
694 dest->left = max( src1->left, src2->left );
695 dest->right = min( src1->right, src2->right );
696 dest->top = max( src1->top, src2->top );
697 dest->bottom = min( src1->bottom, src2->bottom );
698 return TRUE;
702 /***********************************************************************
703 * UnionRect (USER.80)
705 BOOL16 WINAPI UnionRect16( LPRECT16 dest, const RECT16 *src1,
706 const RECT16 *src2 )
708 if (IsRectEmpty16(src1))
710 if (IsRectEmpty16(src2))
712 SetRectEmpty16( dest );
713 return FALSE;
715 else *dest = *src2;
717 else
719 if (IsRectEmpty16(src2)) *dest = *src1;
720 else
722 dest->left = min( src1->left, src2->left );
723 dest->right = max( src1->right, src2->right );
724 dest->top = min( src1->top, src2->top );
725 dest->bottom = max( src1->bottom, src2->bottom );
728 return TRUE;
732 /***********************************************************************
733 * FillRect (USER.81)
734 * NOTE
735 * The Win16 variant doesn't support special color brushes like
736 * the Win32 one, despite the fact that Win16, as well as Win32,
737 * supports special background brushes for a window class.
739 INT16 WINAPI FillRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
741 HBRUSH prevBrush;
743 /* coordinates are logical so we cannot fast-check 'rect',
744 * it will be done later in the PatBlt().
747 if (!(prevBrush = SelectObject( HDC_32(hdc), HBRUSH_32(hbrush) ))) return 0;
748 PatBlt( HDC_32(hdc), rect->left, rect->top,
749 rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
750 SelectObject( HDC_32(hdc), prevBrush );
751 return 1;
755 /***********************************************************************
756 * InvertRect (USER.82)
758 void WINAPI InvertRect16( HDC16 hdc, const RECT16 *rect )
760 PatBlt( HDC_32(hdc), rect->left, rect->top,
761 rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
765 /***********************************************************************
766 * FrameRect (USER.83)
768 INT16 WINAPI FrameRect16( HDC16 hdc, const RECT16 *rect16, HBRUSH16 hbrush )
770 RECT rect;
772 rect.left = rect16->left;
773 rect.top = rect16->top;
774 rect.right = rect16->right;
775 rect.bottom = rect16->bottom;
776 return FrameRect( HDC_32(hdc), &rect, HBRUSH_32(hbrush) );
780 /***********************************************************************
781 * DrawIcon (USER.84)
783 BOOL16 WINAPI DrawIcon16(HDC16 hdc, INT16 x, INT16 y, HICON16 hIcon)
785 return DrawIcon(HDC_32(hdc), x, y, get_icon_32(hIcon) );
789 /***********************************************************************
790 * DrawText (USER.85)
792 INT16 WINAPI DrawText16( HDC16 hdc, LPCSTR str, INT16 count, LPRECT16 rect, UINT16 flags )
794 INT16 ret;
796 if (rect)
798 RECT rect32;
800 rect32.left = rect->left;
801 rect32.top = rect->top;
802 rect32.right = rect->right;
803 rect32.bottom = rect->bottom;
804 ret = DrawTextA( HDC_32(hdc), str, count, &rect32, flags );
805 rect->left = rect32.left;
806 rect->top = rect32.top;
807 rect->right = rect32.right;
808 rect->bottom = rect32.bottom;
810 else ret = DrawTextA( HDC_32(hdc), str, count, NULL, flags);
811 return ret;
815 /***********************************************************************
816 * IconSize (USER.86)
818 * See "Undocumented Windows". Used by W2.0 paint.exe.
820 DWORD WINAPI IconSize16(void)
822 return MAKELONG(GetSystemMetrics(SM_CYICON), GetSystemMetrics(SM_CXICON));
826 /***********************************************************************
827 * AdjustWindowRect (USER.102)
829 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
831 return AdjustWindowRectEx16( rect, style, menu, 0 );
835 /***********************************************************************
836 * MessageBeep (USER.104)
838 void WINAPI MessageBeep16( UINT16 i )
840 MessageBeep( i );
844 /**************************************************************************
845 * CloseClipboard (USER.138)
847 BOOL16 WINAPI CloseClipboard16(void)
849 BOOL ret = CloseClipboard();
850 if (ret) free_clipboard_formats();
851 return ret;
855 /**************************************************************************
856 * EmptyClipboard (USER.139)
858 BOOL16 WINAPI EmptyClipboard16(void)
860 BOOL ret = EmptyClipboard();
861 if (ret) free_clipboard_formats();
862 return ret;
866 /**************************************************************************
867 * SetClipboardData (USER.141)
869 HANDLE16 WINAPI SetClipboardData16( UINT16 format, HANDLE16 data16 )
871 HANDLE data32 = 0;
873 switch (format)
875 case CF_BITMAP:
876 case CF_PALETTE:
877 data32 = HGDIOBJ_32( data16 );
878 break;
880 case CF_METAFILEPICT:
882 METAHEADER *header;
883 METAFILEPICT *pict32;
884 METAFILEPICT16 *pict16 = GlobalLock16( data16 );
886 if (pict16)
888 if (!(data32 = GlobalAlloc( GMEM_MOVEABLE, sizeof(*pict32) ))) return 0;
889 pict32 = GlobalLock( data32 );
890 pict32->mm = pict16->mm;
891 pict32->xExt = pict16->xExt;
892 pict32->yExt = pict16->yExt;
893 header = GlobalLock16( pict16->hMF );
894 pict32->hMF = SetMetaFileBitsEx( header->mtSize * 2, (BYTE *)header );
895 GlobalUnlock16( pict16->hMF );
896 GlobalUnlock( data32 );
898 set_clipboard_format( format, data16 );
899 break;
902 case CF_ENHMETAFILE:
903 FIXME( "enhmetafile not supported in 16-bit\n" );
904 return 0;
906 default:
907 if (format >= CF_GDIOBJFIRST && format <= CF_GDIOBJLAST)
908 data32 = HGDIOBJ_32( data16 );
909 else if (format >= CF_PRIVATEFIRST && format <= CF_PRIVATELAST)
910 data32 = HANDLE_32( data16 );
911 else
913 UINT size = GlobalSize16( data16 );
914 void *ptr32, *ptr16 = GlobalLock16( data16 );
915 if (ptr16)
917 if (!(data32 = GlobalAlloc( GMEM_MOVEABLE, size ))) return 0;
918 ptr32 = GlobalLock( data32 );
919 memcpy( ptr32, ptr16, size );
920 GlobalUnlock( data32 );
922 set_clipboard_format( format, data16 );
924 break;
927 if (!SetClipboardData( format, data32 )) return 0;
928 return data16;
932 /**************************************************************************
933 * GetClipboardData (USER.142)
935 HANDLE16 WINAPI GetClipboardData16( UINT16 format )
937 HANDLE data32 = GetClipboardData( format );
938 HANDLE16 data16 = 0;
939 UINT size;
940 void *ptr;
942 if (!data32) return 0;
944 switch (format)
946 case CF_BITMAP:
947 case CF_PALETTE:
948 data16 = HGDIOBJ_16( data32 );
949 break;
951 case CF_METAFILEPICT:
953 METAFILEPICT16 *pict16;
954 METAFILEPICT *pict32 = GlobalLock( data32 );
956 if (pict32)
958 if (!(data16 = GlobalAlloc16( GMEM_MOVEABLE, sizeof(*pict16) ))) return 0;
959 pict16 = GlobalLock16( data16 );
960 pict16->mm = pict32->mm;
961 pict16->xExt = pict32->xExt;
962 pict16->yExt = pict32->yExt;
963 size = GetMetaFileBitsEx( pict32->hMF, 0, NULL );
964 pict16->hMF = GlobalAlloc16( GMEM_MOVEABLE, size );
965 ptr = GlobalLock16( pict16->hMF );
966 GetMetaFileBitsEx( pict32->hMF, size, ptr );
967 GlobalUnlock16( pict16->hMF );
968 GlobalUnlock16( data16 );
969 set_clipboard_format( format, data16 );
971 break;
974 case CF_ENHMETAFILE:
975 FIXME( "enhmetafile not supported in 16-bit\n" );
976 return 0;
978 default:
979 if (format >= CF_GDIOBJFIRST && format <= CF_GDIOBJLAST)
980 data16 = HGDIOBJ_16( data32 );
981 else if (format >= CF_PRIVATEFIRST && format <= CF_PRIVATELAST)
982 data16 = HANDLE_16( data32 );
983 else
985 void *ptr16, *ptr32 = GlobalLock( data32 );
986 if (ptr32)
988 size = GlobalSize( data32 );
989 if (!(data16 = GlobalAlloc16( GMEM_MOVEABLE, size ))) return 0;
990 ptr16 = GlobalLock16( data16 );
991 memcpy( ptr16, ptr32, size );
992 GlobalUnlock16( data16 );
993 set_clipboard_format( format, data16 );
996 break;
998 return data16;
1002 /**************************************************************************
1003 * CountClipboardFormats (USER.143)
1005 INT16 WINAPI CountClipboardFormats16(void)
1007 return CountClipboardFormats();
1011 /**************************************************************************
1012 * EnumClipboardFormats (USER.144)
1014 UINT16 WINAPI EnumClipboardFormats16( UINT16 id )
1016 return EnumClipboardFormats( id );
1020 /**************************************************************************
1021 * RegisterClipboardFormat (USER.145)
1023 UINT16 WINAPI RegisterClipboardFormat16( LPCSTR name )
1025 return RegisterClipboardFormatA( name );
1029 /**************************************************************************
1030 * GetClipboardFormatName (USER.146)
1032 INT16 WINAPI GetClipboardFormatName16( UINT16 id, LPSTR buffer, INT16 maxlen )
1034 return GetClipboardFormatNameA( id, buffer, maxlen );
1038 /**********************************************************************
1039 * LoadMenu (USER.150)
1041 HMENU16 WINAPI LoadMenu16( HINSTANCE16 instance, LPCSTR name )
1043 HRSRC16 hRsrc;
1044 HGLOBAL16 handle;
1045 HMENU16 hMenu;
1047 if (HIWORD(name) && name[0] == '#') name = ULongToPtr(atoi( name + 1 ));
1048 if (!name) return 0;
1050 instance = GetExePtr( instance );
1051 if (!(hRsrc = FindResource16( instance, name, (LPSTR)RT_MENU ))) return 0;
1052 if (!(handle = LoadResource16( instance, hRsrc ))) return 0;
1053 hMenu = LoadMenuIndirect16(LockResource16(handle));
1054 FreeResource16( handle );
1055 return hMenu;
1059 /**********************************************************************
1060 * CreateMenu (USER.151)
1062 HMENU16 WINAPI CreateMenu16(void)
1064 return HMENU_16( CreateMenu() );
1068 /**********************************************************************
1069 * DestroyMenu (USER.152)
1071 BOOL16 WINAPI DestroyMenu16( HMENU16 hMenu )
1073 return DestroyMenu( HMENU_32(hMenu) );
1077 /*******************************************************************
1078 * ChangeMenu (USER.153)
1080 BOOL16 WINAPI ChangeMenu16( HMENU16 hMenu, UINT16 pos, SEGPTR data,
1081 UINT16 id, UINT16 flags )
1083 if (flags & MF_APPEND) return AppendMenu16( hMenu, flags & ~MF_APPEND, id, data );
1085 /* FIXME: Word passes the item id in 'pos' and 0 or 0xffff as id */
1086 /* for MF_DELETE. We should check the parameters for all others */
1087 /* MF_* actions also (anybody got a doc on ChangeMenu?). */
1089 if (flags & MF_DELETE) return DeleteMenu16(hMenu, pos, flags & ~MF_DELETE);
1090 if (flags & MF_CHANGE) return ModifyMenu16(hMenu, pos, flags & ~MF_CHANGE, id, data );
1091 if (flags & MF_REMOVE) return RemoveMenu16(hMenu, flags & MF_BYPOSITION ? pos : id,
1092 flags & ~MF_REMOVE );
1093 /* Default: MF_INSERT */
1094 return InsertMenu16( hMenu, pos, flags, id, data );
1098 /*******************************************************************
1099 * CheckMenuItem (USER.154)
1101 BOOL16 WINAPI CheckMenuItem16( HMENU16 hMenu, UINT16 id, UINT16 flags )
1103 return CheckMenuItem( HMENU_32(hMenu), id, flags );
1107 /**********************************************************************
1108 * EnableMenuItem (USER.155)
1110 BOOL16 WINAPI EnableMenuItem16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
1112 return EnableMenuItem( HMENU_32(hMenu), wItemID, wFlags );
1116 /**********************************************************************
1117 * GetSubMenu (USER.159)
1119 HMENU16 WINAPI GetSubMenu16( HMENU16 hMenu, INT16 nPos )
1121 return HMENU_16( GetSubMenu( HMENU_32(hMenu), nPos ) );
1125 /*******************************************************************
1126 * GetMenuString (USER.161)
1128 INT16 WINAPI GetMenuString16( HMENU16 hMenu, UINT16 wItemID,
1129 LPSTR str, INT16 nMaxSiz, UINT16 wFlags )
1131 return GetMenuStringA( HMENU_32(hMenu), wItemID, str, nMaxSiz, wFlags );
1135 /**********************************************************************
1136 * WinHelp (USER.171)
1138 BOOL16 WINAPI WinHelp16( HWND16 hWnd, LPCSTR lpHelpFile, UINT16 wCommand,
1139 DWORD dwData )
1141 BOOL ret;
1142 DWORD mutex_count;
1144 /* We might call WinExec() */
1145 ReleaseThunkLock(&mutex_count);
1147 ret = WinHelpA(WIN_Handle32(hWnd), lpHelpFile, wCommand, (DWORD)MapSL(dwData));
1149 RestoreThunkLock(mutex_count);
1150 return ret;
1154 /***********************************************************************
1155 * LoadCursor (USER.173)
1157 HCURSOR16 WINAPI LoadCursor16(HINSTANCE16 hInstance, LPCSTR name)
1159 return LoadImage16( hInstance, name, IMAGE_CURSOR, 0, 0, LR_SHARED | LR_DEFAULTSIZE );
1163 /***********************************************************************
1164 * LoadIcon (USER.174)
1166 HICON16 WINAPI LoadIcon16(HINSTANCE16 hInstance, LPCSTR name)
1168 return LoadImage16( hInstance, name, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE );
1171 /**********************************************************************
1172 * LoadBitmap (USER.175)
1174 HBITMAP16 WINAPI LoadBitmap16(HINSTANCE16 hInstance, LPCSTR name)
1176 return LoadImage16( hInstance, name, IMAGE_BITMAP, 0, 0, 0 );
1179 /**********************************************************************
1180 * LoadString (USER.176)
1182 INT16 WINAPI LoadString16( HINSTANCE16 instance, UINT16 resource_id, LPSTR buffer, INT16 buflen )
1184 HGLOBAL16 hmem;
1185 HRSRC16 hrsrc;
1186 unsigned char *p;
1187 int string_num;
1188 int ret;
1190 TRACE("inst=%04x id=%04x buff=%p len=%d\n", instance, resource_id, buffer, buflen);
1192 hrsrc = FindResource16( instance, MAKEINTRESOURCEA((resource_id>>4)+1), (LPSTR)RT_STRING );
1193 if (!hrsrc) return 0;
1194 hmem = LoadResource16( instance, hrsrc );
1195 if (!hmem) return 0;
1197 p = LockResource16(hmem);
1198 string_num = resource_id & 0x000f;
1199 while (string_num--) p += *p + 1;
1201 if (buffer == NULL) ret = *p;
1202 else
1204 ret = min(buflen - 1, *p);
1205 if (ret > 0)
1207 memcpy(buffer, p + 1, ret);
1208 buffer[ret] = '\0';
1210 else if (buflen > 1)
1212 buffer[0] = '\0';
1213 ret = 0;
1215 TRACE( "%s loaded\n", debugstr_a(buffer));
1217 FreeResource16( hmem );
1218 return ret;
1221 /**********************************************************************
1222 * LoadAccelerators (USER.177)
1224 HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, LPCSTR lpTableName)
1226 HRSRC16 hRsrc;
1227 HGLOBAL16 hMem;
1228 ACCEL16 *table16;
1229 HACCEL ret = 0;
1231 TRACE("%04x %s\n", instance, debugstr_a(lpTableName) );
1233 if (!(hRsrc = FindResource16( instance, lpTableName, (LPSTR)RT_ACCELERATOR )) ||
1234 !(hMem = LoadResource16(instance,hRsrc)))
1236 WARN("couldn't find %04x %s\n", instance, debugstr_a(lpTableName));
1237 return 0;
1239 if ((table16 = LockResource16( hMem )))
1241 DWORD i, count = SizeofResource16( instance, hRsrc ) / sizeof(*table16);
1242 ACCEL *table = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*table) );
1243 if (table)
1245 for (i = 0; i < count; i++)
1247 table[i].fVirt = table16[i].fVirt & 0x7f;
1248 table[i].key = table16[i].key;
1249 table[i].cmd = table16[i].cmd;
1251 ret = CreateAcceleratorTableA( table, count );
1252 HeapFree( GetProcessHeap(), 0, table );
1255 FreeResource16( hMem );
1256 return HACCEL_16(ret);
1259 /***********************************************************************
1260 * GetSystemMetrics (USER.179)
1262 INT16 WINAPI GetSystemMetrics16( INT16 index )
1264 return GetSystemMetrics( index );
1268 /*************************************************************************
1269 * GetSysColor (USER.180)
1271 COLORREF WINAPI GetSysColor16( INT16 index )
1273 return GetSysColor( index );
1277 /*************************************************************************
1278 * SetSysColors (USER.181)
1280 VOID WINAPI SetSysColors16( INT16 count, const INT16 *list16, const COLORREF *values )
1282 INT i, *list;
1284 if ((list = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*list) )))
1286 for (i = 0; i < count; i++) list[i] = list16[i];
1287 SetSysColors( count, list, values );
1288 HeapFree( GetProcessHeap(), 0, list );
1293 /***********************************************************************
1294 * GrayString (USER.185)
1296 BOOL16 WINAPI GrayString16( HDC16 hdc, HBRUSH16 hbr, GRAYSTRINGPROC16 gsprc,
1297 LPARAM lParam, INT16 cch, INT16 x, INT16 y,
1298 INT16 cx, INT16 cy )
1300 BOOL ret;
1302 if (!gsprc) return GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), NULL,
1303 (LPARAM)MapSL(lParam), cch, x, y, cx, cy );
1305 if (cch == -1 || (cch && cx && cy))
1307 /* lParam can be treated as an opaque pointer */
1308 struct gray_string_info info;
1310 info.proc = gsprc;
1311 info.param = lParam;
1312 ret = GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), gray_string_callback,
1313 (LPARAM)&info, cch, x, y, cx, cy );
1315 else /* here we need some string conversions */
1317 char *str16 = MapSL(lParam);
1318 struct gray_string_info *info;
1320 if (!cch) cch = strlen(str16);
1321 if (!(info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info) + cch ))) return FALSE;
1322 info->proc = gsprc;
1323 info->param = lParam;
1324 memcpy( info->str, str16, cch );
1325 ret = GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), gray_string_callback_ptr,
1326 (LPARAM)info->str, cch, x, y, cx, cy );
1327 HeapFree( GetProcessHeap(), 0, info );
1329 return ret;
1333 /***********************************************************************
1334 * SwapMouseButton (USER.186)
1336 BOOL16 WINAPI SwapMouseButton16( BOOL16 fSwap )
1338 return SwapMouseButton( fSwap );
1342 /**************************************************************************
1343 * IsClipboardFormatAvailable (USER.193)
1345 BOOL16 WINAPI IsClipboardFormatAvailable16( UINT16 wFormat )
1347 return IsClipboardFormatAvailable( wFormat );
1351 /***********************************************************************
1352 * TabbedTextOut (USER.196)
1354 LONG WINAPI TabbedTextOut16( HDC16 hdc, INT16 x, INT16 y, LPCSTR lpstr,
1355 INT16 count, INT16 nb_tabs, const INT16 *tabs16, INT16 tab_org )
1357 LONG ret;
1358 INT i, *tabs = HeapAlloc( GetProcessHeap(), 0, nb_tabs * sizeof(tabs) );
1359 if (!tabs) return 0;
1360 for (i = 0; i < nb_tabs; i++) tabs[i] = tabs16[i];
1361 ret = TabbedTextOutA( HDC_32(hdc), x, y, lpstr, count, nb_tabs, tabs, tab_org );
1362 HeapFree( GetProcessHeap(), 0, tabs );
1363 return ret;
1367 /***********************************************************************
1368 * GetTabbedTextExtent (USER.197)
1370 DWORD WINAPI GetTabbedTextExtent16( HDC16 hdc, LPCSTR lpstr, INT16 count,
1371 INT16 nb_tabs, const INT16 *tabs16 )
1373 LONG ret;
1374 INT i, *tabs = HeapAlloc( GetProcessHeap(), 0, nb_tabs * sizeof(tabs) );
1375 if (!tabs) return 0;
1376 for (i = 0; i < nb_tabs; i++) tabs[i] = tabs16[i];
1377 ret = GetTabbedTextExtentA( HDC_32(hdc), lpstr, count, nb_tabs, tabs );
1378 HeapFree( GetProcessHeap(), 0, tabs );
1379 return ret;
1383 /***********************************************************************
1384 * UserSeeUserDo (USER.216)
1386 DWORD WINAPI UserSeeUserDo16(WORD wReqType, WORD wParam1, WORD wParam2, WORD wParam3)
1388 STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
1389 HANDLE16 oldDS = stack16->ds;
1390 DWORD ret = (DWORD)-1;
1392 stack16->ds = USER_HeapSel;
1393 switch (wReqType)
1395 case USUD_LOCALALLOC:
1396 ret = LocalAlloc16(wParam1, wParam3);
1397 break;
1398 case USUD_LOCALFREE:
1399 ret = LocalFree16(wParam1);
1400 break;
1401 case USUD_LOCALCOMPACT:
1402 ret = LocalCompact16(wParam3);
1403 break;
1404 case USUD_LOCALHEAP:
1405 ret = USER_HeapSel;
1406 break;
1407 case USUD_FIRSTCLASS:
1408 FIXME("return a pointer to the first window class.\n");
1409 break;
1410 default:
1411 WARN("wReqType %04x (unknown)\n", wReqType);
1413 stack16->ds = oldDS;
1414 return ret;
1418 /***********************************************************************
1419 * LookupMenuHandle (USER.217)
1421 HMENU16 WINAPI LookupMenuHandle16( HMENU16 hmenu, INT16 id )
1423 FIXME( "%04x %04x: stub\n", hmenu, id );
1424 return hmenu;
1428 static LPCSTR parse_menu_resource( LPCSTR res, HMENU hMenu )
1430 WORD flags, id = 0;
1431 LPCSTR str;
1432 BOOL end_flag;
1436 flags = GET_WORD(res);
1437 end_flag = flags & MF_END;
1438 /* Remove MF_END because it has the same value as MF_HILITE */
1439 flags &= ~MF_END;
1440 res += sizeof(WORD);
1441 if (!(flags & MF_POPUP))
1443 id = GET_WORD(res);
1444 res += sizeof(WORD);
1446 str = res;
1447 res += strlen(str) + 1;
1448 if (flags & MF_POPUP)
1450 HMENU hSubMenu = CreatePopupMenu();
1451 if (!hSubMenu) return NULL;
1452 if (!(res = parse_menu_resource( res, hSubMenu ))) return NULL;
1453 AppendMenuA( hMenu, flags, (UINT_PTR)hSubMenu, str );
1455 else /* Not a popup */
1457 AppendMenuA( hMenu, flags, id, *str ? str : NULL );
1459 } while (!end_flag);
1460 return res;
1463 /**********************************************************************
1464 * LoadMenuIndirect (USER.220)
1466 HMENU16 WINAPI LoadMenuIndirect16( LPCVOID template )
1468 HMENU hMenu;
1469 WORD version, offset;
1470 LPCSTR p = template;
1472 TRACE("(%p)\n", template );
1473 version = GET_WORD(p);
1474 p += sizeof(WORD);
1475 if (version)
1477 WARN("version must be 0 for Win16\n" );
1478 return 0;
1480 offset = GET_WORD(p);
1481 p += sizeof(WORD) + offset;
1482 if (!(hMenu = CreateMenu())) return 0;
1483 if (!parse_menu_resource( p, hMenu ))
1485 DestroyMenu( hMenu );
1486 return 0;
1488 return HMENU_16(hMenu);
1492 /*************************************************************************
1493 * ScrollDC (USER.221)
1495 BOOL16 WINAPI ScrollDC16( HDC16 hdc, INT16 dx, INT16 dy, const RECT16 *rect,
1496 const RECT16 *cliprc, HRGN16 hrgnUpdate,
1497 LPRECT16 rcUpdate )
1499 RECT rect32, clipRect32, rcUpdate32;
1500 BOOL16 ret;
1502 if (rect)
1504 rect32.left = rect->left;
1505 rect32.top = rect->top;
1506 rect32.right = rect->right;
1507 rect32.bottom = rect->bottom;
1509 if (cliprc)
1511 clipRect32.left = cliprc->left;
1512 clipRect32.top = cliprc->top;
1513 clipRect32.right = cliprc->right;
1514 clipRect32.bottom = cliprc->bottom;
1516 ret = ScrollDC( HDC_32(hdc), dx, dy, rect ? &rect32 : NULL,
1517 cliprc ? &clipRect32 : NULL, HRGN_32(hrgnUpdate),
1518 &rcUpdate32 );
1519 if (rcUpdate)
1521 rcUpdate->left = rcUpdate32.left;
1522 rcUpdate->top = rcUpdate32.top;
1523 rcUpdate->right = rcUpdate32.right;
1524 rcUpdate->bottom = rcUpdate32.bottom;
1526 return ret;
1530 /***********************************************************************
1531 * GetSystemDebugState (USER.231)
1533 WORD WINAPI GetSystemDebugState16(void)
1535 return 0; /* FIXME */
1539 /***********************************************************************
1540 * EqualRect (USER.244)
1542 BOOL16 WINAPI EqualRect16( const RECT16* rect1, const RECT16* rect2 )
1544 return ((rect1->left == rect2->left) && (rect1->right == rect2->right) &&
1545 (rect1->top == rect2->top) && (rect1->bottom == rect2->bottom));
1549 /***********************************************************************
1550 * ExitWindowsExec (USER.246)
1552 BOOL16 WINAPI ExitWindowsExec16( LPCSTR lpszExe, LPCSTR lpszParams )
1554 TRACE("Should run the following in DOS-mode: \"%s %s\"\n",
1555 lpszExe, lpszParams);
1556 return ExitWindowsEx( EWX_LOGOFF, 0xffffffff );
1560 /***********************************************************************
1561 * GetCursor (USER.247)
1563 HCURSOR16 WINAPI GetCursor16(void)
1565 return get_icon_16( GetCursor() );
1569 /**********************************************************************
1570 * GetAsyncKeyState (USER.249)
1572 INT16 WINAPI GetAsyncKeyState16( INT16 key )
1574 return GetAsyncKeyState( key );
1578 /**********************************************************************
1579 * GetMenuState (USER.250)
1581 UINT16 WINAPI GetMenuState16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
1583 return GetMenuState( HMENU_32(hMenu), wItemID, wFlags );
1587 /**************************************************************************
1588 * SendDriverMessage (USER.251)
1590 LRESULT WINAPI SendDriverMessage16(HDRVR16 hDriver, UINT16 msg, LPARAM lParam1,
1591 LPARAM lParam2)
1593 FIXME("(%04x, %04x, %08lx, %08lx): stub\n", hDriver, msg, lParam1, lParam2);
1594 return 0;
1598 /**************************************************************************
1599 * OpenDriver (USER.252)
1601 HDRVR16 WINAPI OpenDriver16(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam2)
1603 FIXME( "(%s, %s, %08lx): stub\n", debugstr_a(lpDriverName), debugstr_a(lpSectionName), lParam2);
1604 return 0;
1608 /**************************************************************************
1609 * CloseDriver (USER.253)
1611 LRESULT WINAPI CloseDriver16(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
1613 FIXME( "(%04x, %08lx, %08lx): stub\n", hDrvr, lParam1, lParam2);
1614 return FALSE;
1618 /**************************************************************************
1619 * GetDriverModuleHandle (USER.254)
1621 HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDrvr)
1623 FIXME("(%04x): stub\n", hDrvr);
1624 return 0;
1628 /**************************************************************************
1629 * DefDriverProc (USER.255)
1631 LRESULT WINAPI DefDriverProc16(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg,
1632 LPARAM lParam1, LPARAM lParam2)
1634 FIXME( "devID=0x%08x hDrv=0x%04x wMsg=%04x lP1=0x%08lx lP2=0x%08lx: stub\n",
1635 dwDevID, hDriv, wMsg, lParam1, lParam2);
1636 return 0;
1640 /**************************************************************************
1641 * GetDriverInfo (USER.256)
1643 struct DRIVERINFOSTRUCT16;
1644 BOOL16 WINAPI GetDriverInfo16(HDRVR16 hDrvr, struct DRIVERINFOSTRUCT16 *lpDrvInfo)
1646 FIXME( "(%04x, %p): stub\n", hDrvr, lpDrvInfo);
1647 return FALSE;
1651 /**************************************************************************
1652 * GetNextDriver (USER.257)
1654 HDRVR16 WINAPI GetNextDriver16(HDRVR16 hDrvr, DWORD dwFlags)
1656 FIXME( "(%04x, %08x): stub\n", hDrvr, dwFlags);
1657 return 0;
1661 /**********************************************************************
1662 * GetMenuItemCount (USER.263)
1664 INT16 WINAPI GetMenuItemCount16( HMENU16 hMenu )
1666 return GetMenuItemCount( HMENU_32(hMenu) );
1670 /**********************************************************************
1671 * GetMenuItemID (USER.264)
1673 UINT16 WINAPI GetMenuItemID16( HMENU16 hMenu, INT16 nPos )
1675 return GetMenuItemID( HMENU_32(hMenu), nPos );
1679 /***********************************************************************
1680 * GlobalAddAtom (USER.268)
1682 ATOM WINAPI GlobalAddAtom16(LPCSTR lpString)
1684 return GlobalAddAtomA(lpString);
1687 /***********************************************************************
1688 * GlobalDeleteAtom (USER.269)
1690 ATOM WINAPI GlobalDeleteAtom16(ATOM nAtom)
1692 return GlobalDeleteAtom(nAtom);
1695 /***********************************************************************
1696 * GlobalFindAtom (USER.270)
1698 ATOM WINAPI GlobalFindAtom16(LPCSTR lpString)
1700 return GlobalFindAtomA(lpString);
1703 /***********************************************************************
1704 * GlobalGetAtomName (USER.271)
1706 UINT16 WINAPI GlobalGetAtomName16(ATOM nAtom, LPSTR lpBuffer, INT16 nSize)
1708 return GlobalGetAtomNameA(nAtom, lpBuffer, nSize);
1712 /***********************************************************************
1713 * ControlPanelInfo (USER.273)
1715 void WINAPI ControlPanelInfo16( INT16 nInfoType, WORD wData, LPSTR lpBuffer )
1717 FIXME("(%d, %04x, %p): stub.\n", nInfoType, wData, lpBuffer);
1721 /***********************************************************************
1722 * OldSetDeskPattern (USER.279)
1724 BOOL16 WINAPI SetDeskPattern16(void)
1726 return SystemParametersInfoA( SPI_SETDESKPATTERN, -1, NULL, FALSE );
1730 /***********************************************************************
1731 * GetSysColorBrush (USER.281)
1733 HBRUSH16 WINAPI GetSysColorBrush16( INT16 index )
1735 return HBRUSH_16( GetSysColorBrush(index) );
1739 /***********************************************************************
1740 * SelectPalette (USER.282)
1742 HPALETTE16 WINAPI SelectPalette16( HDC16 hdc, HPALETTE16 hpal, BOOL16 bForceBackground )
1744 return HPALETTE_16( SelectPalette( HDC_32(hdc), HPALETTE_32(hpal), bForceBackground ));
1747 /***********************************************************************
1748 * RealizePalette (USER.283)
1750 UINT16 WINAPI RealizePalette16( HDC16 hdc )
1752 return UserRealizePalette( HDC_32(hdc) );
1756 /***********************************************************************
1757 * GetFreeSystemResources (USER.284)
1759 WORD WINAPI GetFreeSystemResources16( WORD resType )
1761 STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
1762 HANDLE16 oldDS = stack16->ds;
1763 HINSTANCE16 gdi_inst;
1764 int userPercent, gdiPercent;
1766 if ((gdi_inst = LoadLibrary16( "GDI" )) < 32) return 0;
1768 switch(resType)
1770 case GFSR_USERRESOURCES:
1771 stack16->ds = USER_HeapSel;
1772 userPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1773 gdiPercent = 100;
1774 stack16->ds = oldDS;
1775 break;
1777 case GFSR_GDIRESOURCES:
1778 stack16->ds = gdi_inst;
1779 gdiPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1780 userPercent = 100;
1781 stack16->ds = oldDS;
1782 break;
1784 case GFSR_SYSTEMRESOURCES:
1785 stack16->ds = USER_HeapSel;
1786 userPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1787 stack16->ds = gdi_inst;
1788 gdiPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1789 stack16->ds = oldDS;
1790 break;
1792 default:
1793 userPercent = gdiPercent = 0;
1794 break;
1796 FreeLibrary16( gdi_inst );
1797 TRACE("<- userPercent %d, gdiPercent %d\n", userPercent, gdiPercent);
1798 return (WORD)min( userPercent, gdiPercent );
1802 /***********************************************************************
1803 * SetDeskWallPaper (USER.285)
1805 BOOL16 WINAPI SetDeskWallPaper16( LPCSTR filename )
1807 return SetDeskWallPaper( filename );
1811 /***********************************************************************
1812 * keybd_event (USER.289)
1814 void WINAPI keybd_event16( CONTEXT86 *context )
1816 DWORD dwFlags = 0;
1818 if (HIBYTE(context->Eax) & 0x80) dwFlags |= KEYEVENTF_KEYUP;
1819 if (HIBYTE(context->Ebx) & 0x01) dwFlags |= KEYEVENTF_EXTENDEDKEY;
1821 keybd_event( LOBYTE(context->Eax), LOBYTE(context->Ebx),
1822 dwFlags, MAKELONG(LOWORD(context->Esi), LOWORD(context->Edi)) );
1826 /***********************************************************************
1827 * mouse_event (USER.299)
1829 void WINAPI mouse_event16( CONTEXT86 *context )
1831 mouse_event( LOWORD(context->Eax), LOWORD(context->Ebx), LOWORD(context->Ecx),
1832 LOWORD(context->Edx), MAKELONG(context->Esi, context->Edi) );
1836 /***********************************************************************
1837 * GetClipCursor (USER.309)
1839 void WINAPI GetClipCursor16( RECT16 *rect )
1841 if (rect)
1843 RECT rect32;
1844 GetClipCursor( &rect32 );
1845 rect->left = rect32.left;
1846 rect->top = rect32.top;
1847 rect->right = rect32.right;
1848 rect->bottom = rect32.bottom;
1853 /***********************************************************************
1854 * SignalProc (USER.314)
1856 void WINAPI SignalProc16( HANDLE16 hModule, UINT16 code,
1857 UINT16 uExitFn, HINSTANCE16 hInstance, HQUEUE16 hQueue )
1859 if (code == USIG16_DLL_UNLOAD)
1861 hModule = GetExePtr(hModule);
1862 /* HOOK_FreeModuleHooks( hModule ); */
1863 free_module_classes( hModule );
1864 free_module_icons( hModule );
1869 /***********************************************************************
1870 * SetEventHook (USER.321)
1872 * Used by Turbo Debugger for Windows
1874 FARPROC16 WINAPI SetEventHook16(FARPROC16 lpfnEventHook)
1876 FIXME("(lpfnEventHook=%p): stub\n", lpfnEventHook);
1877 return 0;
1881 /**********************************************************************
1882 * EnableHardwareInput (USER.331)
1884 BOOL16 WINAPI EnableHardwareInput16(BOOL16 bEnable)
1886 FIXME("(%d) - stub\n", bEnable);
1887 return TRUE;
1891 /**********************************************************************
1892 * LoadCursorIconHandler (USER.336)
1894 * Supposed to load resources of Windows 2.x applications.
1896 HGLOBAL16 WINAPI LoadCursorIconHandler16( HGLOBAL16 hResource, HMODULE16 hModule, HRSRC16 hRsrc )
1898 FIXME("(%04x,%04x,%04x): old 2.x resources are not supported!\n", hResource, hModule, hRsrc);
1899 return 0;
1903 /***********************************************************************
1904 * GetMouseEventProc (USER.337)
1906 FARPROC16 WINAPI GetMouseEventProc16(void)
1908 HMODULE16 hmodule = GetModuleHandle16("USER");
1909 return GetProcAddress16( hmodule, "mouse_event" );
1913 /***********************************************************************
1914 * IsUserIdle (USER.333)
1916 BOOL16 WINAPI IsUserIdle16(void)
1918 if ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
1919 return FALSE;
1920 if ( GetAsyncKeyState( VK_RBUTTON ) & 0x8000 )
1921 return FALSE;
1922 if ( GetAsyncKeyState( VK_MBUTTON ) & 0x8000 )
1923 return FALSE;
1924 /* Should check for screen saver activation here ... */
1925 return TRUE;
1929 /**********************************************************************
1930 * LoadDIBIconHandler (USER.357)
1932 * RT_ICON resource loader, installed by USER_SignalProc when module
1933 * is initialized.
1935 HGLOBAL16 WINAPI LoadDIBIconHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc )
1937 /* If hResource is zero we must allocate a new memory block, if it's
1938 * non-zero but GlobalLock() returns NULL then it was discarded and
1939 * we have to recommit some memory, otherwise we just need to check
1940 * the block size. See LoadProc() in 16-bit SDK for more.
1942 FIXME( "%x %x %x: stub, not supported anymore\n", hMemObj, hModule, hRsrc );
1943 return 0;
1946 /**********************************************************************
1947 * LoadDIBCursorHandler (USER.356)
1949 * RT_CURSOR resource loader. Same as above.
1951 HGLOBAL16 WINAPI LoadDIBCursorHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc )
1953 FIXME( "%x %x %x: stub, not supported anymore\n", hMemObj, hModule, hRsrc );
1954 return 0;
1958 /**********************************************************************
1959 * IsMenu (USER.358)
1961 BOOL16 WINAPI IsMenu16( HMENU16 hmenu )
1963 return IsMenu( HMENU_32(hmenu) );
1967 /***********************************************************************
1968 * DCHook (USER.362)
1970 BOOL16 WINAPI DCHook16( HDC16 hdc, WORD code, DWORD data, LPARAM lParam )
1972 FIXME( "hDC = %x, %i: stub\n", hdc, code );
1973 return FALSE;
1977 /**********************************************************************
1978 * LookupIconIdFromDirectoryEx (USER.364)
1980 * FIXME: exact parameter sizes
1982 INT16 WINAPI LookupIconIdFromDirectoryEx16( LPBYTE dir, BOOL16 bIcon,
1983 INT16 width, INT16 height, UINT16 cFlag )
1985 return LookupIconIdFromDirectoryEx( dir, bIcon, width, height, cFlag );
1989 /***********************************************************************
1990 * CopyIcon (USER.368)
1992 HICON16 WINAPI CopyIcon16( HINSTANCE16 hInstance, HICON16 hIcon )
1994 CURSORICONINFO *info = get_icon_ptr( hIcon );
1995 void *and_bits = info + 1;
1996 void *xor_bits = (BYTE *)and_bits + info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
1997 HGLOBAL16 ret = CreateCursorIconIndirect16( hInstance, info, and_bits, xor_bits );
1998 release_icon_ptr( hIcon, info );
1999 return ret;
2003 /***********************************************************************
2004 * CopyCursor (USER.369)
2006 HCURSOR16 WINAPI CopyCursor16( HINSTANCE16 hInstance, HCURSOR16 hCursor )
2008 CURSORICONINFO *info = get_icon_ptr( hCursor );
2009 void *and_bits = info + 1;
2010 void *xor_bits = (BYTE *)and_bits + info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
2011 HGLOBAL16 ret = CreateCursorIconIndirect16( hInstance, info, and_bits, xor_bits );
2012 release_icon_ptr( hCursor, info );
2013 return ret;
2017 /***********************************************************************
2018 * SubtractRect (USER.373)
2020 BOOL16 WINAPI SubtractRect16( LPRECT16 dest, const RECT16 *src1,
2021 const RECT16 *src2 )
2023 RECT16 tmp;
2025 if (IsRectEmpty16( src1 ))
2027 SetRectEmpty16( dest );
2028 return FALSE;
2030 *dest = *src1;
2031 if (IntersectRect16( &tmp, src1, src2 ))
2033 if (EqualRect16( &tmp, dest ))
2035 SetRectEmpty16( dest );
2036 return FALSE;
2038 if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom))
2040 if (tmp.left == dest->left) dest->left = tmp.right;
2041 else if (tmp.right == dest->right) dest->right = tmp.left;
2043 else if ((tmp.left == dest->left) && (tmp.right == dest->right))
2045 if (tmp.top == dest->top) dest->top = tmp.bottom;
2046 else if (tmp.bottom == dest->bottom) dest->bottom = tmp.top;
2049 return TRUE;
2053 /**********************************************************************
2054 * DllEntryPoint (USER.374)
2056 BOOL WINAPI DllEntryPoint( DWORD reason, HINSTANCE16 inst, WORD ds,
2057 WORD heap, DWORD reserved1, WORD reserved2 )
2059 if (reason != DLL_PROCESS_ATTACH) return TRUE;
2060 if (USER_HeapSel) return TRUE; /* already called */
2062 USER_HeapSel = ds;
2063 register_wow_handlers();
2064 LoadLibrary16( "display.drv" );
2065 LoadLibrary16( "keyboard.drv" );
2066 LoadLibrary16( "mouse.drv" );
2067 return TRUE;
2071 /**********************************************************************
2072 * SetMenuContextHelpId (USER.384)
2074 BOOL16 WINAPI SetMenuContextHelpId16( HMENU16 hMenu, DWORD dwContextHelpID)
2076 return SetMenuContextHelpId( HMENU_32(hMenu), dwContextHelpID );
2080 /**********************************************************************
2081 * GetMenuContextHelpId (USER.385)
2083 DWORD WINAPI GetMenuContextHelpId16( HMENU16 hMenu )
2085 return GetMenuContextHelpId( HMENU_32(hMenu) );
2089 /***********************************************************************
2090 * LoadImage (USER.389)
2092 HANDLE16 WINAPI LoadImage16(HINSTANCE16 hinst, LPCSTR name, UINT16 type, INT16 cx, INT16 cy, UINT16 flags)
2094 HGLOBAL16 handle;
2095 HRSRC16 hRsrc, hGroupRsrc;
2097 if (!hinst || (flags & LR_LOADFROMFILE))
2099 if (type == IMAGE_BITMAP)
2100 return HBITMAP_16( LoadImageA( 0, name, type, cx, cy, flags ));
2101 else
2102 return get_icon_16( LoadImageA( 0, name, type, cx, cy, flags ));
2105 hinst = GetExePtr( hinst );
2107 if (flags & LR_DEFAULTSIZE)
2109 if (type == IMAGE_ICON)
2111 if (!cx) cx = GetSystemMetrics(SM_CXICON);
2112 if (!cy) cy = GetSystemMetrics(SM_CYICON);
2114 else if (type == IMAGE_CURSOR)
2116 if (!cx) cx = GetSystemMetrics(SM_CXCURSOR);
2117 if (!cy) cy = GetSystemMetrics(SM_CYCURSOR);
2121 switch (type)
2123 case IMAGE_BITMAP:
2125 HBITMAP ret = 0;
2126 char *ptr;
2127 static const WCHAR prefixW[] = {'b','m','p',0};
2128 BITMAPFILEHEADER header;
2129 WCHAR path[MAX_PATH], filename[MAX_PATH];
2130 HANDLE file;
2131 DWORD size;
2133 filename[0] = 0;
2134 if (!(hRsrc = FindResource16( hinst, name, (LPCSTR)RT_BITMAP ))) return 0;
2135 if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
2136 if (!(ptr = LockResource16( handle ))) goto done;
2137 size = SizeofResource16( hinst, hRsrc );
2139 header.bfType = 0x4d42; /* 'BM' */
2140 header.bfReserved1 = 0;
2141 header.bfReserved2 = 0;
2142 header.bfSize = sizeof(header) + size;
2143 header.bfOffBits = 0; /* not used by the 32-bit loading code */
2145 if (!GetTempPathW( MAX_PATH, path )) goto done;
2146 if (!GetTempFileNameW( path, prefixW, 0, filename )) goto done;
2148 file = CreateFileW( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
2149 if (file != INVALID_HANDLE_VALUE)
2151 DWORD written;
2152 BOOL ok;
2153 ok = WriteFile( file, &header, sizeof(header), &written, NULL ) && (written == sizeof(header));
2154 if (ok) ok = WriteFile( file, ptr, size, &written, NULL ) && (written == size);
2155 CloseHandle( file );
2156 if (ok) ret = LoadImageW( 0, filename, IMAGE_BITMAP, cx, cy, flags | LR_LOADFROMFILE );
2158 done:
2159 if (filename[0]) DeleteFileW( filename );
2160 FreeResource16( handle );
2161 return HBITMAP_16( ret );
2164 case IMAGE_ICON:
2165 case IMAGE_CURSOR:
2167 HICON16 hIcon = 0;
2168 BYTE *dir, *bits;
2169 INT id = 0;
2171 if (!(hRsrc = FindResource16( hinst, name,
2172 (LPCSTR)(type == IMAGE_ICON ? RT_GROUP_ICON : RT_GROUP_CURSOR ))))
2173 return 0;
2174 hGroupRsrc = hRsrc;
2176 if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
2177 if ((dir = LockResource16( handle ))) id = LookupIconIdFromDirectory( dir, type == IMAGE_ICON );
2178 FreeResource16( handle );
2179 if (!id) return 0;
2181 if (!(hRsrc = FindResource16( hinst, MAKEINTRESOURCEA(id),
2182 (LPCSTR)(type == IMAGE_ICON ? RT_ICON : RT_CURSOR) ))) return 0;
2184 if ((flags & LR_SHARED) && (hIcon = find_shared_icon( hinst, hRsrc ) ) != 0) return hIcon;
2186 if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
2187 bits = LockResource16( handle );
2188 hIcon = CreateIconFromResourceEx16( bits, 0, type == IMAGE_ICON, 0x00030000, cx, cy, flags );
2189 FreeResource16( handle );
2191 if (hIcon && (flags & LR_SHARED)) add_shared_icon( hinst, hRsrc, hGroupRsrc, hIcon );
2192 return hIcon;
2194 default:
2195 return 0;
2199 /******************************************************************************
2200 * CopyImage (USER.390) Creates new image and copies attributes to it
2203 HICON16 WINAPI CopyImage16(HANDLE16 hnd, UINT16 type, INT16 desiredx,
2204 INT16 desiredy, UINT16 flags)
2206 if (flags & LR_COPYFROMRESOURCE) FIXME( "LR_COPYFROMRESOURCE not supported\n" );
2208 switch (type)
2210 case IMAGE_BITMAP:
2211 return HBITMAP_16( CopyImage( HBITMAP_32(hnd), type, desiredx, desiredy, flags ));
2212 case IMAGE_ICON:
2213 case IMAGE_CURSOR:
2214 return CopyIcon16( FarGetOwner16(hnd), hnd );
2215 default:
2216 return 0;
2220 /**********************************************************************
2221 * DrawIconEx (USER.394)
2223 BOOL16 WINAPI DrawIconEx16(HDC16 hdc, INT16 xLeft, INT16 yTop, HICON16 hIcon,
2224 INT16 cxWidth, INT16 cyWidth, UINT16 istep,
2225 HBRUSH16 hbr, UINT16 flags)
2227 return DrawIconEx(HDC_32(hdc), xLeft, yTop, get_icon_32(hIcon), cxWidth, cyWidth,
2228 istep, HBRUSH_32(hbr), flags);
2231 /**********************************************************************
2232 * GetIconInfo (USER.395)
2234 BOOL16 WINAPI GetIconInfo16(HICON16 hIcon, LPICONINFO16 iconinfo)
2236 CURSORICONINFO *info = get_icon_ptr( hIcon );
2237 INT height;
2239 if (!info) return FALSE;
2241 if ((info->ptHotSpot.x == ICON_HOTSPOT) && (info->ptHotSpot.y == ICON_HOTSPOT))
2243 iconinfo->fIcon = TRUE;
2244 iconinfo->xHotspot = info->nWidth / 2;
2245 iconinfo->yHotspot = info->nHeight / 2;
2247 else
2249 iconinfo->fIcon = FALSE;
2250 iconinfo->xHotspot = info->ptHotSpot.x;
2251 iconinfo->yHotspot = info->ptHotSpot.y;
2254 height = info->nHeight;
2256 if (info->bBitsPerPixel > 1)
2258 iconinfo->hbmColor = HBITMAP_16( CreateBitmap( info->nWidth, info->nHeight,
2259 info->bPlanes, info->bBitsPerPixel,
2260 (char *)(info + 1)
2261 + info->nHeight *
2262 get_bitmap_width_bytes(info->nWidth,1) ));
2264 else
2266 iconinfo->hbmColor = 0;
2267 height *= 2;
2270 iconinfo->hbmMask = HBITMAP_16( CreateBitmap( info->nWidth, height, 1, 1, info + 1 ));
2271 release_icon_ptr( hIcon, info );
2272 return TRUE;
2276 /***********************************************************************
2277 * FinalUserInit (USER.400)
2279 void WINAPI FinalUserInit16( void )
2281 /* FIXME: Should chain to FinalGdiInit */
2285 /***********************************************************************
2286 * CreateCursor (USER.406)
2288 HCURSOR16 WINAPI CreateCursor16(HINSTANCE16 hInstance,
2289 INT16 xHotSpot, INT16 yHotSpot,
2290 INT16 nWidth, INT16 nHeight,
2291 LPCVOID lpANDbits, LPCVOID lpXORbits)
2293 CURSORICONINFO info;
2295 info.ptHotSpot.x = xHotSpot;
2296 info.ptHotSpot.y = yHotSpot;
2297 info.nWidth = nWidth;
2298 info.nHeight = nHeight;
2299 info.nWidthBytes = 0;
2300 info.bPlanes = 1;
2301 info.bBitsPerPixel = 1;
2303 return CreateCursorIconIndirect16(hInstance, &info, lpANDbits, lpXORbits);
2307 /***********************************************************************
2308 * CreateIcon (USER.407)
2310 HICON16 WINAPI CreateIcon16( HINSTANCE16 hInstance, INT16 nWidth,
2311 INT16 nHeight, BYTE bPlanes, BYTE bBitsPixel,
2312 LPCVOID lpANDbits, LPCVOID lpXORbits )
2314 CURSORICONINFO info;
2316 info.ptHotSpot.x = ICON_HOTSPOT;
2317 info.ptHotSpot.y = ICON_HOTSPOT;
2318 info.nWidth = nWidth;
2319 info.nHeight = nHeight;
2320 info.nWidthBytes = 0;
2321 info.bPlanes = bPlanes;
2322 info.bBitsPerPixel = bBitsPixel;
2324 return CreateCursorIconIndirect16( hInstance, &info, lpANDbits, lpXORbits );
2328 /***********************************************************************
2329 * CreateCursorIconIndirect (USER.408)
2331 HGLOBAL16 WINAPI CreateCursorIconIndirect16( HINSTANCE16 hInstance,
2332 CURSORICONINFO *info,
2333 LPCVOID lpANDbits,
2334 LPCVOID lpXORbits )
2336 HICON16 handle;
2337 CURSORICONINFO *ptr;
2338 int sizeAnd, sizeXor;
2340 hInstance = GetExePtr( hInstance ); /* Make it a module handle */
2341 if (!lpXORbits || !lpANDbits || info->bPlanes != 1) return 0;
2342 info->nWidthBytes = get_bitmap_width_bytes(info->nWidth,info->bBitsPerPixel);
2343 sizeXor = info->nHeight * info->nWidthBytes;
2344 sizeAnd = info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
2345 if (!(handle = alloc_icon_handle( sizeof(CURSORICONINFO) + sizeXor + sizeAnd )))
2346 return 0;
2347 FarSetOwner16( handle, hInstance );
2348 ptr = get_icon_ptr( handle );
2349 memcpy( ptr, info, sizeof(*info) );
2350 memcpy( ptr + 1, lpANDbits, sizeAnd );
2351 memcpy( (char *)(ptr + 1) + sizeAnd, lpXORbits, sizeXor );
2352 release_icon_ptr( handle, ptr );
2353 return handle;
2357 /***********************************************************************
2358 * InitThreadInput (USER.409)
2360 HQUEUE16 WINAPI InitThreadInput16( WORD unknown, WORD flags )
2362 /* nothing to do here */
2363 return 0xbeef;
2367 /*******************************************************************
2368 * InsertMenu (USER.410)
2370 BOOL16 WINAPI InsertMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
2371 UINT16 id, SEGPTR data )
2373 UINT pos32 = (UINT)pos;
2374 if ((pos == (UINT16)-1) && (flags & MF_BYPOSITION)) pos32 = (UINT)-1;
2375 if (IS_MENU_STRING_ITEM(flags) && data)
2376 return InsertMenuA( HMENU_32(hMenu), pos32, flags, id, MapSL(data) );
2377 return InsertMenuA( HMENU_32(hMenu), pos32, flags, id, (LPSTR)data );
2381 /*******************************************************************
2382 * AppendMenu (USER.411)
2384 BOOL16 WINAPI AppendMenu16(HMENU16 hMenu, UINT16 flags, UINT16 id, SEGPTR data)
2386 return InsertMenu16( hMenu, -1, flags | MF_BYPOSITION, id, data );
2390 /**********************************************************************
2391 * RemoveMenu (USER.412)
2393 BOOL16 WINAPI RemoveMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
2395 return RemoveMenu( HMENU_32(hMenu), nPos, wFlags );
2399 /**********************************************************************
2400 * DeleteMenu (USER.413)
2402 BOOL16 WINAPI DeleteMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
2404 return DeleteMenu( HMENU_32(hMenu), nPos, wFlags );
2408 /*******************************************************************
2409 * ModifyMenu (USER.414)
2411 BOOL16 WINAPI ModifyMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
2412 UINT16 id, SEGPTR data )
2414 if (IS_MENU_STRING_ITEM(flags))
2415 return ModifyMenuA( HMENU_32(hMenu), pos, flags, id, MapSL(data) );
2416 return ModifyMenuA( HMENU_32(hMenu), pos, flags, id, (LPSTR)data );
2420 /**********************************************************************
2421 * CreatePopupMenu (USER.415)
2423 HMENU16 WINAPI CreatePopupMenu16(void)
2425 return HMENU_16( CreatePopupMenu() );
2429 /**********************************************************************
2430 * SetMenuItemBitmaps (USER.418)
2432 BOOL16 WINAPI SetMenuItemBitmaps16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags,
2433 HBITMAP16 hNewUnCheck, HBITMAP16 hNewCheck)
2435 return SetMenuItemBitmaps( HMENU_32(hMenu), nPos, wFlags,
2436 HBITMAP_32(hNewUnCheck), HBITMAP_32(hNewCheck) );
2440 /***********************************************************************
2441 * wvsprintf (USER.421)
2443 INT16 WINAPI wvsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 args )
2445 WPRINTF_FORMAT format;
2446 LPSTR p = buffer;
2447 UINT i, len, sign;
2448 CHAR number[20];
2449 CHAR char_view = 0;
2450 LPCSTR lpcstr_view = NULL;
2451 INT int_view;
2452 SEGPTR seg_str;
2454 while (*spec)
2456 if (*spec != '%') { *p++ = *spec++; continue; }
2457 spec++;
2458 if (*spec == '%') { *p++ = *spec++; continue; }
2459 spec += parse_format( spec, &format );
2460 switch(format.type)
2462 case WPR_CHAR:
2463 char_view = VA_ARG16( args, CHAR );
2464 len = format.precision = 1;
2465 break;
2466 case WPR_STRING:
2467 seg_str = VA_ARG16( args, SEGPTR );
2468 if (IsBadReadPtr16( seg_str, 1 )) lpcstr_view = "";
2469 else lpcstr_view = MapSL( seg_str );
2470 if (!lpcstr_view) lpcstr_view = "(null)";
2471 for (len = 0; !format.precision || (len < format.precision); len++)
2472 if (!lpcstr_view[len]) break;
2473 format.precision = len;
2474 break;
2475 case WPR_SIGNED:
2476 if (format.flags & WPRINTF_LONG) int_view = VA_ARG16( args, INT );
2477 else int_view = VA_ARG16( args, INT16 );
2478 len = sprintf( number, "%d", int_view );
2479 break;
2480 case WPR_UNSIGNED:
2481 if (format.flags & WPRINTF_LONG) int_view = VA_ARG16( args, UINT );
2482 else int_view = VA_ARG16( args, UINT16 );
2483 len = sprintf( number, "%u", int_view );
2484 break;
2485 case WPR_HEXA:
2486 if (format.flags & WPRINTF_LONG) int_view = VA_ARG16( args, UINT );
2487 else int_view = VA_ARG16( args, UINT16 );
2488 len = sprintf( number, (format.flags & WPRINTF_UPPER_HEX) ? "%X" : "%x", int_view);
2489 break;
2490 case WPR_UNKNOWN:
2491 continue;
2493 if (format.precision < len) format.precision = len;
2494 if (format.flags & WPRINTF_LEFTALIGN) format.flags &= ~WPRINTF_ZEROPAD;
2495 if ((format.flags & WPRINTF_ZEROPAD) && (format.width > format.precision))
2496 format.precision = format.width;
2497 if (format.flags & WPRINTF_PREFIX_HEX) len += 2;
2499 sign = 0;
2500 if (!(format.flags & WPRINTF_LEFTALIGN))
2501 for (i = format.precision; i < format.width; i++) *p++ = ' ';
2502 switch(format.type)
2504 case WPR_CHAR:
2505 *p = char_view;
2506 /* wsprintf16 ignores null characters */
2507 if (*p != '\0') p++;
2508 else if (format.width > 1) *p++ = ' ';
2509 else len = 0;
2510 break;
2511 case WPR_STRING:
2512 if (len) memcpy( p, lpcstr_view, len );
2513 p += len;
2514 break;
2515 case WPR_HEXA:
2516 if (format.flags & WPRINTF_PREFIX_HEX)
2518 *p++ = '0';
2519 *p++ = (format.flags & WPRINTF_UPPER_HEX) ? 'X' : 'x';
2520 len -= 2;
2522 /* fall through */
2523 case WPR_SIGNED:
2524 /* Transfer the sign now, just in case it will be zero-padded*/
2525 if (number[0] == '-')
2527 *p++ = '-';
2528 sign = 1;
2530 /* fall through */
2531 case WPR_UNSIGNED:
2532 for (i = len; i < format.precision; i++) *p++ = '0';
2533 if (len > sign) memcpy( p, number + sign, len - sign );
2534 p += len-sign;
2535 break;
2536 case WPR_UNKNOWN:
2537 continue;
2539 if (format.flags & WPRINTF_LEFTALIGN)
2540 for (i = format.precision; i < format.width; i++) *p++ = ' ';
2542 *p = 0;
2543 return p - buffer;
2547 /***********************************************************************
2548 * _wsprintf (USER.420)
2550 INT16 WINAPIV wsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 valist )
2552 return wvsprintf16( buffer, spec, valist );
2556 /***********************************************************************
2557 * lstrcmp (USER.430)
2559 INT16 WINAPI lstrcmp16( LPCSTR str1, LPCSTR str2 )
2561 return strcmp( str1, str2 );
2565 /***********************************************************************
2566 * AnsiUpper (USER.431)
2568 SEGPTR WINAPI AnsiUpper16( SEGPTR strOrChar )
2570 /* uppercase only one char if strOrChar < 0x10000 */
2571 if (HIWORD(strOrChar))
2573 CharUpperA( MapSL(strOrChar) );
2574 return strOrChar;
2576 else return (SEGPTR)CharUpperA( (LPSTR)strOrChar );
2580 /***********************************************************************
2581 * AnsiLower (USER.432)
2583 SEGPTR WINAPI AnsiLower16( SEGPTR strOrChar )
2585 /* lowercase only one char if strOrChar < 0x10000 */
2586 if (HIWORD(strOrChar))
2588 CharLowerA( MapSL(strOrChar) );
2589 return strOrChar;
2591 else return (SEGPTR)CharLowerA( (LPSTR)strOrChar );
2595 /***********************************************************************
2596 * AnsiUpperBuff (USER.437)
2598 UINT16 WINAPI AnsiUpperBuff16( LPSTR str, UINT16 len )
2600 CharUpperBuffA( str, len ? len : 65536 );
2601 return len;
2605 /***********************************************************************
2606 * AnsiLowerBuff (USER.438)
2608 UINT16 WINAPI AnsiLowerBuff16( LPSTR str, UINT16 len )
2610 CharLowerBuffA( str, len ? len : 65536 );
2611 return len;
2615 /*******************************************************************
2616 * InsertMenuItem (USER.441)
2618 * FIXME: untested
2620 BOOL16 WINAPI InsertMenuItem16( HMENU16 hmenu, UINT16 pos, BOOL16 byposition,
2621 const MENUITEMINFO16 *mii )
2623 MENUITEMINFOA miia;
2625 miia.cbSize = sizeof(miia);
2626 miia.fMask = mii->fMask;
2627 miia.dwTypeData = (LPSTR)mii->dwTypeData;
2628 miia.fType = mii->fType;
2629 miia.fState = mii->fState;
2630 miia.wID = mii->wID;
2631 miia.hSubMenu = HMENU_32(mii->hSubMenu);
2632 miia.hbmpChecked = HBITMAP_32(mii->hbmpChecked);
2633 miia.hbmpUnchecked = HBITMAP_32(mii->hbmpUnchecked);
2634 miia.dwItemData = mii->dwItemData;
2635 miia.cch = mii->cch;
2636 if (IS_MENU_STRING_ITEM(miia.fType))
2637 miia.dwTypeData = MapSL(mii->dwTypeData);
2638 return InsertMenuItemA( HMENU_32(hmenu), pos, byposition, &miia );
2642 /**********************************************************************
2643 * DrawState (USER.449)
2645 BOOL16 WINAPI DrawState16( HDC16 hdc, HBRUSH16 hbr, DRAWSTATEPROC16 func, LPARAM ldata,
2646 WPARAM16 wdata, INT16 x, INT16 y, INT16 cx, INT16 cy, UINT16 flags )
2648 struct draw_state_info info;
2649 UINT opcode = flags & 0xf;
2651 if (opcode == DST_TEXT || opcode == DST_PREFIXTEXT)
2653 /* make sure DrawStateA doesn't try to use ldata as a pointer */
2654 if (!wdata) wdata = strlen( MapSL(ldata) );
2655 if (!cx || !cy)
2657 SIZE s;
2658 if (!GetTextExtentPoint32A( HDC_32(hdc), MapSL(ldata), wdata, &s )) return FALSE;
2659 if (!cx) cx = s.cx;
2660 if (!cy) cy = s.cy;
2663 info.proc = func;
2664 info.param = ldata;
2665 return DrawStateA( HDC_32(hdc), HBRUSH_32(hbr), draw_state_callback,
2666 (LPARAM)&info, wdata, x, y, cx, cy, flags );
2670 /**********************************************************************
2671 * CreateIconFromResourceEx (USER.450)
2673 * FIXME: not sure about exact parameter types
2675 HICON16 WINAPI CreateIconFromResourceEx16(LPBYTE bits, UINT16 cbSize,
2676 BOOL16 bIcon, DWORD dwVersion,
2677 INT16 width, INT16 height,
2678 UINT16 cFlag)
2680 return get_icon_16( CreateIconFromResourceEx( bits, cbSize, bIcon, dwVersion, width, height, cFlag ));
2684 /***********************************************************************
2685 * AdjustWindowRectEx (USER.454)
2687 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style, BOOL16 menu, DWORD exStyle )
2689 RECT rect32;
2690 BOOL ret;
2692 rect32.left = rect->left;
2693 rect32.top = rect->top;
2694 rect32.right = rect->right;
2695 rect32.bottom = rect->bottom;
2696 ret = AdjustWindowRectEx( &rect32, style, menu, exStyle );
2697 rect->left = rect32.left;
2698 rect->top = rect32.top;
2699 rect->right = rect32.right;
2700 rect->bottom = rect32.bottom;
2701 return ret;
2705 /**********************************************************************
2706 * GetIconID (USER.455)
2708 WORD WINAPI GetIconID16( HGLOBAL16 hResource, DWORD resType )
2710 BYTE *dir = GlobalLock16(hResource);
2712 switch (resType)
2714 case RT_CURSOR:
2715 return LookupIconIdFromDirectoryEx16( dir, FALSE, GetSystemMetrics(SM_CXCURSOR),
2716 GetSystemMetrics(SM_CYCURSOR), LR_MONOCHROME );
2717 case RT_ICON:
2718 return LookupIconIdFromDirectoryEx16( dir, TRUE, GetSystemMetrics(SM_CXICON),
2719 GetSystemMetrics(SM_CYICON), 0 );
2721 return 0;
2725 /**********************************************************************
2726 * LoadIconHandler (USER.456)
2728 HICON16 WINAPI LoadIconHandler16( HGLOBAL16 hResource, BOOL16 bNew )
2730 return CreateIconFromResourceEx16( LockResource16( hResource ), 0, TRUE,
2731 bNew ? 0x00030000 : 0x00020000, 0, 0, LR_DEFAULTCOLOR );
2735 /***********************************************************************
2736 * DestroyIcon (USER.457)
2738 BOOL16 WINAPI DestroyIcon16(HICON16 hIcon)
2740 int count;
2742 TRACE("%04x\n", hIcon );
2744 count = release_shared_icon( hIcon );
2745 if (count != -1) return !count;
2746 /* assume non-shared */
2747 free_icon_handle( hIcon );
2748 return TRUE;
2751 /***********************************************************************
2752 * DestroyCursor (USER.458)
2754 BOOL16 WINAPI DestroyCursor16(HCURSOR16 hCursor)
2756 return DestroyIcon16( hCursor );
2760 /***********************************************************************
2761 * DumpIcon (USER.459)
2763 DWORD WINAPI DumpIcon16( SEGPTR pInfo, WORD *lpLen,
2764 SEGPTR *lpXorBits, SEGPTR *lpAndBits )
2766 CURSORICONINFO *info = MapSL( pInfo );
2767 int sizeAnd, sizeXor;
2769 if (!info) return 0;
2770 sizeXor = info->nHeight * info->nWidthBytes;
2771 sizeAnd = info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
2772 if (lpAndBits) *lpAndBits = pInfo + sizeof(CURSORICONINFO);
2773 if (lpXorBits) *lpXorBits = pInfo + sizeof(CURSORICONINFO) + sizeAnd;
2774 if (lpLen) *lpLen = sizeof(CURSORICONINFO) + sizeAnd + sizeXor;
2775 return MAKELONG( sizeXor, sizeXor );
2779 /*******************************************************************
2780 * DRAG_QueryUpdate16
2782 * Recursively find a child that contains spDragInfo->pt point
2783 * and send WM_QUERYDROPOBJECT. Helper for DragObject16.
2785 static BOOL DRAG_QueryUpdate16( HWND hQueryWnd, SEGPTR spDragInfo )
2787 BOOL bResult = 0;
2788 WPARAM wParam;
2789 POINT pt, old_pt;
2790 LPDRAGINFO16 ptrDragInfo = MapSL(spDragInfo);
2791 RECT tempRect;
2792 HWND child;
2794 if (!IsWindowEnabled(hQueryWnd)) return FALSE;
2796 old_pt.x = ptrDragInfo->pt.x;
2797 old_pt.y = ptrDragInfo->pt.y;
2798 pt = old_pt;
2799 ScreenToClient( hQueryWnd, &pt );
2800 child = ChildWindowFromPointEx( hQueryWnd, pt, CWP_SKIPINVISIBLE );
2801 if (!child) return FALSE;
2803 if (child != hQueryWnd)
2805 wParam = 0;
2806 if (DRAG_QueryUpdate16( child, spDragInfo )) return TRUE;
2808 else
2810 GetClientRect( hQueryWnd, &tempRect );
2811 wParam = !PtInRect( &tempRect, pt );
2814 ptrDragInfo->pt.x = pt.x;
2815 ptrDragInfo->pt.y = pt.y;
2816 ptrDragInfo->hScope = HWND_16(hQueryWnd);
2818 bResult = SendMessage16( HWND_16(hQueryWnd), WM_QUERYDROPOBJECT, wParam, spDragInfo );
2820 if (!bResult)
2822 ptrDragInfo->pt.x = old_pt.x;
2823 ptrDragInfo->pt.y = old_pt.y;
2825 return bResult;
2829 /******************************************************************************
2830 * DragObject (USER.464)
2832 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2833 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2835 MSG msg;
2836 LPDRAGINFO16 lpDragInfo;
2837 SEGPTR spDragInfo;
2838 HCURSOR hOldCursor=0, hBummer=0, hCursor32;
2839 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO16));
2840 HCURSOR hCurrentCursor = 0;
2841 HWND16 hCurrentWnd = 0;
2843 lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo);
2844 spDragInfo = WOWGlobalLock16(hDragInfo);
2846 if( !lpDragInfo || !spDragInfo ) return 0L;
2848 if (!(hBummer = LoadCursorA(0, MAKEINTRESOURCEA(OCR_NO))))
2850 GlobalFree16(hDragInfo);
2851 return 0L;
2854 if ((hCursor32 = get_icon_32( hCursor ))) SetCursor( hCursor32 );
2856 lpDragInfo->hWnd = hWnd;
2857 lpDragInfo->hScope = 0;
2858 lpDragInfo->wFlags = wObj;
2859 lpDragInfo->hList = szList; /* near pointer! */
2860 lpDragInfo->hOfStruct = hOfStruct;
2861 lpDragInfo->l = 0L;
2863 SetCapture( HWND_32(hWnd) );
2864 ShowCursor( TRUE );
2868 GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST );
2870 *(lpDragInfo+1) = *lpDragInfo;
2872 lpDragInfo->pt.x = msg.pt.x;
2873 lpDragInfo->pt.y = msg.pt.y;
2875 /* update DRAGINFO struct */
2876 if( DRAG_QueryUpdate16(WIN_Handle32(hwndScope), spDragInfo) > 0 )
2877 hCurrentCursor = hCursor32;
2878 else
2880 hCurrentCursor = hBummer;
2881 lpDragInfo->hScope = 0;
2883 if( hCurrentCursor )
2884 SetCursor(hCurrentCursor);
2886 /* send WM_DRAGLOOP */
2887 SendMessage16( hWnd, WM_DRAGLOOP, hCurrentCursor != hBummer, spDragInfo );
2888 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2889 if( hCurrentWnd != lpDragInfo->hScope )
2891 if( hCurrentWnd )
2892 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2893 MAKELPARAM(LOWORD(spDragInfo)+sizeof(DRAGINFO16),
2894 HIWORD(spDragInfo)) );
2895 hCurrentWnd = lpDragInfo->hScope;
2896 if( hCurrentWnd )
2897 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, spDragInfo);
2899 else
2900 if( hCurrentWnd )
2901 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, spDragInfo);
2903 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2905 ReleaseCapture();
2906 ShowCursor( FALSE );
2908 if( hCursor ) SetCursor(hOldCursor);
2910 if( hCurrentCursor != hBummer )
2911 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2912 hWnd, spDragInfo );
2913 else
2914 msg.lParam = 0;
2915 GlobalFree16(hDragInfo);
2917 return (DWORD)(msg.lParam);
2921 /***********************************************************************
2922 * DrawFocusRect (USER.466)
2924 void WINAPI DrawFocusRect16( HDC16 hdc, const RECT16* rc )
2926 RECT rect32;
2928 rect32.left = rc->left;
2929 rect32.top = rc->top;
2930 rect32.right = rc->right;
2931 rect32.bottom = rc->bottom;
2932 DrawFocusRect( HDC_32(hdc), &rect32 );
2936 /***********************************************************************
2937 * AnsiNext (USER.472)
2939 SEGPTR WINAPI AnsiNext16(SEGPTR current)
2941 char *ptr = MapSL(current);
2942 return current + (CharNextA(ptr) - ptr);
2946 /***********************************************************************
2947 * AnsiPrev (USER.473)
2949 SEGPTR WINAPI AnsiPrev16( LPCSTR start, SEGPTR current )
2951 char *ptr = MapSL(current);
2952 return current - (ptr - CharPrevA( start, ptr ));
2956 /****************************************************************************
2957 * GetKeyboardLayoutName (USER.477)
2959 INT16 WINAPI GetKeyboardLayoutName16( LPSTR name )
2961 return GetKeyboardLayoutNameA( name );
2965 /***********************************************************************
2966 * SystemParametersInfo (USER.483)
2968 BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
2969 LPVOID lpvParam, UINT16 fuWinIni )
2971 BOOL16 ret;
2973 TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
2975 switch (uAction)
2977 case SPI_GETBEEP:
2978 case SPI_GETSCREENSAVEACTIVE:
2979 case SPI_GETICONTITLEWRAP:
2980 case SPI_GETMENUDROPALIGNMENT:
2981 case SPI_GETFASTTASKSWITCH:
2982 case SPI_GETDRAGFULLWINDOWS:
2984 BOOL tmp;
2985 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2986 if (ret && lpvParam) *(BOOL16 *)lpvParam = tmp;
2987 break;
2990 case SPI_GETBORDER:
2991 case SPI_ICONHORIZONTALSPACING:
2992 case SPI_GETSCREENSAVETIMEOUT:
2993 case SPI_GETGRIDGRANULARITY:
2994 case SPI_GETKEYBOARDDELAY:
2995 case SPI_ICONVERTICALSPACING:
2997 INT tmp;
2998 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2999 if (ret && lpvParam) *(INT16 *)lpvParam = tmp;
3000 break;
3003 case SPI_GETKEYBOARDSPEED:
3004 case SPI_GETMOUSEHOVERWIDTH:
3005 case SPI_GETMOUSEHOVERHEIGHT:
3006 case SPI_GETMOUSEHOVERTIME:
3008 DWORD tmp;
3009 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
3010 if (ret && lpvParam) *(WORD *)lpvParam = tmp;
3011 break;
3014 case SPI_GETICONTITLELOGFONT:
3016 LOGFONTA tmp;
3017 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
3018 if (ret && lpvParam) logfont_32_to_16( &tmp, (LPLOGFONT16)lpvParam );
3019 break;
3022 case SPI_GETNONCLIENTMETRICS:
3024 NONCLIENTMETRICSA tmp;
3025 LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
3026 if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
3028 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
3029 ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
3030 if (ret)
3032 lpnm16->iBorderWidth = tmp.iBorderWidth;
3033 lpnm16->iScrollWidth = tmp.iScrollWidth;
3034 lpnm16->iScrollHeight = tmp.iScrollHeight;
3035 lpnm16->iCaptionWidth = tmp.iCaptionWidth;
3036 lpnm16->iCaptionHeight = tmp.iCaptionHeight;
3037 lpnm16->iSmCaptionWidth = tmp.iSmCaptionWidth;
3038 lpnm16->iSmCaptionHeight = tmp.iSmCaptionHeight;
3039 lpnm16->iMenuWidth = tmp.iMenuWidth;
3040 lpnm16->iMenuHeight = tmp.iMenuHeight;
3041 logfont_32_to_16( &tmp.lfCaptionFont, &lpnm16->lfCaptionFont );
3042 logfont_32_to_16( &tmp.lfSmCaptionFont, &lpnm16->lfSmCaptionFont );
3043 logfont_32_to_16( &tmp.lfMenuFont, &lpnm16->lfMenuFont );
3044 logfont_32_to_16( &tmp.lfStatusFont, &lpnm16->lfStatusFont );
3045 logfont_32_to_16( &tmp.lfMessageFont, &lpnm16->lfMessageFont );
3048 else /* winfile 95 sets cbSize to 340 */
3049 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
3050 break;
3053 case SPI_GETWORKAREA:
3055 RECT tmp;
3056 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
3057 if (ret && lpvParam)
3059 RECT16 *r16 = lpvParam;
3060 r16->left = tmp.left;
3061 r16->top = tmp.top;
3062 r16->right = tmp.right;
3063 r16->bottom = tmp.bottom;
3065 break;
3068 default:
3069 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
3070 break;
3073 return ret;
3077 /***********************************************************************
3078 * USER_489 (USER.489)
3080 LONG WINAPI stub_USER_489(void)
3082 FIXME("stub\n");
3083 return 0;
3087 /***********************************************************************
3088 * USER_490 (USER.490)
3090 LONG WINAPI stub_USER_490(void)
3092 FIXME("stub\n");
3093 return 0;
3097 /***********************************************************************
3098 * USER_492 (USER.492)
3100 LONG WINAPI stub_USER_492(void)
3102 FIXME("stub\n");
3103 return 0;
3107 /***********************************************************************
3108 * USER_496 (USER.496)
3110 LONG WINAPI stub_USER_496(void)
3112 FIXME("stub\n");
3113 return 0;
3117 /***********************************************************************
3118 * FormatMessage (USER.606)
3120 DWORD WINAPI FormatMessage16(
3121 DWORD dwFlags,
3122 SEGPTR lpSource, /* [in] NOTE: not always a valid pointer */
3123 WORD dwMessageId,
3124 WORD dwLanguageId,
3125 LPSTR lpBuffer, /* [out] NOTE: *((HLOCAL16*)) for FORMAT_MESSAGE_ALLOCATE_BUFFER*/
3126 WORD nSize,
3127 LPDWORD args ) /* [in] NOTE: va_list *args */
3129 /* This implementation is completely dependent on the format of the va_list on x86 CPUs */
3130 LPSTR target,t;
3131 DWORD talloced;
3132 LPSTR from,f;
3133 DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
3134 BOOL eos = FALSE;
3135 LPSTR allocstring = NULL;
3137 TRACE("(0x%x,%x,%d,0x%x,%p,%d,%p)\n",
3138 dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
3139 if ((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
3140 && (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)) return 0;
3141 if ((dwFlags & FORMAT_MESSAGE_FROM_STRING)
3142 &&((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
3143 || (dwFlags & FORMAT_MESSAGE_FROM_HMODULE))) return 0;
3145 if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
3146 FIXME("line wrapping (%u) not supported.\n", width);
3147 from = NULL;
3148 if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
3150 char *source = MapSL(lpSource);
3151 from = HeapAlloc( GetProcessHeap(), 0, strlen(source)+1 );
3152 strcpy( from, source );
3154 else if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
3155 from = HeapAlloc( GetProcessHeap(),0,200 );
3156 sprintf(from,"Systemmessage, messageid = 0x%08x\n",dwMessageId);
3158 else if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
3159 INT16 bufsize;
3160 HINSTANCE16 hinst16 = ((HINSTANCE16)lpSource & 0xffff);
3162 dwMessageId &= 0xFFFF;
3163 bufsize=LoadString16(hinst16,dwMessageId,NULL,0);
3164 if (bufsize) {
3165 from = HeapAlloc( GetProcessHeap(), 0, bufsize +1);
3166 LoadString16(hinst16,dwMessageId,from,bufsize+1);
3169 target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
3170 t = target;
3171 talloced= 100;
3173 #define ADD_TO_T(c) \
3174 *t++=c;\
3175 if (t-target == talloced) {\
3176 target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
3177 t = target+talloced;\
3178 talloced*=2;\
3181 if (from) {
3182 f=from;
3183 while (*f && !eos) {
3184 if (*f=='%') {
3185 int insertnr;
3186 char *fmtstr,*x,*lastf;
3187 DWORD *argliststart;
3189 fmtstr = NULL;
3190 lastf = f;
3191 f++;
3192 if (!*f) {
3193 ADD_TO_T('%');
3194 continue;
3196 switch (*f) {
3197 case '1':case '2':case '3':case '4':case '5':
3198 case '6':case '7':case '8':case '9':
3199 insertnr=*f-'0';
3200 switch (f[1]) {
3201 case '0':case '1':case '2':case '3':
3202 case '4':case '5':case '6':case '7':
3203 case '8':case '9':
3204 f++;
3205 insertnr=insertnr*10+*f-'0';
3206 f++;
3207 break;
3208 default:
3209 f++;
3210 break;
3212 if (*f=='!') {
3213 f++;
3214 if (NULL!=(x=strchr(f,'!'))) {
3215 *x='\0';
3216 fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
3217 sprintf(fmtstr,"%%%s",f);
3218 f=x+1;
3219 } else {
3220 fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
3221 sprintf(fmtstr,"%%%s",f);
3222 f+=strlen(f); /*at \0*/
3225 else
3227 if(!args) break;
3228 fmtstr=HeapAlloc( GetProcessHeap(), 0, 3 );
3229 strcpy( fmtstr, "%s" );
3231 if (args) {
3232 int ret;
3233 int sz;
3234 LPSTR b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 100);
3236 argliststart=args+insertnr-1;
3238 /* CMF - This makes a BIG assumption about va_list */
3239 while ((ret = vsnprintf(b, sz, fmtstr, (va_list) argliststart) < 0) || (ret >= sz)) {
3240 sz = (ret == -1 ? sz + 100 : ret + 1);
3241 b = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, b, sz);
3243 for (x=b; *x; x++) ADD_TO_T(*x);
3244 HeapFree(GetProcessHeap(), 0, b);
3245 } else {
3246 /* NULL args - copy formatstr
3247 * (probably wrong)
3249 while ((lastf<f)&&(*lastf)) {
3250 ADD_TO_T(*lastf++);
3253 HeapFree(GetProcessHeap(),0,fmtstr);
3254 break;
3255 case '0': /* Just stop processing format string */
3256 eos = TRUE;
3257 f++;
3258 break;
3259 case 'n': /* 16 bit version just outputs 'n' */
3260 default:
3261 ADD_TO_T(*f++);
3262 break;
3264 } else { /* '\n' or '\r' gets mapped to "\r\n" */
3265 if(*f == '\n' || *f == '\r') {
3266 if (width == 0) {
3267 ADD_TO_T('\r');
3268 ADD_TO_T('\n');
3269 if(*f++ == '\r' && *f == '\n')
3270 f++;
3272 } else {
3273 ADD_TO_T(*f++);
3277 *t='\0';
3279 talloced = strlen(target)+1;
3280 if (nSize && talloced<nSize) {
3281 target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
3283 TRACE("-- %s\n",debugstr_a(target));
3284 if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
3285 /* nSize is the MINIMUM size */
3286 HLOCAL16 h = LocalAlloc16(LPTR,talloced);
3287 SEGPTR ptr = LocalLock16(h);
3288 allocstring = MapSL( ptr );
3289 memcpy( allocstring,target,talloced);
3290 LocalUnlock16( h );
3291 *((HLOCAL16*)lpBuffer) = h;
3292 } else
3293 lstrcpynA(lpBuffer,target,nSize);
3294 HeapFree(GetProcessHeap(),0,target);
3295 HeapFree(GetProcessHeap(),0,from);
3296 return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
3297 strlen(allocstring):
3298 strlen(lpBuffer);
3300 #undef ADD_TO_T
3303 /**********************************************************************
3304 * DestroyIcon32 (USER.610)
3306 * This routine is actually exported from Win95 USER under the name
3307 * DestroyIcon32 ... The behaviour implemented here should mimic
3308 * the Win95 one exactly, especially the return values, which
3309 * depend on the setting of various flags.
3311 WORD WINAPI DestroyIcon32( HGLOBAL16 handle, UINT16 flags )
3313 WORD retv;
3315 /* Check whether destroying active cursor */
3317 if (GetCursor16() == handle)
3319 WARN("Destroying active cursor!\n" );
3320 return FALSE;
3323 /* Try shared cursor/icon first */
3325 if (!(flags & CID_NONSHARED))
3327 INT count = release_shared_icon( handle );
3328 if (count != -1)
3329 return (flags & CID_WIN32) ? TRUE : (count == 0);
3332 /* Now assume non-shared cursor/icon */
3334 retv = free_icon_handle( handle );
3335 return (flags & CID_RESOURCE)? retv : TRUE;
3339 /***********************************************************************
3340 * ChangeDisplaySettings (USER.620)
3342 LONG WINAPI ChangeDisplaySettings16( LPDEVMODEA devmode, DWORD flags )
3344 return ChangeDisplaySettingsA( devmode, flags );
3348 /***********************************************************************
3349 * EnumDisplaySettings (USER.621)
3351 BOOL16 WINAPI EnumDisplaySettings16( LPCSTR name, DWORD n, LPDEVMODEA devmode )
3353 return EnumDisplaySettingsA( name, n, devmode );
3356 /**********************************************************************
3357 * DrawFrameControl (USER.656)
3359 BOOL16 WINAPI DrawFrameControl16( HDC16 hdc, LPRECT16 rc, UINT16 uType, UINT16 uState )
3361 RECT rect32;
3362 BOOL ret;
3364 rect32.left = rc->left;
3365 rect32.top = rc->top;
3366 rect32.right = rc->right;
3367 rect32.bottom = rc->bottom;
3368 ret = DrawFrameControl( HDC_32(hdc), &rect32, uType, uState );
3369 rc->left = rect32.left;
3370 rc->top = rect32.top;
3371 rc->right = rect32.right;
3372 rc->bottom = rect32.bottom;
3373 return ret;
3376 /**********************************************************************
3377 * DrawEdge (USER.659)
3379 BOOL16 WINAPI DrawEdge16( HDC16 hdc, LPRECT16 rc, UINT16 edge, UINT16 flags )
3381 RECT rect32;
3382 BOOL ret;
3384 rect32.left = rc->left;
3385 rect32.top = rc->top;
3386 rect32.right = rc->right;
3387 rect32.bottom = rc->bottom;
3388 ret = DrawEdge( HDC_32(hdc), &rect32, edge, flags );
3389 rc->left = rect32.left;
3390 rc->top = rect32.top;
3391 rc->right = rect32.right;
3392 rc->bottom = rect32.bottom;
3393 return ret;
3396 /**********************************************************************
3397 * CheckMenuRadioItem (USER.666)
3399 BOOL16 WINAPI CheckMenuRadioItem16(HMENU16 hMenu, UINT16 first, UINT16 last,
3400 UINT16 check, BOOL16 bypos)
3402 return CheckMenuRadioItem( HMENU_32(hMenu), first, last, check, bypos );