ieframe: Fixed index of stored history when loading from history.
[wine] / dlls / user.exe16 / user.c
CommitLineData
d8f50798
PS
1/*
2 * Misc 16-bit USER functions
3 *
6de70abd 4 * Copyright 1993, 1996 Alexandre Julliard
d8f50798
PS
5 * Copyright 2002 Patrik Stridvall
6 *
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.
11 *
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.
16 *
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
360a3f91 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
d8f50798
PS
20 */
21
e37c6e18 22#include <stdarg.h>
7ef66af3 23#include <stdlib.h>
89b0f3ae
AJ
24#include <stdio.h>
25#include <string.h>
26
09969805
FG
27#define OEMRESOURCE
28
d8f50798 29#include "wine/winuser16.h"
e37c6e18 30#include "windef.h"
d8f50798 31#include "winbase.h"
0ca051e5 32#include "wownt32.h"
6a78c16a 33#include "user_private.h"
d5b270ea 34#include "wine/list.h"
d646c7ed
AJ
35#include "wine/debug.h"
36
37WINE_DEFAULT_DEBUG_CHANNEL(user);
d8f50798 38
2d0acacb
MS
39/* handle to handle 16 conversions */
40#define HANDLE_16(h32) (LOWORD(h32))
3313c40b 41#define HGDIOBJ_16(h32) (LOWORD(h32))
2d0acacb
MS
42
43/* handle16 to handle conversions */
44#define HANDLE_32(h16) ((HANDLE)(ULONG_PTR)(h16))
3313c40b 45#define HGDIOBJ_32(h16) ((HGDIOBJ)(ULONG_PTR)(h16))
2d0acacb 46
7ef66af3
AJ
47#define IS_MENU_STRING_ITEM(flags) \
48 (((flags) & (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR)) == MF_STRING)
49
03f6f6f7
AJ
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
56
1d1f8e2a
AJ
57#define CID_RESOURCE 0x0001
58#define CID_WIN32 0x0004
59#define CID_NONSHARED 0x0008
2d0acacb 60
796346f8 61WORD USER_HeapSel = 0; /* USER heap selector */
2d0acacb 62
a157959d
AJ
63static HINSTANCE16 gdi_inst;
64
45078fb0
AJ
65struct gray_string_info
66{
67 GRAYSTRINGPROC16 proc;
68 LPARAM param;
69 char str[1];
70};
71
72/* callback for 16-bit gray string proc with opaque pointer */
73static BOOL CALLBACK gray_string_callback( HDC hdc, LPARAM param, INT len )
74{
75 const struct gray_string_info *info = (struct gray_string_info *)param;
7e92c9af
AJ
76 WORD args[4];
77 DWORD ret;
78
79 args[3] = HDC_16(hdc);
80 args[2] = HIWORD(info->param);
81 args[1] = LOWORD(info->param);
82 args[0] = len;
83 WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
84 return LOWORD(ret);
45078fb0
AJ
85}
86
87/* callback for 16-bit gray string proc with string pointer */
88static BOOL CALLBACK gray_string_callback_ptr( HDC hdc, LPARAM param, INT len )
89{
90 const struct gray_string_info *info;
91 char *str = (char *)param;
92
93 info = (struct gray_string_info *)(str - offsetof( struct gray_string_info, str ));
7e92c9af
AJ
94 return gray_string_callback( hdc, (LPARAM)info, len );
95}
96
97struct draw_state_info
98{
99 DRAWSTATEPROC16 proc;
100 LPARAM param;
101};
102
103/* callback for 16-bit DrawState functions */
104static BOOL CALLBACK draw_state_callback( HDC hdc, LPARAM lparam, WPARAM wparam, int cx, int cy )
105{
106 const struct draw_state_info *info = (struct draw_state_info *)lparam;
107 WORD args[6];
108 DWORD ret;
109
110 args[5] = HDC_16(hdc);
111 args[4] = HIWORD(info->param);
112 args[3] = LOWORD(info->param);
113 args[2] = wparam;
114 args[1] = cx;
115 args[0] = cy;
116 WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
117 return LOWORD(ret);
45078fb0
AJ
118}
119
57e9244a
AJ
120/* This function is a copy of the one in objects/font.c */
121static void logfont_32_to_16( const LOGFONTA* font32, LPLOGFONT16 font16 )
122{
123 font16->lfHeight = font32->lfHeight;
124 font16->lfWidth = font32->lfWidth;
125 font16->lfEscapement = font32->lfEscapement;
126 font16->lfOrientation = font32->lfOrientation;
127 font16->lfWeight = font32->lfWeight;
128 font16->lfItalic = font32->lfItalic;
129 font16->lfUnderline = font32->lfUnderline;
130 font16->lfStrikeOut = font32->lfStrikeOut;
131 font16->lfCharSet = font32->lfCharSet;
132 font16->lfOutPrecision = font32->lfOutPrecision;
133 font16->lfClipPrecision = font32->lfClipPrecision;
134 font16->lfQuality = font32->lfQuality;
135 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
136 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
137}
3c39a991 138
3806f9ae
AJ
139static int get_bitmap_width_bytes( int width, int bpp )
140{
141 switch(bpp)
142 {
143 case 1:
144 return 2 * ((width+15) / 16);
145 case 4:
146 return 2 * ((width+3) / 4);
147 case 24:
148 width *= 3;
149 /* fall through */
150 case 8:
151 return width + (width & 1);
152 case 16:
153 case 15:
154 return width * 2;
155 case 32:
156 return width * 4;
157 default:
158 WARN("Unknown depth %d, please report.\n", bpp );
159 }
160 return -1;
161}
25d7e0b9
AJ
162
163/***********************************************************************
164 * Helper for wsprintf16
165 */
166
167#define WPRINTF_LEFTALIGN 0x0001 /* Align output on the left ('-' prefix) */
168#define WPRINTF_PREFIX_HEX 0x0002 /* Prefix hex with 0x ('#' prefix) */
169#define WPRINTF_ZEROPAD 0x0004 /* Pad with zeros ('0' prefix) */
170#define WPRINTF_LONG 0x0008 /* Long arg ('l' prefix) */
171#define WPRINTF_SHORT 0x0010 /* Short arg ('h' prefix) */
172#define WPRINTF_UPPER_HEX 0x0020 /* Upper-case hex ('X' specifier) */
173
174typedef enum
175{
176 WPR_UNKNOWN,
177 WPR_CHAR,
178 WPR_STRING,
179 WPR_SIGNED,
180 WPR_UNSIGNED,
181 WPR_HEXA
182} WPRINTF_TYPE;
183
184typedef struct
185{
186 UINT flags;
187 UINT width;
188 UINT precision;
189 WPRINTF_TYPE type;
190} WPRINTF_FORMAT;
191
192static INT parse_format( LPCSTR format, WPRINTF_FORMAT *res )
193{
194 LPCSTR p = format;
195
196 res->flags = 0;
197 res->width = 0;
198 res->precision = 0;
199 if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; }
200 if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; }
201 if (*p == '0') { res->flags |= WPRINTF_ZEROPAD; p++; }
202 while ((*p >= '0') && (*p <= '9')) /* width field */
203 {
204 res->width = res->width * 10 + *p - '0';
205 p++;
206 }
207 if (*p == '.') /* precision field */
208 {
209 p++;
210 while ((*p >= '0') && (*p <= '9'))
211 {
212 res->precision = res->precision * 10 + *p - '0';
213 p++;
214 }
215 }
216 if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; }
217 else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; }
218 switch(*p)
219 {
220 case 'c':
221 case 'C': /* no Unicode in Win16 */
222 res->type = WPR_CHAR;
223 break;
224 case 's':
225 case 'S':
226 res->type = WPR_STRING;
227 break;
228 case 'd':
229 case 'i':
230 res->type = WPR_SIGNED;
231 break;
232 case 'u':
233 res->type = WPR_UNSIGNED;
234 break;
235 case 'p':
236 res->width = 8;
237 res->flags |= WPRINTF_ZEROPAD;
238 /* fall through */
239 case 'X':
240 res->flags |= WPRINTF_UPPER_HEX;
241 /* fall through */
242 case 'x':
243 res->type = WPR_HEXA;
244 break;
245 default: /* unknown format char */
246 res->type = WPR_UNKNOWN;
247 p--; /* print format as normal char */
248 break;
249 }
250 return (INT)(p - format) + 1;
251}
252
253
d5b270ea 254/**********************************************************************
0280f058 255 * Management of the 16-bit cursors and icons
d5b270ea
AJ
256 */
257
258struct cache_entry
259{
260 struct list entry;
261 HINSTANCE16 inst;
262 HRSRC16 rsrc;
263 HRSRC16 group;
264 HICON16 icon;
265 INT count;
266};
267
268static struct list icon_cache = LIST_INIT( icon_cache );
269
e474bfe0
AJ
270static const WORD ICON_HOTSPOT = 0x4242;
271
0280f058
AJ
272static HICON16 alloc_icon_handle( unsigned int size )
273{
f89aaa65
AJ
274 HGLOBAL16 handle = GlobalAlloc16( GMEM_MOVEABLE, size + sizeof(ULONG_PTR) );
275 char *ptr = GlobalLock16( handle );
276 memset( ptr + size, 0, sizeof(ULONG_PTR) );
277 GlobalUnlock16( handle );
0280f058
AJ
278 FarSetOwner16( handle, 0 );
279 return handle;
280}
281
282static CURSORICONINFO *get_icon_ptr( HICON16 handle )
283{
284 return GlobalLock16( handle );
285}
286
287static void release_icon_ptr( HICON16 handle, CURSORICONINFO *ptr )
288{
289 GlobalUnlock16( handle );
290}
291
f89aaa65
AJ
292static HICON store_icon_32( HICON16 icon16, HICON icon )
293{
294 HICON ret = 0;
295 CURSORICONINFO *ptr = get_icon_ptr( icon16 );
296
297 if (ptr)
298 {
299 unsigned int and_size = ptr->nHeight * get_bitmap_width_bytes( ptr->nWidth, 1 );
300 unsigned int xor_size = ptr->nHeight * get_bitmap_width_bytes( ptr->nWidth, ptr->bBitsPerPixel );
301 if (GlobalSize16( icon16 ) >= sizeof(*ptr) + sizeof(ULONG_PTR) + and_size + xor_size )
302 {
303 memcpy( &ret, (char *)(ptr + 1) + and_size + xor_size, sizeof(ret) );
304 memcpy( (char *)(ptr + 1) + and_size + xor_size, &icon, sizeof(icon) );
305 wow_handlers32.set_icon_param( icon, icon16 );
306 }
307 release_icon_ptr( icon16, ptr );
308 }
309 return ret;
310}
311
0280f058
AJ
312static int free_icon_handle( HICON16 handle )
313{
f89aaa65
AJ
314 HICON icon32;
315
316 if ((icon32 = store_icon_32( handle, 0 ))) DestroyIcon( icon32 );
0280f058
AJ
317 return GlobalFree16( handle );
318}
319
f89aaa65 320/* retrieve the 32-bit counterpart of a 16-bit icon, creating it if needed */
8fc1fc49
AJ
321HICON get_icon_32( HICON16 icon16 )
322{
f89aaa65
AJ
323 HICON ret = 0;
324 CURSORICONINFO *ptr = get_icon_ptr( icon16 );
325
326 if (ptr)
327 {
328 unsigned int and_size = ptr->nHeight * get_bitmap_width_bytes( ptr->nWidth, 1 );
329 unsigned int xor_size = ptr->nHeight * get_bitmap_width_bytes( ptr->nWidth, ptr->bBitsPerPixel );
330 if (GlobalSize16( icon16 ) >= sizeof(*ptr) + sizeof(ULONG_PTR) + xor_size + and_size )
331 {
332 memcpy( &ret, (char *)(ptr + 1) + xor_size + and_size, sizeof(ret) );
333 if (!ret)
334 {
335 ICONINFO iinfo;
336
337 iinfo.fIcon = (ptr->ptHotSpot.x == ICON_HOTSPOT) && (ptr->ptHotSpot.y == ICON_HOTSPOT);
338 iinfo.xHotspot = ptr->ptHotSpot.x;
339 iinfo.yHotspot = ptr->ptHotSpot.y;
340 iinfo.hbmMask = CreateBitmap( ptr->nWidth, ptr->nHeight, 1, 1, ptr + 1 );
341 iinfo.hbmColor = CreateBitmap( ptr->nWidth, ptr->nHeight, ptr->bPlanes, ptr->bBitsPerPixel,
342 (char *)(ptr + 1) + and_size );
343 ret = CreateIconIndirect( &iinfo );
344 DeleteObject( iinfo.hbmMask );
345 DeleteObject( iinfo.hbmColor );
346 memcpy( (char *)(ptr + 1) + xor_size + and_size, &ret, sizeof(ret) );
347 wow_handlers32.set_icon_param( ret, icon16 );
348 }
349 }
350 release_icon_ptr( icon16, ptr );
351 }
352 return ret;
8fc1fc49
AJ
353}
354
f89aaa65 355/* retrieve the 16-bit counterpart of a 32-bit icon, creating it if needed */
8fc1fc49
AJ
356HICON16 get_icon_16( HICON icon )
357{
f89aaa65
AJ
358 HICON16 ret = wow_handlers32.get_icon_param( icon );
359
360 if (!ret)
361 {
362 ICONINFO info;
363 BITMAP bm;
364 UINT and_size, xor_size;
365 void *xor_bits = NULL, *and_bits;
366 CURSORICONINFO cinfo;
367
368 if (!(GetIconInfo( icon, &info ))) return 0;
369 GetObjectW( info.hbmMask, sizeof(bm), &bm );
370 and_size = bm.bmHeight * bm.bmWidthBytes;
371 if (!(and_bits = HeapAlloc( GetProcessHeap(), 0, and_size ))) goto done;
372 GetBitmapBits( info.hbmMask, and_size, and_bits );
373 if (info.hbmColor)
374 {
375 GetObjectW( info.hbmColor, sizeof(bm), &bm );
376 xor_size = bm.bmHeight * bm.bmWidthBytes;
377 if (!(xor_bits = HeapAlloc( GetProcessHeap(), 0, xor_size ))) goto done;
378 GetBitmapBits( info.hbmColor, xor_size, xor_bits );
379 }
380 else
381 {
382 bm.bmHeight /= 2;
383 xor_bits = (char *)and_bits + and_size / 2;
384 }
385 if (!info.fIcon)
386 {
387 cinfo.ptHotSpot.x = info.xHotspot;
388 cinfo.ptHotSpot.y = info.yHotspot;
389 }
390 else cinfo.ptHotSpot.x = cinfo.ptHotSpot.y = ICON_HOTSPOT;
391
392 cinfo.nWidth = bm.bmWidth;
393 cinfo.nHeight = bm.bmHeight;
394 cinfo.nWidthBytes = bm.bmWidthBytes;
395 cinfo.bPlanes = bm.bmPlanes;
396 cinfo.bBitsPerPixel = bm.bmBitsPixel;
397
398 if ((ret = CreateCursorIconIndirect16( 0, &cinfo, and_bits, xor_bits )))
399 store_icon_32( ret, icon );
400
401 done:
402 if (info.hbmColor)
403 {
404 HeapFree( GetProcessHeap(), 0, xor_bits );
405 DeleteObject( info.hbmColor );
406 }
407 HeapFree( GetProcessHeap(), 0, and_bits );
408 DeleteObject( info.hbmMask );
409 }
410 return ret;
8fc1fc49
AJ
411}
412
d5b270ea
AJ
413static void add_shared_icon( HINSTANCE16 inst, HRSRC16 rsrc, HRSRC16 group, HICON16 icon )
414{
415 struct cache_entry *cache = HeapAlloc( GetProcessHeap(), 0, sizeof(*cache) );
416
417 if (!cache) return;
418 cache->inst = inst;
419 cache->rsrc = rsrc;
420 cache->group = group;
421 cache->icon = icon;
422 cache->count = 1;
423 list_add_tail( &icon_cache, &cache->entry );
424}
425
426static HICON16 find_shared_icon( HINSTANCE16 inst, HRSRC16 rsrc )
427{
428 struct cache_entry *cache;
429
430 LIST_FOR_EACH_ENTRY( cache, &icon_cache, struct cache_entry, entry )
431 {
432 if (cache->inst != inst || cache->rsrc != rsrc) continue;
433 cache->count++;
434 return cache->icon;
435 }
436 return 0;
437}
438
439static int release_shared_icon( HICON16 icon )
440{
441 struct cache_entry *cache;
442
443 LIST_FOR_EACH_ENTRY( cache, &icon_cache, struct cache_entry, entry )
444 {
445 if (cache->icon != icon) continue;
446 if (!cache->count) return 0;
447 return --cache->count;
448 }
449 return -1;
450}
451
e3bcc11b
AJ
452static void free_module_icons( HINSTANCE16 inst )
453{
454 struct cache_entry *cache, *next;
455
456 LIST_FOR_EACH_ENTRY_SAFE( cache, next, &icon_cache, struct cache_entry, entry )
457 {
458 if (cache->inst != inst) continue;
459 list_remove( &cache->entry );
0280f058 460 free_icon_handle( cache->icon );
e3bcc11b
AJ
461 HeapFree( GetProcessHeap(), 0, cache );
462 }
463}
464
3313c40b
AJ
465/**********************************************************************
466 * Management of the 16-bit clipboard formats
467 */
468
469struct clipboard_format
470{
471 struct list entry;
472 UINT format;
473 HANDLE16 data;
474};
475
476static struct list clipboard_formats = LIST_INIT( clipboard_formats );
477
478static void set_clipboard_format( UINT format, HANDLE16 data )
479{
480 struct clipboard_format *fmt;
481
482 /* replace it if it exists already */
483 LIST_FOR_EACH_ENTRY( fmt, &clipboard_formats, struct clipboard_format, entry )
484 {
485 if (fmt->format != format) continue;
486 GlobalFree16( fmt->data );
487 fmt->data = data;
488 return;
489 }
490
491 if ((fmt = HeapAlloc( GetProcessHeap(), 0, sizeof(*fmt) )))
492 {
493 fmt->format = format;
494 fmt->data = data;
495 list_add_tail( &clipboard_formats, &fmt->entry );
496 }
497}
498
499static void free_clipboard_formats(void)
500{
501 struct list *head;
502
503 while ((head = list_head( &clipboard_formats )))
504 {
505 struct clipboard_format *fmt = LIST_ENTRY( head, struct clipboard_format, entry );
506 list_remove( &fmt->entry );
507 GlobalFree16( fmt->data );
508 HeapFree( GetProcessHeap(), 0, fmt );
509 }
510}
d5b270ea 511
9ceda483 512
d646c7ed
AJ
513/**********************************************************************
514 * InitApp (USER.5)
515 */
516INT16 WINAPI InitApp16( HINSTANCE16 hInstance )
517{
518 /* Create task message queue */
519 return (InitThreadInput16( 0, 0 ) != 0);
520}
521
522
523/***********************************************************************
524 * ExitWindows (USER.7)
525 */
526BOOL16 WINAPI ExitWindows16( DWORD dwReturnCode, UINT16 wReserved )
527{
528 return ExitWindowsEx( EWX_LOGOFF, 0xffffffff );
529}
530
531
0844afc3
AJ
532/***********************************************************************
533 * GetTimerResolution (USER.14)
534 */
535LONG WINAPI GetTimerResolution16(void)
536{
537 return (1000);
538}
539
540
3c39a991
AJ
541/***********************************************************************
542 * ClipCursor (USER.16)
543 */
544BOOL16 WINAPI ClipCursor16( const RECT16 *rect )
545{
546 RECT rect32;
547
548 if (!rect) return ClipCursor( NULL );
549 rect32.left = rect->left;
550 rect32.top = rect->top;
551 rect32.right = rect->right;
552 rect32.bottom = rect->bottom;
553 return ClipCursor( &rect32 );
554}
555
556
d646c7ed
AJ
557/***********************************************************************
558 * GetCursorPos (USER.17)
559 */
560BOOL16 WINAPI GetCursorPos16( POINT16 *pt )
561{
562 POINT pos;
563 if (!pt) return 0;
564 GetCursorPos(&pos);
565 pt->x = pos.x;
566 pt->y = pos.y;
567 return 1;
568}
569
570
15000f32
AJ
571/*******************************************************************
572 * AnyPopup (USER.52)
573 */
574BOOL16 WINAPI AnyPopup16(void)
575{
576 return AnyPopup();
577}
578
579
2d0acacb
MS
580/***********************************************************************
581 * SetCursor (USER.69)
582 */
583HCURSOR16 WINAPI SetCursor16(HCURSOR16 hCursor)
584{
8fc1fc49 585 return get_icon_16( SetCursor( get_icon_32(hCursor) ));
2d0acacb
MS
586}
587
d646c7ed
AJ
588
589/***********************************************************************
590 * SetCursorPos (USER.70)
591 */
592void WINAPI SetCursorPos16( INT16 x, INT16 y )
593{
594 SetCursorPos( x, y );
595}
596
597
2d0acacb
MS
598/***********************************************************************
599 * ShowCursor (USER.71)
600 */
601INT16 WINAPI ShowCursor16(BOOL16 bShow)
602{
603 return ShowCursor(bShow);
604}
605
c1585509 606
6de70abd
AJ
607/***********************************************************************
608 * SetRect (USER.72)
609 */
610void WINAPI SetRect16( LPRECT16 rect, INT16 left, INT16 top, INT16 right, INT16 bottom )
611{
612 rect->left = left;
613 rect->right = right;
614 rect->top = top;
615 rect->bottom = bottom;
616}
617
618
619/***********************************************************************
620 * SetRectEmpty (USER.73)
621 */
622void WINAPI SetRectEmpty16( LPRECT16 rect )
623{
624 rect->left = rect->right = rect->top = rect->bottom = 0;
625}
626
627
628/***********************************************************************
629 * CopyRect (USER.74)
630 */
631BOOL16 WINAPI CopyRect16( RECT16 *dest, const RECT16 *src )
632{
633 *dest = *src;
634 return TRUE;
635}
636
637
638/***********************************************************************
639 * IsRectEmpty (USER.75)
640 *
641 * Bug compat: Windows checks for 0 or negative width/height.
642 */
643BOOL16 WINAPI IsRectEmpty16( const RECT16 *rect )
644{
645 return ((rect->left >= rect->right) || (rect->top >= rect->bottom));
646}
647
648
649/***********************************************************************
650 * PtInRect (USER.76)
651 */
652BOOL16 WINAPI PtInRect16( const RECT16 *rect, POINT16 pt )
653{
654 return ((pt.x >= rect->left) && (pt.x < rect->right) &&
655 (pt.y >= rect->top) && (pt.y < rect->bottom));
656}
657
658
659/***********************************************************************
660 * OffsetRect (USER.77)
661 */
662void WINAPI OffsetRect16( LPRECT16 rect, INT16 x, INT16 y )
663{
664 rect->left += x;
665 rect->right += x;
666 rect->top += y;
667 rect->bottom += y;
668}
669
670
671/***********************************************************************
672 * InflateRect (USER.78)
673 */
674void WINAPI InflateRect16( LPRECT16 rect, INT16 x, INT16 y )
675{
676 rect->left -= x;
677 rect->top -= y;
678 rect->right += x;
679 rect->bottom += y;
680}
681
682
683/***********************************************************************
684 * IntersectRect (USER.79)
685 */
686BOOL16 WINAPI IntersectRect16( LPRECT16 dest, const RECT16 *src1,
687 const RECT16 *src2 )
688{
689 if (IsRectEmpty16(src1) || IsRectEmpty16(src2) ||
690 (src1->left >= src2->right) || (src2->left >= src1->right) ||
691 (src1->top >= src2->bottom) || (src2->top >= src1->bottom))
692 {
693 SetRectEmpty16( dest );
694 return FALSE;
695 }
696 dest->left = max( src1->left, src2->left );
697 dest->right = min( src1->right, src2->right );
698 dest->top = max( src1->top, src2->top );
699 dest->bottom = min( src1->bottom, src2->bottom );
700 return TRUE;
701}
702
703
704/***********************************************************************
705 * UnionRect (USER.80)
706 */
707BOOL16 WINAPI UnionRect16( LPRECT16 dest, const RECT16 *src1,
708 const RECT16 *src2 )
709{
710 if (IsRectEmpty16(src1))
711 {
712 if (IsRectEmpty16(src2))
713 {
714 SetRectEmpty16( dest );
715 return FALSE;
716 }
717 else *dest = *src2;
718 }
719 else
720 {
721 if (IsRectEmpty16(src2)) *dest = *src1;
722 else
723 {
724 dest->left = min( src1->left, src2->left );
725 dest->right = max( src1->right, src2->right );
726 dest->top = min( src1->top, src2->top );
727 dest->bottom = max( src1->bottom, src2->bottom );
728 }
729 }
730 return TRUE;
731}
732
733
c1585509
AJ
734/***********************************************************************
735 * FillRect (USER.81)
736 * NOTE
737 * The Win16 variant doesn't support special color brushes like
738 * the Win32 one, despite the fact that Win16, as well as Win32,
739 * supports special background brushes for a window class.
740 */
741INT16 WINAPI FillRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
742{
743 HBRUSH prevBrush;
744
745 /* coordinates are logical so we cannot fast-check 'rect',
746 * it will be done later in the PatBlt().
747 */
748
749 if (!(prevBrush = SelectObject( HDC_32(hdc), HBRUSH_32(hbrush) ))) return 0;
750 PatBlt( HDC_32(hdc), rect->left, rect->top,
751 rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
752 SelectObject( HDC_32(hdc), prevBrush );
753 return 1;
754}
755
756
757/***********************************************************************
758 * InvertRect (USER.82)
759 */
760void WINAPI InvertRect16( HDC16 hdc, const RECT16 *rect )
761{
762 PatBlt( HDC_32(hdc), rect->left, rect->top,
763 rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
764}
765
766
767/***********************************************************************
768 * FrameRect (USER.83)
769 */
770INT16 WINAPI FrameRect16( HDC16 hdc, const RECT16 *rect16, HBRUSH16 hbrush )
771{
772 RECT rect;
3c39a991
AJ
773
774 rect.left = rect16->left;
775 rect.top = rect16->top;
776 rect.right = rect16->right;
777 rect.bottom = rect16->bottom;
c1585509
AJ
778 return FrameRect( HDC_32(hdc), &rect, HBRUSH_32(hbrush) );
779}
780
781
2d0acacb
MS
782/***********************************************************************
783 * DrawIcon (USER.84)
784 */
785BOOL16 WINAPI DrawIcon16(HDC16 hdc, INT16 x, INT16 y, HICON16 hIcon)
786{
8fc1fc49 787 return DrawIcon(HDC_32(hdc), x, y, get_icon_32(hIcon) );
2d0acacb
MS
788}
789
7ef66af3
AJ
790
791/***********************************************************************
792 * DrawText (USER.85)
793 */
794INT16 WINAPI DrawText16( HDC16 hdc, LPCSTR str, INT16 count, LPRECT16 rect, UINT16 flags )
795{
796 INT16 ret;
797
798 if (rect)
799 {
800 RECT rect32;
3c39a991
AJ
801
802 rect32.left = rect->left;
803 rect32.top = rect->top;
804 rect32.right = rect->right;
805 rect32.bottom = rect->bottom;
7ef66af3 806 ret = DrawTextA( HDC_32(hdc), str, count, &rect32, flags );
3c39a991
AJ
807 rect->left = rect32.left;
808 rect->top = rect32.top;
809 rect->right = rect32.right;
810 rect->bottom = rect32.bottom;
7ef66af3 811 }
45078fb0 812 else ret = DrawTextA( HDC_32(hdc), str, count, NULL, flags);
7ef66af3
AJ
813 return ret;
814}
815
816
2d0acacb
MS
817/***********************************************************************
818 * IconSize (USER.86)
819 *
820 * See "Undocumented Windows". Used by W2.0 paint.exe.
821 */
822DWORD WINAPI IconSize16(void)
823{
824 return MAKELONG(GetSystemMetrics(SM_CYICON), GetSystemMetrics(SM_CXICON));
825}
826
7ef66af3 827
3c39a991
AJ
828/***********************************************************************
829 * AdjustWindowRect (USER.102)
830 */
831BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
832{
833 return AdjustWindowRectEx16( rect, style, menu, 0 );
834}
835
836
6c8e3a85
AJ
837/***********************************************************************
838 * MessageBeep (USER.104)
839 */
840void WINAPI MessageBeep16( UINT16 i )
841{
842 MessageBeep( i );
843}
844
845
d646c7ed
AJ
846/**************************************************************************
847 * CloseClipboard (USER.138)
848 */
849BOOL16 WINAPI CloseClipboard16(void)
850{
3313c40b
AJ
851 BOOL ret = CloseClipboard();
852 if (ret) free_clipboard_formats();
853 return ret;
d646c7ed
AJ
854}
855
856
857/**************************************************************************
858 * EmptyClipboard (USER.139)
859 */
860BOOL16 WINAPI EmptyClipboard16(void)
861{
3313c40b
AJ
862 BOOL ret = EmptyClipboard();
863 if (ret) free_clipboard_formats();
864 return ret;
865}
866
867
868/**************************************************************************
869 * SetClipboardData (USER.141)
870 */
871HANDLE16 WINAPI SetClipboardData16( UINT16 format, HANDLE16 data16 )
872{
873 HANDLE data32 = 0;
874
875 switch (format)
876 {
877 case CF_BITMAP:
878 case CF_PALETTE:
879 data32 = HGDIOBJ_32( data16 );
880 break;
881
882 case CF_METAFILEPICT:
883 {
884 METAHEADER *header;
885 METAFILEPICT *pict32;
886 METAFILEPICT16 *pict16 = GlobalLock16( data16 );
887
888 if (pict16)
889 {
890 if (!(data32 = GlobalAlloc( GMEM_MOVEABLE, sizeof(*pict32) ))) return 0;
891 pict32 = GlobalLock( data32 );
892 pict32->mm = pict16->mm;
893 pict32->xExt = pict16->xExt;
894 pict32->yExt = pict16->yExt;
895 header = GlobalLock16( pict16->hMF );
896 pict32->hMF = SetMetaFileBitsEx( header->mtSize * 2, (BYTE *)header );
897 GlobalUnlock16( pict16->hMF );
898 GlobalUnlock( data32 );
899 }
900 set_clipboard_format( format, data16 );
901 break;
902 }
903
904 case CF_ENHMETAFILE:
905 FIXME( "enhmetafile not supported in 16-bit\n" );
906 return 0;
907
908 default:
909 if (format >= CF_GDIOBJFIRST && format <= CF_GDIOBJLAST)
910 data32 = HGDIOBJ_32( data16 );
911 else if (format >= CF_PRIVATEFIRST && format <= CF_PRIVATELAST)
912 data32 = HANDLE_32( data16 );
913 else
914 {
915 UINT size = GlobalSize16( data16 );
916 void *ptr32, *ptr16 = GlobalLock16( data16 );
917 if (ptr16)
918 {
919 if (!(data32 = GlobalAlloc( GMEM_MOVEABLE, size ))) return 0;
920 ptr32 = GlobalLock( data32 );
921 memcpy( ptr32, ptr16, size );
922 GlobalUnlock( data32 );
923 }
924 set_clipboard_format( format, data16 );
925 }
926 break;
927 }
928
929 if (!SetClipboardData( format, data32 )) return 0;
930 return data16;
931}
932
933
934/**************************************************************************
935 * GetClipboardData (USER.142)
936 */
937HANDLE16 WINAPI GetClipboardData16( UINT16 format )
938{
939 HANDLE data32 = GetClipboardData( format );
940 HANDLE16 data16 = 0;
941 UINT size;
942 void *ptr;
943
944 if (!data32) return 0;
945
946 switch (format)
947 {
948 case CF_BITMAP:
949 case CF_PALETTE:
950 data16 = HGDIOBJ_16( data32 );
951 break;
952
953 case CF_METAFILEPICT:
954 {
955 METAFILEPICT16 *pict16;
956 METAFILEPICT *pict32 = GlobalLock( data32 );
957
958 if (pict32)
959 {
960 if (!(data16 = GlobalAlloc16( GMEM_MOVEABLE, sizeof(*pict16) ))) return 0;
961 pict16 = GlobalLock16( data16 );
962 pict16->mm = pict32->mm;
963 pict16->xExt = pict32->xExt;
964 pict16->yExt = pict32->yExt;
965 size = GetMetaFileBitsEx( pict32->hMF, 0, NULL );
966 pict16->hMF = GlobalAlloc16( GMEM_MOVEABLE, size );
967 ptr = GlobalLock16( pict16->hMF );
968 GetMetaFileBitsEx( pict32->hMF, size, ptr );
969 GlobalUnlock16( pict16->hMF );
970 GlobalUnlock16( data16 );
971 set_clipboard_format( format, data16 );
972 }
973 break;
974 }
975
976 case CF_ENHMETAFILE:
977 FIXME( "enhmetafile not supported in 16-bit\n" );
978 return 0;
979
980 default:
981 if (format >= CF_GDIOBJFIRST && format <= CF_GDIOBJLAST)
982 data16 = HGDIOBJ_16( data32 );
983 else if (format >= CF_PRIVATEFIRST && format <= CF_PRIVATELAST)
984 data16 = HANDLE_16( data32 );
985 else
986 {
987 void *ptr16, *ptr32 = GlobalLock( data32 );
988 if (ptr32)
989 {
990 size = GlobalSize( data32 );
991 if (!(data16 = GlobalAlloc16( GMEM_MOVEABLE, size ))) return 0;
992 ptr16 = GlobalLock16( data16 );
993 memcpy( ptr16, ptr32, size );
994 GlobalUnlock16( data16 );
995 set_clipboard_format( format, data16 );
996 }
997 }
998 break;
999 }
1000 return data16;
d646c7ed
AJ
1001}
1002
1003
1004/**************************************************************************
1005 * CountClipboardFormats (USER.143)
1006 */
1007INT16 WINAPI CountClipboardFormats16(void)
1008{
1009 return CountClipboardFormats();
1010}
1011
1012
1013/**************************************************************************
1014 * EnumClipboardFormats (USER.144)
1015 */
1016UINT16 WINAPI EnumClipboardFormats16( UINT16 id )
1017{
1018 return EnumClipboardFormats( id );
1019}
1020
1021
1022/**************************************************************************
1023 * RegisterClipboardFormat (USER.145)
1024 */
1025UINT16 WINAPI RegisterClipboardFormat16( LPCSTR name )
1026{
1027 return RegisterClipboardFormatA( name );
1028}
1029
1030
1031/**************************************************************************
1032 * GetClipboardFormatName (USER.146)
1033 */
1034INT16 WINAPI GetClipboardFormatName16( UINT16 id, LPSTR buffer, INT16 maxlen )
1035{
1036 return GetClipboardFormatNameA( id, buffer, maxlen );
1037}
1038
1039
15000f32
AJ
1040/**********************************************************************
1041 * LoadMenu (USER.150)
1042 */
1043HMENU16 WINAPI LoadMenu16( HINSTANCE16 instance, LPCSTR name )
1044{
1045 HRSRC16 hRsrc;
1046 HGLOBAL16 handle;
1047 HMENU16 hMenu;
1048
1049 if (HIWORD(name) && name[0] == '#') name = ULongToPtr(atoi( name + 1 ));
1050 if (!name) return 0;
1051
1052 instance = GetExePtr( instance );
1053 if (!(hRsrc = FindResource16( instance, name, (LPSTR)RT_MENU ))) return 0;
1054 if (!(handle = LoadResource16( instance, hRsrc ))) return 0;
1055 hMenu = LoadMenuIndirect16(LockResource16(handle));
1056 FreeResource16( handle );
1057 return hMenu;
1058}
1059
1060
7ef66af3
AJ
1061/**********************************************************************
1062 * CreateMenu (USER.151)
1063 */
1064HMENU16 WINAPI CreateMenu16(void)
1065{
1066 return HMENU_16( CreateMenu() );
1067}
1068
1069
1070/**********************************************************************
1071 * DestroyMenu (USER.152)
1072 */
1073BOOL16 WINAPI DestroyMenu16( HMENU16 hMenu )
1074{
1075 return DestroyMenu( HMENU_32(hMenu) );
1076}
1077
1078
1079/*******************************************************************
1080 * ChangeMenu (USER.153)
1081 */
1082BOOL16 WINAPI ChangeMenu16( HMENU16 hMenu, UINT16 pos, SEGPTR data,
1083 UINT16 id, UINT16 flags )
1084{
1085 if (flags & MF_APPEND) return AppendMenu16( hMenu, flags & ~MF_APPEND, id, data );
1086
1087 /* FIXME: Word passes the item id in 'pos' and 0 or 0xffff as id */
1088 /* for MF_DELETE. We should check the parameters for all others */
1089 /* MF_* actions also (anybody got a doc on ChangeMenu?). */
1090
1091 if (flags & MF_DELETE) return DeleteMenu16(hMenu, pos, flags & ~MF_DELETE);
1092 if (flags & MF_CHANGE) return ModifyMenu16(hMenu, pos, flags & ~MF_CHANGE, id, data );
1093 if (flags & MF_REMOVE) return RemoveMenu16(hMenu, flags & MF_BYPOSITION ? pos : id,
1094 flags & ~MF_REMOVE );
1095 /* Default: MF_INSERT */
1096 return InsertMenu16( hMenu, pos, flags, id, data );
1097}
1098
1099
1100/*******************************************************************
1101 * CheckMenuItem (USER.154)
1102 */
1103BOOL16 WINAPI CheckMenuItem16( HMENU16 hMenu, UINT16 id, UINT16 flags )
1104{
1105 return CheckMenuItem( HMENU_32(hMenu), id, flags );
1106}
1107
1108
1109/**********************************************************************
1110 * EnableMenuItem (USER.155)
1111 */
b7652d89 1112BOOL16 WINAPI EnableMenuItem16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
7ef66af3
AJ
1113{
1114 return EnableMenuItem( HMENU_32(hMenu), wItemID, wFlags );
1115}
1116
1117
1118/**********************************************************************
1119 * GetSubMenu (USER.159)
1120 */
1121HMENU16 WINAPI GetSubMenu16( HMENU16 hMenu, INT16 nPos )
1122{
1123 return HMENU_16( GetSubMenu( HMENU_32(hMenu), nPos ) );
1124}
1125
1126
1127/*******************************************************************
1128 * GetMenuString (USER.161)
1129 */
1130INT16 WINAPI GetMenuString16( HMENU16 hMenu, UINT16 wItemID,
1131 LPSTR str, INT16 nMaxSiz, UINT16 wFlags )
1132{
1133 return GetMenuStringA( HMENU_32(hMenu), wItemID, str, nMaxSiz, wFlags );
1134}
1135
1136
1137/**********************************************************************
1138 * WinHelp (USER.171)
1139 */
1140BOOL16 WINAPI WinHelp16( HWND16 hWnd, LPCSTR lpHelpFile, UINT16 wCommand,
1141 DWORD dwData )
1142{
1143 BOOL ret;
1144 DWORD mutex_count;
1145
1146 /* We might call WinExec() */
1147 ReleaseThunkLock(&mutex_count);
1148
1149 ret = WinHelpA(WIN_Handle32(hWnd), lpHelpFile, wCommand, (DWORD)MapSL(dwData));
1150
1151 RestoreThunkLock(mutex_count);
1152 return ret;
1153}
1154
1155
2d0acacb
MS
1156/***********************************************************************
1157 * LoadCursor (USER.173)
1158 */
1159HCURSOR16 WINAPI LoadCursor16(HINSTANCE16 hInstance, LPCSTR name)
1160{
d5b270ea 1161 return LoadImage16( hInstance, name, IMAGE_CURSOR, 0, 0, LR_SHARED | LR_DEFAULTSIZE );
2d0acacb
MS
1162}
1163
1164
1165/***********************************************************************
1166 * LoadIcon (USER.174)
1167 */
1168HICON16 WINAPI LoadIcon16(HINSTANCE16 hInstance, LPCSTR name)
1169{
d5b270ea 1170 return LoadImage16( hInstance, name, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE );
2d0acacb
MS
1171}
1172
1173/**********************************************************************
1174 * LoadBitmap (USER.175)
1175 */
1176HBITMAP16 WINAPI LoadBitmap16(HINSTANCE16 hInstance, LPCSTR name)
1177{
2ced4102 1178 return LoadImage16( hInstance, name, IMAGE_BITMAP, 0, 0, 0 );
2d0acacb
MS
1179}
1180
09d1c52f
AJ
1181/**********************************************************************
1182 * LoadString (USER.176)
1183 */
1184INT16 WINAPI LoadString16( HINSTANCE16 instance, UINT16 resource_id, LPSTR buffer, INT16 buflen )
1185{
1186 HGLOBAL16 hmem;
1187 HRSRC16 hrsrc;
1188 unsigned char *p;
1189 int string_num;
1190 int ret;
1191
1192 TRACE("inst=%04x id=%04x buff=%p len=%d\n", instance, resource_id, buffer, buflen);
1193
1194 hrsrc = FindResource16( instance, MAKEINTRESOURCEA((resource_id>>4)+1), (LPSTR)RT_STRING );
1195 if (!hrsrc) return 0;
1196 hmem = LoadResource16( instance, hrsrc );
1197 if (!hmem) return 0;
1198
1199 p = LockResource16(hmem);
1200 string_num = resource_id & 0x000f;
1201 while (string_num--) p += *p + 1;
1202
1203 if (buffer == NULL) ret = *p;
1204 else
1205 {
1206 ret = min(buflen - 1, *p);
1207 if (ret > 0)
1208 {
1209 memcpy(buffer, p + 1, ret);
1210 buffer[ret] = '\0';
1211 }
1212 else if (buflen > 1)
1213 {
1214 buffer[0] = '\0';
1215 ret = 0;
1216 }
1217 TRACE( "%s loaded\n", debugstr_a(buffer));
1218 }
1219 FreeResource16( hmem );
1220 return ret;
1221}
1222
1223/**********************************************************************
1224 * LoadAccelerators (USER.177)
1225 */
1226HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, LPCSTR lpTableName)
1227{
1228 HRSRC16 hRsrc;
1229 HGLOBAL16 hMem;
1230 ACCEL16 *table16;
1231 HACCEL ret = 0;
1232
1233 TRACE("%04x %s\n", instance, debugstr_a(lpTableName) );
1234
1235 if (!(hRsrc = FindResource16( instance, lpTableName, (LPSTR)RT_ACCELERATOR )) ||
1236 !(hMem = LoadResource16(instance,hRsrc)))
1237 {
1238 WARN("couldn't find %04x %s\n", instance, debugstr_a(lpTableName));
1239 return 0;
1240 }
1241 if ((table16 = LockResource16( hMem )))
1242 {
1243 DWORD i, count = SizeofResource16( instance, hRsrc ) / sizeof(*table16);
1244 ACCEL *table = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*table) );
1245 if (table)
1246 {
1247 for (i = 0; i < count; i++)
1248 {
1249 table[i].fVirt = table16[i].fVirt & 0x7f;
1250 table[i].key = table16[i].key;
1251 table[i].cmd = table16[i].cmd;
1252 }
1253 ret = CreateAcceleratorTableA( table, count );
1254 HeapFree( GetProcessHeap(), 0, table );
1255 }
1256 }
1257 FreeResource16( hMem );
1258 return HACCEL_16(ret);
1259}
45078fb0 1260
d646c7ed
AJ
1261/***********************************************************************
1262 * GetSystemMetrics (USER.179)
1263 */
1264INT16 WINAPI GetSystemMetrics16( INT16 index )
1265{
1266 return GetSystemMetrics( index );
1267}
1268
1269
1270/*************************************************************************
1271 * GetSysColor (USER.180)
1272 */
1273COLORREF WINAPI GetSysColor16( INT16 index )
1274{
1275 return GetSysColor( index );
1276}
1277
1278
1279/*************************************************************************
1280 * SetSysColors (USER.181)
1281 */
1282VOID WINAPI SetSysColors16( INT16 count, const INT16 *list16, const COLORREF *values )
1283{
1284 INT i, *list;
1285
1286 if ((list = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*list) )))
1287 {
1288 for (i = 0; i < count; i++) list[i] = list16[i];
1289 SetSysColors( count, list, values );
1290 HeapFree( GetProcessHeap(), 0, list );
1291 }
1292}
1293
1294
45078fb0
AJ
1295/***********************************************************************
1296 * GrayString (USER.185)
1297 */
1298BOOL16 WINAPI GrayString16( HDC16 hdc, HBRUSH16 hbr, GRAYSTRINGPROC16 gsprc,
1299 LPARAM lParam, INT16 cch, INT16 x, INT16 y,
1300 INT16 cx, INT16 cy )
1301{
1302 BOOL ret;
1303
1304 if (!gsprc) return GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), NULL,
1305 (LPARAM)MapSL(lParam), cch, x, y, cx, cy );
1306
1307 if (cch == -1 || (cch && cx && cy))
1308 {
1309 /* lParam can be treated as an opaque pointer */
1310 struct gray_string_info info;
1311
1312 info.proc = gsprc;
1313 info.param = lParam;
1314 ret = GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), gray_string_callback,
1315 (LPARAM)&info, cch, x, y, cx, cy );
1316 }
1317 else /* here we need some string conversions */
1318 {
1319 char *str16 = MapSL(lParam);
1320 struct gray_string_info *info;
1321
1322 if (!cch) cch = strlen(str16);
96e428cc
MS
1323 info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( struct gray_string_info, str[cch] ));
1324 if (!info) return FALSE;
45078fb0
AJ
1325 info->proc = gsprc;
1326 info->param = lParam;
1327 memcpy( info->str, str16, cch );
1328 ret = GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), gray_string_callback_ptr,
1329 (LPARAM)info->str, cch, x, y, cx, cy );
1330 HeapFree( GetProcessHeap(), 0, info );
1331 }
1332 return ret;
1333}
1334
1335
6c8e3a85
AJ
1336/***********************************************************************
1337 * SwapMouseButton (USER.186)
1338 */
1339BOOL16 WINAPI SwapMouseButton16( BOOL16 fSwap )
1340{
1341 return SwapMouseButton( fSwap );
1342}
1343
1344
d646c7ed
AJ
1345/**************************************************************************
1346 * IsClipboardFormatAvailable (USER.193)
1347 */
1348BOOL16 WINAPI IsClipboardFormatAvailable16( UINT16 wFormat )
1349{
1350 return IsClipboardFormatAvailable( wFormat );
1351}
1352
1353
45078fb0
AJ
1354/***********************************************************************
1355 * TabbedTextOut (USER.196)
1356 */
1357LONG WINAPI TabbedTextOut16( HDC16 hdc, INT16 x, INT16 y, LPCSTR lpstr,
1358 INT16 count, INT16 nb_tabs, const INT16 *tabs16, INT16 tab_org )
1359{
1360 LONG ret;
90ca3620 1361 INT i, *tabs = HeapAlloc( GetProcessHeap(), 0, nb_tabs * sizeof(*tabs) );
45078fb0
AJ
1362 if (!tabs) return 0;
1363 for (i = 0; i < nb_tabs; i++) tabs[i] = tabs16[i];
1364 ret = TabbedTextOutA( HDC_32(hdc), x, y, lpstr, count, nb_tabs, tabs, tab_org );
1365 HeapFree( GetProcessHeap(), 0, tabs );
1366 return ret;
1367}
1368
1369
1370/***********************************************************************
1371 * GetTabbedTextExtent (USER.197)
1372 */
1373DWORD WINAPI GetTabbedTextExtent16( HDC16 hdc, LPCSTR lpstr, INT16 count,
1374 INT16 nb_tabs, const INT16 *tabs16 )
1375{
1376 LONG ret;
90ca3620 1377 INT i, *tabs = HeapAlloc( GetProcessHeap(), 0, nb_tabs * sizeof(*tabs) );
45078fb0
AJ
1378 if (!tabs) return 0;
1379 for (i = 0; i < nb_tabs; i++) tabs[i] = tabs16[i];
1380 ret = GetTabbedTextExtentA( HDC_32(hdc), lpstr, count, nb_tabs, tabs );
1381 HeapFree( GetProcessHeap(), 0, tabs );
1382 return ret;
1383}
1384
1385
03f6f6f7
AJ
1386/***********************************************************************
1387 * UserSeeUserDo (USER.216)
1388 */
1389DWORD WINAPI UserSeeUserDo16(WORD wReqType, WORD wParam1, WORD wParam2, WORD wParam3)
1390{
1391 STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
1392 HANDLE16 oldDS = stack16->ds;
1393 DWORD ret = (DWORD)-1;
1394
1395 stack16->ds = USER_HeapSel;
1396 switch (wReqType)
1397 {
1398 case USUD_LOCALALLOC:
1399 ret = LocalAlloc16(wParam1, wParam3);
1400 break;
1401 case USUD_LOCALFREE:
1402 ret = LocalFree16(wParam1);
1403 break;
1404 case USUD_LOCALCOMPACT:
1405 ret = LocalCompact16(wParam3);
1406 break;
1407 case USUD_LOCALHEAP:
1408 ret = USER_HeapSel;
1409 break;
1410 case USUD_FIRSTCLASS:
1411 FIXME("return a pointer to the first window class.\n");
1412 break;
1413 default:
1414 WARN("wReqType %04x (unknown)\n", wReqType);
1415 }
1416 stack16->ds = oldDS;
1417 return ret;
1418}
1419
1420
15000f32
AJ
1421/***********************************************************************
1422 * LookupMenuHandle (USER.217)
1423 */
1424HMENU16 WINAPI LookupMenuHandle16( HMENU16 hmenu, INT16 id )
1425{
1426 FIXME( "%04x %04x: stub\n", hmenu, id );
1427 return hmenu;
1428}
1429
1430
1431static LPCSTR parse_menu_resource( LPCSTR res, HMENU hMenu )
1432{
1433 WORD flags, id = 0;
1434 LPCSTR str;
1435 BOOL end_flag;
1436
1437 do
1438 {
1439 flags = GET_WORD(res);
1440 end_flag = flags & MF_END;
1441 /* Remove MF_END because it has the same value as MF_HILITE */
1442 flags &= ~MF_END;
1443 res += sizeof(WORD);
1444 if (!(flags & MF_POPUP))
1445 {
1446 id = GET_WORD(res);
1447 res += sizeof(WORD);
1448 }
1449 str = res;
1450 res += strlen(str) + 1;
1451 if (flags & MF_POPUP)
1452 {
1453 HMENU hSubMenu = CreatePopupMenu();
1454 if (!hSubMenu) return NULL;
1455 if (!(res = parse_menu_resource( res, hSubMenu ))) return NULL;
1456 AppendMenuA( hMenu, flags, (UINT_PTR)hSubMenu, str );
1457 }
1458 else /* Not a popup */
1459 {
1460 AppendMenuA( hMenu, flags, id, *str ? str : NULL );
1461 }
1462 } while (!end_flag);
1463 return res;
1464}
1465
1466/**********************************************************************
1467 * LoadMenuIndirect (USER.220)
1468 */
1469HMENU16 WINAPI LoadMenuIndirect16( LPCVOID template )
1470{
1471 HMENU hMenu;
1472 WORD version, offset;
1473 LPCSTR p = template;
1474
1475 TRACE("(%p)\n", template );
1476 version = GET_WORD(p);
1477 p += sizeof(WORD);
1478 if (version)
1479 {
1480 WARN("version must be 0 for Win16\n" );
1481 return 0;
1482 }
1483 offset = GET_WORD(p);
1484 p += sizeof(WORD) + offset;
1485 if (!(hMenu = CreateMenu())) return 0;
1486 if (!parse_menu_resource( p, hMenu ))
1487 {
1488 DestroyMenu( hMenu );
1489 return 0;
1490 }
1491 return HMENU_16(hMenu);
1492}
1493
1494
ec5612ee
MS
1495/*************************************************************************
1496 * ScrollDC (USER.221)
1497 */
1498BOOL16 WINAPI ScrollDC16( HDC16 hdc, INT16 dx, INT16 dy, const RECT16 *rect,
1499 const RECT16 *cliprc, HRGN16 hrgnUpdate,
1500 LPRECT16 rcUpdate )
1501{
1502 RECT rect32, clipRect32, rcUpdate32;
1503 BOOL16 ret;
1504
3c39a991
AJ
1505 if (rect)
1506 {
1507 rect32.left = rect->left;
1508 rect32.top = rect->top;
1509 rect32.right = rect->right;
1510 rect32.bottom = rect->bottom;
1511 }
1512 if (cliprc)
1513 {
1514 clipRect32.left = cliprc->left;
1515 clipRect32.top = cliprc->top;
1516 clipRect32.right = cliprc->right;
1517 clipRect32.bottom = cliprc->bottom;
1518 }
ec5612ee
MS
1519 ret = ScrollDC( HDC_32(hdc), dx, dy, rect ? &rect32 : NULL,
1520 cliprc ? &clipRect32 : NULL, HRGN_32(hrgnUpdate),
1521 &rcUpdate32 );
3c39a991
AJ
1522 if (rcUpdate)
1523 {
1524 rcUpdate->left = rcUpdate32.left;
1525 rcUpdate->top = rcUpdate32.top;
1526 rcUpdate->right = rcUpdate32.right;
1527 rcUpdate->bottom = rcUpdate32.bottom;
1528 }
ec5612ee
MS
1529 return ret;
1530}
1531
d646c7ed
AJ
1532
1533/***********************************************************************
1534 * GetSystemDebugState (USER.231)
1535 */
1536WORD WINAPI GetSystemDebugState16(void)
1537{
1538 return 0; /* FIXME */
1539}
1540
1541
6de70abd
AJ
1542/***********************************************************************
1543 * EqualRect (USER.244)
1544 */
1545BOOL16 WINAPI EqualRect16( const RECT16* rect1, const RECT16* rect2 )
1546{
1547 return ((rect1->left == rect2->left) && (rect1->right == rect2->right) &&
1548 (rect1->top == rect2->top) && (rect1->bottom == rect2->bottom));
1549}
1550
1551
d646c7ed
AJ
1552/***********************************************************************
1553 * ExitWindowsExec (USER.246)
1554 */
1555BOOL16 WINAPI ExitWindowsExec16( LPCSTR lpszExe, LPCSTR lpszParams )
1556{
1557 TRACE("Should run the following in DOS-mode: \"%s %s\"\n",
1558 lpszExe, lpszParams);
1559 return ExitWindowsEx( EWX_LOGOFF, 0xffffffff );
1560}
1561
1562
2d0acacb
MS
1563/***********************************************************************
1564 * GetCursor (USER.247)
1565 */
1566HCURSOR16 WINAPI GetCursor16(void)
1567{
8fc1fc49 1568 return get_icon_16( GetCursor() );
2d0acacb
MS
1569}
1570
7ef66af3 1571
d646c7ed
AJ
1572/**********************************************************************
1573 * GetAsyncKeyState (USER.249)
1574 */
1575INT16 WINAPI GetAsyncKeyState16( INT16 key )
1576{
1577 return GetAsyncKeyState( key );
1578}
1579
1580
7ef66af3
AJ
1581/**********************************************************************
1582 * GetMenuState (USER.250)
1583 */
1584UINT16 WINAPI GetMenuState16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
1585{
1586 return GetMenuState( HMENU_32(hMenu), wItemID, wFlags );
1587}
1588
1589
2a64c6b1
AJ
1590/**************************************************************************
1591 * SendDriverMessage (USER.251)
1592 */
1593LRESULT WINAPI SendDriverMessage16(HDRVR16 hDriver, UINT16 msg, LPARAM lParam1,
1594 LPARAM lParam2)
1595{
1596 FIXME("(%04x, %04x, %08lx, %08lx): stub\n", hDriver, msg, lParam1, lParam2);
1597 return 0;
1598}
1599
1600
1601/**************************************************************************
1602 * OpenDriver (USER.252)
1603 */
1604HDRVR16 WINAPI OpenDriver16(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam2)
1605{
1606 FIXME( "(%s, %s, %08lx): stub\n", debugstr_a(lpDriverName), debugstr_a(lpSectionName), lParam2);
1607 return 0;
1608}
1609
1610
1611/**************************************************************************
1612 * CloseDriver (USER.253)
1613 */
1614LRESULT WINAPI CloseDriver16(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
1615{
1616 FIXME( "(%04x, %08lx, %08lx): stub\n", hDrvr, lParam1, lParam2);
1617 return FALSE;
1618}
1619
1620
1621/**************************************************************************
1622 * GetDriverModuleHandle (USER.254)
1623 */
1624HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDrvr)
1625{
1626 FIXME("(%04x): stub\n", hDrvr);
1627 return 0;
1628}
1629
1630
1631/**************************************************************************
1632 * DefDriverProc (USER.255)
1633 */
1634LRESULT WINAPI DefDriverProc16(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg,
1635 LPARAM lParam1, LPARAM lParam2)
1636{
1637 FIXME( "devID=0x%08x hDrv=0x%04x wMsg=%04x lP1=0x%08lx lP2=0x%08lx: stub\n",
1638 dwDevID, hDriv, wMsg, lParam1, lParam2);
1639 return 0;
1640}
1641
1642
1643/**************************************************************************
1644 * GetDriverInfo (USER.256)
1645 */
1646struct DRIVERINFOSTRUCT16;
1647BOOL16 WINAPI GetDriverInfo16(HDRVR16 hDrvr, struct DRIVERINFOSTRUCT16 *lpDrvInfo)
1648{
1649 FIXME( "(%04x, %p): stub\n", hDrvr, lpDrvInfo);
1650 return FALSE;
1651}
1652
1653
1654/**************************************************************************
1655 * GetNextDriver (USER.257)
1656 */
1657HDRVR16 WINAPI GetNextDriver16(HDRVR16 hDrvr, DWORD dwFlags)
1658{
1659 FIXME( "(%04x, %08x): stub\n", hDrvr, dwFlags);
1660 return 0;
1661}
1662
1663
7ef66af3
AJ
1664/**********************************************************************
1665 * GetMenuItemCount (USER.263)
1666 */
1667INT16 WINAPI GetMenuItemCount16( HMENU16 hMenu )
1668{
1669 return GetMenuItemCount( HMENU_32(hMenu) );
1670}
1671
1672
1673/**********************************************************************
1674 * GetMenuItemID (USER.264)
1675 */
1676UINT16 WINAPI GetMenuItemID16( HMENU16 hMenu, INT16 nPos )
1677{
1678 return GetMenuItemID( HMENU_32(hMenu), nPos );
1679}
1680
1681
d8f50798
PS
1682/***********************************************************************
1683 * GlobalAddAtom (USER.268)
1684 */
1685ATOM WINAPI GlobalAddAtom16(LPCSTR lpString)
1686{
1687 return GlobalAddAtomA(lpString);
1688}
1689
1690/***********************************************************************
1691 * GlobalDeleteAtom (USER.269)
1692 */
1693ATOM WINAPI GlobalDeleteAtom16(ATOM nAtom)
1694{
1695 return GlobalDeleteAtom(nAtom);
1696}
1697
1698/***********************************************************************
1699 * GlobalFindAtom (USER.270)
1700 */
1701ATOM WINAPI GlobalFindAtom16(LPCSTR lpString)
1702{
1703 return GlobalFindAtomA(lpString);
1704}
1705
1706/***********************************************************************
1707 * GlobalGetAtomName (USER.271)
1708 */
1709UINT16 WINAPI GlobalGetAtomName16(ATOM nAtom, LPSTR lpBuffer, INT16 nSize)
1710{
1711 return GlobalGetAtomNameA(nAtom, lpBuffer, nSize);
1712}
2d0acacb 1713
7ef66af3 1714
0844afc3
AJ
1715/***********************************************************************
1716 * ControlPanelInfo (USER.273)
1717 */
1718void WINAPI ControlPanelInfo16( INT16 nInfoType, WORD wData, LPSTR lpBuffer )
1719{
1720 FIXME("(%d, %04x, %p): stub.\n", nInfoType, wData, lpBuffer);
1721}
1722
1723
06b39679
RA
1724/***********************************************************************
1725 * OldSetDeskPattern (USER.279)
1726 */
1727BOOL16 WINAPI SetDeskPattern16(void)
1728{
1729 return SystemParametersInfoA( SPI_SETDESKPATTERN, -1, NULL, FALSE );
1730}
1731
1732
7ef66af3
AJ
1733/***********************************************************************
1734 * GetSysColorBrush (USER.281)
1735 */
1736HBRUSH16 WINAPI GetSysColorBrush16( INT16 index )
1737{
1738 return HBRUSH_16( GetSysColorBrush(index) );
1739}
1740
1741
0ccb9fea
AJ
1742/***********************************************************************
1743 * SelectPalette (USER.282)
1744 */
1745HPALETTE16 WINAPI SelectPalette16( HDC16 hdc, HPALETTE16 hpal, BOOL16 bForceBackground )
1746{
1747 return HPALETTE_16( SelectPalette( HDC_32(hdc), HPALETTE_32(hpal), bForceBackground ));
1748}
1749
1750/***********************************************************************
1751 * RealizePalette (USER.283)
1752 */
1753UINT16 WINAPI RealizePalette16( HDC16 hdc )
1754{
1755 return UserRealizePalette( HDC_32(hdc) );
1756}
1757
7ef66af3 1758
03f6f6f7
AJ
1759/***********************************************************************
1760 * GetFreeSystemResources (USER.284)
1761 */
1762WORD WINAPI GetFreeSystemResources16( WORD resType )
1763{
1764 STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
1765 HANDLE16 oldDS = stack16->ds;
03f6f6f7
AJ
1766 int userPercent, gdiPercent;
1767
03f6f6f7
AJ
1768 switch(resType)
1769 {
1770 case GFSR_USERRESOURCES:
1771 stack16->ds = USER_HeapSel;
1772 userPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1773 gdiPercent = 100;
1774 stack16->ds = oldDS;
1775 break;
1776
1777 case GFSR_GDIRESOURCES:
1778 stack16->ds = gdi_inst;
1779 gdiPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1780 userPercent = 100;
1781 stack16->ds = oldDS;
1782 break;
1783
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;
1791
1792 default:
1793 userPercent = gdiPercent = 0;
1794 break;
1795 }
03f6f6f7
AJ
1796 TRACE("<- userPercent %d, gdiPercent %d\n", userPercent, gdiPercent);
1797 return (WORD)min( userPercent, gdiPercent );
1798}
1799
1800
6e9fea22
RA
1801/***********************************************************************
1802 * SetDeskWallPaper (USER.285)
1803 */
1804BOOL16 WINAPI SetDeskWallPaper16( LPCSTR filename )
1805{
1806 return SetDeskWallPaper( filename );
1807}
1808
1809
6c8e3a85
AJ
1810/***********************************************************************
1811 * keybd_event (USER.289)
1812 */
d86df456 1813void WINAPI keybd_event16( CONTEXT *context )
6c8e3a85
AJ
1814{
1815 DWORD dwFlags = 0;
1816
1817 if (HIBYTE(context->Eax) & 0x80) dwFlags |= KEYEVENTF_KEYUP;
1818 if (HIBYTE(context->Ebx) & 0x01) dwFlags |= KEYEVENTF_EXTENDEDKEY;
1819
1820 keybd_event( LOBYTE(context->Eax), LOBYTE(context->Ebx),
1821 dwFlags, MAKELONG(LOWORD(context->Esi), LOWORD(context->Edi)) );
1822}
1823
1824
1825/***********************************************************************
1826 * mouse_event (USER.299)
1827 */
d86df456 1828void WINAPI mouse_event16( CONTEXT *context )
6c8e3a85
AJ
1829{
1830 mouse_event( LOWORD(context->Eax), LOWORD(context->Ebx), LOWORD(context->Ecx),
1831 LOWORD(context->Edx), MAKELONG(context->Esi, context->Edi) );
1832}
1833
1834
3c39a991
AJ
1835/***********************************************************************
1836 * GetClipCursor (USER.309)
1837 */
1838void WINAPI GetClipCursor16( RECT16 *rect )
1839{
1840 if (rect)
1841 {
1842 RECT rect32;
1843 GetClipCursor( &rect32 );
1844 rect->left = rect32.left;
1845 rect->top = rect32.top;
1846 rect->right = rect32.right;
1847 rect->bottom = rect32.bottom;
1848 }
1849}
1850
1851
c963e25c
AJ
1852/***********************************************************************
1853 * SignalProc (USER.314)
1854 */
1855void WINAPI SignalProc16( HANDLE16 hModule, UINT16 code,
1856 UINT16 uExitFn, HINSTANCE16 hInstance, HQUEUE16 hQueue )
1857{
1858 if (code == USIG16_DLL_UNLOAD)
1859 {
0fbe20a2 1860 hModule = GetExePtr(hModule);
c963e25c 1861 /* HOOK_FreeModuleHooks( hModule ); */
0fbe20a2
AJ
1862 free_module_classes( hModule );
1863 free_module_icons( hModule );
c963e25c
AJ
1864 }
1865}
1866
1867
d646c7ed
AJ
1868/***********************************************************************
1869 * SetEventHook (USER.321)
1870 *
1871 * Used by Turbo Debugger for Windows
1872 */
1873FARPROC16 WINAPI SetEventHook16(FARPROC16 lpfnEventHook)
1874{
1875 FIXME("(lpfnEventHook=%p): stub\n", lpfnEventHook);
1876 return 0;
1877}
1878
1879
1880/**********************************************************************
1881 * EnableHardwareInput (USER.331)
1882 */
1883BOOL16 WINAPI EnableHardwareInput16(BOOL16 bEnable)
1884{
1885 FIXME("(%d) - stub\n", bEnable);
1886 return TRUE;
1887}
1888
1889
3806f9ae
AJ
1890/**********************************************************************
1891 * LoadCursorIconHandler (USER.336)
1892 *
1893 * Supposed to load resources of Windows 2.x applications.
1894 */
1895HGLOBAL16 WINAPI LoadCursorIconHandler16( HGLOBAL16 hResource, HMODULE16 hModule, HRSRC16 hRsrc )
1896{
1897 FIXME("(%04x,%04x,%04x): old 2.x resources are not supported!\n", hResource, hModule, hRsrc);
1898 return 0;
1899}
1900
1901
6c8e3a85
AJ
1902/***********************************************************************
1903 * GetMouseEventProc (USER.337)
1904 */
1905FARPROC16 WINAPI GetMouseEventProc16(void)
1906{
1907 HMODULE16 hmodule = GetModuleHandle16("USER");
1908 return GetProcAddress16( hmodule, "mouse_event" );
1909}
1910
1911
d646c7ed
AJ
1912/***********************************************************************
1913 * IsUserIdle (USER.333)
1914 */
1915BOOL16 WINAPI IsUserIdle16(void)
1916{
1917 if ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
1918 return FALSE;
1919 if ( GetAsyncKeyState( VK_RBUTTON ) & 0x8000 )
1920 return FALSE;
1921 if ( GetAsyncKeyState( VK_MBUTTON ) & 0x8000 )
1922 return FALSE;
1923 /* Should check for screen saver activation here ... */
1924 return TRUE;
1925}
1926
1927
90dd7f06
AJ
1928/**********************************************************************
1929 * LoadDIBIconHandler (USER.357)
1930 *
1931 * RT_ICON resource loader, installed by USER_SignalProc when module
1932 * is initialized.
1933 */
1934HGLOBAL16 WINAPI LoadDIBIconHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc )
1935{
1936 /* If hResource is zero we must allocate a new memory block, if it's
1937 * non-zero but GlobalLock() returns NULL then it was discarded and
1938 * we have to recommit some memory, otherwise we just need to check
1939 * the block size. See LoadProc() in 16-bit SDK for more.
1940 */
1941 FIXME( "%x %x %x: stub, not supported anymore\n", hMemObj, hModule, hRsrc );
1942 return 0;
1943}
1944
1945/**********************************************************************
1946 * LoadDIBCursorHandler (USER.356)
1947 *
1948 * RT_CURSOR resource loader. Same as above.
1949 */
1950HGLOBAL16 WINAPI LoadDIBCursorHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc )
1951{
1952 FIXME( "%x %x %x: stub, not supported anymore\n", hMemObj, hModule, hRsrc );
1953 return 0;
1954}
1955
1956
7ef66af3
AJ
1957/**********************************************************************
1958 * IsMenu (USER.358)
1959 */
1960BOOL16 WINAPI IsMenu16( HMENU16 hmenu )
1961{
1962 return IsMenu( HMENU_32(hmenu) );
1963}
1964
1965
2fb7c875
AJ
1966/***********************************************************************
1967 * DCHook (USER.362)
1968 */
1969BOOL16 WINAPI DCHook16( HDC16 hdc, WORD code, DWORD data, LPARAM lParam )
1970{
1971 FIXME( "hDC = %x, %i: stub\n", hdc, code );
1972 return FALSE;
1973}
1974
1975
3806f9ae
AJ
1976/**********************************************************************
1977 * LookupIconIdFromDirectoryEx (USER.364)
1978 *
1979 * FIXME: exact parameter sizes
1980 */
1981INT16 WINAPI LookupIconIdFromDirectoryEx16( LPBYTE dir, BOOL16 bIcon,
1982 INT16 width, INT16 height, UINT16 cFlag )
1983{
1984 return LookupIconIdFromDirectoryEx( dir, bIcon, width, height, cFlag );
1985}
1986
1987
1988/***********************************************************************
1989 * CopyIcon (USER.368)
1990 */
1991HICON16 WINAPI CopyIcon16( HINSTANCE16 hInstance, HICON16 hIcon )
1992{
0280f058 1993 CURSORICONINFO *info = get_icon_ptr( hIcon );
3806f9ae
AJ
1994 void *and_bits = info + 1;
1995 void *xor_bits = (BYTE *)and_bits + info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
1996 HGLOBAL16 ret = CreateCursorIconIndirect16( hInstance, info, and_bits, xor_bits );
0280f058 1997 release_icon_ptr( hIcon, info );
3806f9ae
AJ
1998 return ret;
1999}
2000
2001
2002/***********************************************************************
2003 * CopyCursor (USER.369)
2004 */
2005HCURSOR16 WINAPI CopyCursor16( HINSTANCE16 hInstance, HCURSOR16 hCursor )
2006{
0280f058 2007 CURSORICONINFO *info = get_icon_ptr( hCursor );
3806f9ae
AJ
2008 void *and_bits = info + 1;
2009 void *xor_bits = (BYTE *)and_bits + info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
2010 HGLOBAL16 ret = CreateCursorIconIndirect16( hInstance, info, and_bits, xor_bits );
0280f058 2011 release_icon_ptr( hCursor, info );
3806f9ae
AJ
2012 return ret;
2013}
2014
2015
6de70abd
AJ
2016/***********************************************************************
2017 * SubtractRect (USER.373)
2018 */
2019BOOL16 WINAPI SubtractRect16( LPRECT16 dest, const RECT16 *src1,
2020 const RECT16 *src2 )
2021{
2022 RECT16 tmp;
2023
2024 if (IsRectEmpty16( src1 ))
2025 {
2026 SetRectEmpty16( dest );
2027 return FALSE;
2028 }
2029 *dest = *src1;
2030 if (IntersectRect16( &tmp, src1, src2 ))
2031 {
2032 if (EqualRect16( &tmp, dest ))
2033 {
2034 SetRectEmpty16( dest );
2035 return FALSE;
2036 }
2037 if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom))
2038 {
2039 if (tmp.left == dest->left) dest->left = tmp.right;
2040 else if (tmp.right == dest->right) dest->right = tmp.left;
2041 }
2042 else if ((tmp.left == dest->left) && (tmp.right == dest->right))
2043 {
2044 if (tmp.top == dest->top) dest->top = tmp.bottom;
2045 else if (tmp.bottom == dest->bottom) dest->bottom = tmp.top;
2046 }
2047 }
2048 return TRUE;
2049}
2050
2051
796346f8
AJ
2052/**********************************************************************
2053 * DllEntryPoint (USER.374)
2054 */
2055BOOL WINAPI DllEntryPoint( DWORD reason, HINSTANCE16 inst, WORD ds,
2056 WORD heap, DWORD reserved1, WORD reserved2 )
2057{
2058 if (reason != DLL_PROCESS_ATTACH) return TRUE;
2059 if (USER_HeapSel) return TRUE; /* already called */
2060
2061 USER_HeapSel = ds;
02e74fa8 2062 register_wow_handlers();
a157959d 2063 gdi_inst = LoadLibrary16( "gdi.exe" );
40a264b0
AJ
2064 LoadLibrary16( "display.drv" );
2065 LoadLibrary16( "keyboard.drv" );
2066 LoadLibrary16( "mouse.drv" );
5d9801bc 2067 LoadLibrary16( "user.exe" ); /* make sure it never gets unloaded */
796346f8
AJ
2068 return TRUE;
2069}
2070
2071
7ef66af3
AJ
2072/**********************************************************************
2073 * SetMenuContextHelpId (USER.384)
2074 */
2075BOOL16 WINAPI SetMenuContextHelpId16( HMENU16 hMenu, DWORD dwContextHelpID)
2076{
2077 return SetMenuContextHelpId( HMENU_32(hMenu), dwContextHelpID );
2078}
2079
2080
2081/**********************************************************************
2082 * GetMenuContextHelpId (USER.385)
2083 */
2084DWORD WINAPI GetMenuContextHelpId16( HMENU16 hMenu )
2085{
2086 return GetMenuContextHelpId( HMENU_32(hMenu) );
2087}
2088
2089
2d0acacb
MS
2090/***********************************************************************
2091 * LoadImage (USER.389)
2d0acacb 2092 */
d5b270ea 2093HANDLE16 WINAPI LoadImage16(HINSTANCE16 hinst, LPCSTR name, UINT16 type, INT16 cx, INT16 cy, UINT16 flags)
2d0acacb 2094{
2ced4102
AJ
2095 HGLOBAL16 handle;
2096 HRSRC16 hRsrc, hGroupRsrc;
2097
d5b270ea 2098 if (!hinst || (flags & LR_LOADFROMFILE))
8fc1fc49
AJ
2099 {
2100 if (type == IMAGE_BITMAP)
2101 return HBITMAP_16( LoadImageA( 0, name, type, cx, cy, flags ));
2102 else
2103 return get_icon_16( LoadImageA( 0, name, type, cx, cy, flags ));
2104 }
d5b270ea
AJ
2105
2106 hinst = GetExePtr( hinst );
2107
2108 if (flags & LR_DEFAULTSIZE)
2109 {
2110 if (type == IMAGE_ICON)
2111 {
2112 if (!cx) cx = GetSystemMetrics(SM_CXICON);
2113 if (!cy) cy = GetSystemMetrics(SM_CYICON);
2114 }
2115 else if (type == IMAGE_CURSOR)
2116 {
2117 if (!cx) cx = GetSystemMetrics(SM_CXCURSOR);
2118 if (!cy) cy = GetSystemMetrics(SM_CYCURSOR);
2119 }
2120 }
2121
2122 switch (type)
2123 {
2124 case IMAGE_BITMAP:
2ced4102
AJ
2125 {
2126 HBITMAP ret = 0;
2127 char *ptr;
2128 static const WCHAR prefixW[] = {'b','m','p',0};
2a00c86a 2129 BITMAPFILEHEADER header;
2ced4102
AJ
2130 WCHAR path[MAX_PATH], filename[MAX_PATH];
2131 HANDLE file;
2a00c86a 2132 DWORD size;
2ced4102
AJ
2133
2134 filename[0] = 0;
2135 if (!(hRsrc = FindResource16( hinst, name, (LPCSTR)RT_BITMAP ))) return 0;
2136 if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
2137 if (!(ptr = LockResource16( handle ))) goto done;
2a00c86a
AJ
2138 size = SizeofResource16( hinst, hRsrc );
2139
2140 header.bfType = 0x4d42; /* 'BM' */
2141 header.bfReserved1 = 0;
2142 header.bfReserved2 = 0;
2143 header.bfSize = sizeof(header) + size;
2144 header.bfOffBits = 0; /* not used by the 32-bit loading code */
2ced4102
AJ
2145
2146 if (!GetTempPathW( MAX_PATH, path )) goto done;
2147 if (!GetTempFileNameW( path, prefixW, 0, filename )) goto done;
2148
2149 file = CreateFileW( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
2150 if (file != INVALID_HANDLE_VALUE)
2151 {
2a00c86a
AJ
2152 DWORD written;
2153 BOOL ok;
2154 ok = WriteFile( file, &header, sizeof(header), &written, NULL ) && (written == sizeof(header));
2155 if (ok) ok = WriteFile( file, ptr, size, &written, NULL ) && (written == size);
2ced4102
AJ
2156 CloseHandle( file );
2157 if (ok) ret = LoadImageW( 0, filename, IMAGE_BITMAP, cx, cy, flags | LR_LOADFROMFILE );
2158 }
2159 done:
2160 if (filename[0]) DeleteFileW( filename );
2161 FreeResource16( handle );
2162 return HBITMAP_16( ret );
2163 }
d5b270ea
AJ
2164
2165 case IMAGE_ICON:
2166 case IMAGE_CURSOR:
2167 {
d5b270ea 2168 HICON16 hIcon = 0;
d5b270ea
AJ
2169 BYTE *dir, *bits;
2170 INT id = 0;
2171
2172 if (!(hRsrc = FindResource16( hinst, name,
2173 (LPCSTR)(type == IMAGE_ICON ? RT_GROUP_ICON : RT_GROUP_CURSOR ))))
2174 return 0;
2175 hGroupRsrc = hRsrc;
2176
2177 if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
2178 if ((dir = LockResource16( handle ))) id = LookupIconIdFromDirectory( dir, type == IMAGE_ICON );
2179 FreeResource16( handle );
2180 if (!id) return 0;
2181
2182 if (!(hRsrc = FindResource16( hinst, MAKEINTRESOURCEA(id),
2183 (LPCSTR)(type == IMAGE_ICON ? RT_ICON : RT_CURSOR) ))) return 0;
2184
2185 if ((flags & LR_SHARED) && (hIcon = find_shared_icon( hinst, hRsrc ) ) != 0) return hIcon;
2186
2187 if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
2188 bits = LockResource16( handle );
2189 hIcon = CreateIconFromResourceEx16( bits, 0, type == IMAGE_ICON, 0x00030000, cx, cy, flags );
2190 FreeResource16( handle );
2191
2192 if (hIcon && (flags & LR_SHARED)) add_shared_icon( hinst, hRsrc, hGroupRsrc, hIcon );
2193 return hIcon;
2194 }
2195 default:
2196 return 0;
2197 }
2d0acacb
MS
2198}
2199
2200/******************************************************************************
2201 * CopyImage (USER.390) Creates new image and copies attributes to it
2202 *
2203 */
2204HICON16 WINAPI CopyImage16(HANDLE16 hnd, UINT16 type, INT16 desiredx,
2205 INT16 desiredy, UINT16 flags)
2206{
593b9735
AJ
2207 if (flags & LR_COPYFROMRESOURCE) FIXME( "LR_COPYFROMRESOURCE not supported\n" );
2208
2209 switch (type)
2210 {
2211 case IMAGE_BITMAP:
2212 return HBITMAP_16( CopyImage( HBITMAP_32(hnd), type, desiredx, desiredy, flags ));
2213 case IMAGE_ICON:
2214 case IMAGE_CURSOR:
2215 return CopyIcon16( FarGetOwner16(hnd), hnd );
2216 default:
2217 return 0;
2218 }
2d0acacb
MS
2219}
2220
2221/**********************************************************************
2222 * DrawIconEx (USER.394)
2223 */
2224BOOL16 WINAPI DrawIconEx16(HDC16 hdc, INT16 xLeft, INT16 yTop, HICON16 hIcon,
2225 INT16 cxWidth, INT16 cyWidth, UINT16 istep,
2226 HBRUSH16 hbr, UINT16 flags)
2227{
8fc1fc49 2228 return DrawIconEx(HDC_32(hdc), xLeft, yTop, get_icon_32(hIcon), cxWidth, cyWidth,
2d0acacb
MS
2229 istep, HBRUSH_32(hbr), flags);
2230}
2231
2232/**********************************************************************
2233 * GetIconInfo (USER.395)
2234 */
2235BOOL16 WINAPI GetIconInfo16(HICON16 hIcon, LPICONINFO16 iconinfo)
2236{
e474bfe0
AJ
2237 CURSORICONINFO *info = get_icon_ptr( hIcon );
2238 INT height;
2239
2240 if (!info) return FALSE;
2241
2242 if ((info->ptHotSpot.x == ICON_HOTSPOT) && (info->ptHotSpot.y == ICON_HOTSPOT))
2243 {
2244 iconinfo->fIcon = TRUE;
2245 iconinfo->xHotspot = info->nWidth / 2;
2246 iconinfo->yHotspot = info->nHeight / 2;
2247 }
2248 else
2249 {
2250 iconinfo->fIcon = FALSE;
2251 iconinfo->xHotspot = info->ptHotSpot.x;
2252 iconinfo->yHotspot = info->ptHotSpot.y;
2253 }
2d0acacb 2254
e474bfe0
AJ
2255 height = info->nHeight;
2256
2257 if (info->bBitsPerPixel > 1)
2258 {
2259 iconinfo->hbmColor = HBITMAP_16( CreateBitmap( info->nWidth, info->nHeight,
2260 info->bPlanes, info->bBitsPerPixel,
2261 (char *)(info + 1)
2262 + info->nHeight *
2263 get_bitmap_width_bytes(info->nWidth,1) ));
2264 }
2265 else
2266 {
2267 iconinfo->hbmColor = 0;
2268 height *= 2;
2269 }
2270
2271 iconinfo->hbmMask = HBITMAP_16( CreateBitmap( info->nWidth, height, 1, 1, info + 1 ));
2272 release_icon_ptr( hIcon, info );
2273 return TRUE;
2d0acacb
MS
2274}
2275
d646c7ed
AJ
2276
2277/***********************************************************************
2278 * FinalUserInit (USER.400)
2279 */
2280void WINAPI FinalUserInit16( void )
2281{
2282 /* FIXME: Should chain to FinalGdiInit */
2283}
2284
2285
2d0acacb
MS
2286/***********************************************************************
2287 * CreateCursor (USER.406)
2288 */
2289HCURSOR16 WINAPI CreateCursor16(HINSTANCE16 hInstance,
2290 INT16 xHotSpot, INT16 yHotSpot,
2291 INT16 nWidth, INT16 nHeight,
2292 LPCVOID lpANDbits, LPCVOID lpXORbits)
2293{
2294 CURSORICONINFO info;
2295
2296 info.ptHotSpot.x = xHotSpot;
2297 info.ptHotSpot.y = yHotSpot;
2298 info.nWidth = nWidth;
2299 info.nHeight = nHeight;
2300 info.nWidthBytes = 0;
2301 info.bPlanes = 1;
2302 info.bBitsPerPixel = 1;
2303
613ead7f 2304 return CreateCursorIconIndirect16(hInstance, &info, lpANDbits, lpXORbits);
2d0acacb
MS
2305}
2306
7ef66af3 2307
3806f9ae
AJ
2308/***********************************************************************
2309 * CreateIcon (USER.407)
2310 */
2311HICON16 WINAPI CreateIcon16( HINSTANCE16 hInstance, INT16 nWidth,
2312 INT16 nHeight, BYTE bPlanes, BYTE bBitsPixel,
2313 LPCVOID lpANDbits, LPCVOID lpXORbits )
2314{
3806f9ae
AJ
2315 CURSORICONINFO info;
2316
2317 info.ptHotSpot.x = ICON_HOTSPOT;
2318 info.ptHotSpot.y = ICON_HOTSPOT;
2319 info.nWidth = nWidth;
2320 info.nHeight = nHeight;
2321 info.nWidthBytes = 0;
2322 info.bPlanes = bPlanes;
2323 info.bBitsPerPixel = bBitsPixel;
2324
2325 return CreateCursorIconIndirect16( hInstance, &info, lpANDbits, lpXORbits );
2326}
2327
2328
2329/***********************************************************************
2330 * CreateCursorIconIndirect (USER.408)
2331 */
2332HGLOBAL16 WINAPI CreateCursorIconIndirect16( HINSTANCE16 hInstance,
2333 CURSORICONINFO *info,
2334 LPCVOID lpANDbits,
2335 LPCVOID lpXORbits )
2336{
0280f058
AJ
2337 HICON16 handle;
2338 CURSORICONINFO *ptr;
3806f9ae
AJ
2339 int sizeAnd, sizeXor;
2340
2341 hInstance = GetExePtr( hInstance ); /* Make it a module handle */
2342 if (!lpXORbits || !lpANDbits || info->bPlanes != 1) return 0;
2343 info->nWidthBytes = get_bitmap_width_bytes(info->nWidth,info->bBitsPerPixel);
2344 sizeXor = info->nHeight * info->nWidthBytes;
2345 sizeAnd = info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
0280f058 2346 if (!(handle = alloc_icon_handle( sizeof(CURSORICONINFO) + sizeXor + sizeAnd )))
3806f9ae
AJ
2347 return 0;
2348 FarSetOwner16( handle, hInstance );
0280f058 2349 ptr = get_icon_ptr( handle );
3806f9ae 2350 memcpy( ptr, info, sizeof(*info) );
0280f058
AJ
2351 memcpy( ptr + 1, lpANDbits, sizeAnd );
2352 memcpy( (char *)(ptr + 1) + sizeAnd, lpXORbits, sizeXor );
2353 release_icon_ptr( handle, ptr );
3806f9ae
AJ
2354 return handle;
2355}
2356
2357
86be9f20
AJ
2358/***********************************************************************
2359 * InitThreadInput (USER.409)
2360 */
2361HQUEUE16 WINAPI InitThreadInput16( WORD unknown, WORD flags )
2362{
2363 /* nothing to do here */
2364 return 0xbeef;
2365}
2366
2367
7ef66af3
AJ
2368/*******************************************************************
2369 * InsertMenu (USER.410)
2370 */
2371BOOL16 WINAPI InsertMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
2372 UINT16 id, SEGPTR data )
2373{
2374 UINT pos32 = (UINT)pos;
2375 if ((pos == (UINT16)-1) && (flags & MF_BYPOSITION)) pos32 = (UINT)-1;
2376 if (IS_MENU_STRING_ITEM(flags) && data)
2377 return InsertMenuA( HMENU_32(hMenu), pos32, flags, id, MapSL(data) );
2378 return InsertMenuA( HMENU_32(hMenu), pos32, flags, id, (LPSTR)data );
2379}
2380
2381
2382/*******************************************************************
2383 * AppendMenu (USER.411)
2384 */
2385BOOL16 WINAPI AppendMenu16(HMENU16 hMenu, UINT16 flags, UINT16 id, SEGPTR data)
2386{
45078fb0 2387 return InsertMenu16( hMenu, -1, flags | MF_BYPOSITION, id, data );
7ef66af3
AJ
2388}
2389
2390
2391/**********************************************************************
2392 * RemoveMenu (USER.412)
2393 */
2394BOOL16 WINAPI RemoveMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
2395{
2396 return RemoveMenu( HMENU_32(hMenu), nPos, wFlags );
2397}
2398
2399
2400/**********************************************************************
2401 * DeleteMenu (USER.413)
2402 */
2403BOOL16 WINAPI DeleteMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
2404{
2405 return DeleteMenu( HMENU_32(hMenu), nPos, wFlags );
2406}
2407
2408
2409/*******************************************************************
2410 * ModifyMenu (USER.414)
2411 */
2412BOOL16 WINAPI ModifyMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
2413 UINT16 id, SEGPTR data )
2414{
2415 if (IS_MENU_STRING_ITEM(flags))
2416 return ModifyMenuA( HMENU_32(hMenu), pos, flags, id, MapSL(data) );
2417 return ModifyMenuA( HMENU_32(hMenu), pos, flags, id, (LPSTR)data );
2418}
2419
2420
2421/**********************************************************************
2422 * CreatePopupMenu (USER.415)
2423 */
2424HMENU16 WINAPI CreatePopupMenu16(void)
2425{
2426 return HMENU_16( CreatePopupMenu() );
2427}
2428
2429
2430/**********************************************************************
2431 * SetMenuItemBitmaps (USER.418)
2432 */
2433BOOL16 WINAPI SetMenuItemBitmaps16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags,
2434 HBITMAP16 hNewUnCheck, HBITMAP16 hNewCheck)
2435{
2436 return SetMenuItemBitmaps( HMENU_32(hMenu), nPos, wFlags,
2437 HBITMAP_32(hNewUnCheck), HBITMAP_32(hNewCheck) );
2438}
2439
2440
25d7e0b9
AJ
2441/***********************************************************************
2442 * wvsprintf (USER.421)
2443 */
2444INT16 WINAPI wvsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 args )
2445{
2446 WPRINTF_FORMAT format;
2447 LPSTR p = buffer;
2448 UINT i, len, sign;
2449 CHAR number[20];
2450 CHAR char_view = 0;
2451 LPCSTR lpcstr_view = NULL;
2452 INT int_view;
2453 SEGPTR seg_str;
2454
2455 while (*spec)
2456 {
2457 if (*spec != '%') { *p++ = *spec++; continue; }
2458 spec++;
2459 if (*spec == '%') { *p++ = *spec++; continue; }
2460 spec += parse_format( spec, &format );
2461 switch(format.type)
2462 {
2463 case WPR_CHAR:
2464 char_view = VA_ARG16( args, CHAR );
2465 len = format.precision = 1;
2466 break;
2467 case WPR_STRING:
2468 seg_str = VA_ARG16( args, SEGPTR );
2469 if (IsBadReadPtr16( seg_str, 1 )) lpcstr_view = "";
2470 else lpcstr_view = MapSL( seg_str );
2471 if (!lpcstr_view) lpcstr_view = "(null)";
2472 for (len = 0; !format.precision || (len < format.precision); len++)
2473 if (!lpcstr_view[len]) break;
2474 format.precision = len;
2475 break;
2476 case WPR_SIGNED:
2477 if (format.flags & WPRINTF_LONG) int_view = VA_ARG16( args, INT );
2478 else int_view = VA_ARG16( args, INT16 );
2479 len = sprintf( number, "%d", int_view );
2480 break;
2481 case WPR_UNSIGNED:
2482 if (format.flags & WPRINTF_LONG) int_view = VA_ARG16( args, UINT );
2483 else int_view = VA_ARG16( args, UINT16 );
2484 len = sprintf( number, "%u", int_view );
2485 break;
2486 case WPR_HEXA:
2487 if (format.flags & WPRINTF_LONG) int_view = VA_ARG16( args, UINT );
2488 else int_view = VA_ARG16( args, UINT16 );
2489 len = sprintf( number, (format.flags & WPRINTF_UPPER_HEX) ? "%X" : "%x", int_view);
2490 break;
2491 case WPR_UNKNOWN:
2492 continue;
2493 }
2494 if (format.precision < len) format.precision = len;
2495 if (format.flags & WPRINTF_LEFTALIGN) format.flags &= ~WPRINTF_ZEROPAD;
2496 if ((format.flags & WPRINTF_ZEROPAD) && (format.width > format.precision))
2497 format.precision = format.width;
2498 if (format.flags & WPRINTF_PREFIX_HEX) len += 2;
2499
2500 sign = 0;
2501 if (!(format.flags & WPRINTF_LEFTALIGN))
2502 for (i = format.precision; i < format.width; i++) *p++ = ' ';
2503 switch(format.type)
2504 {
2505 case WPR_CHAR:
2506 *p = char_view;
2507 /* wsprintf16 ignores null characters */
2508 if (*p != '\0') p++;
2509 else if (format.width > 1) *p++ = ' ';
25d7e0b9
AJ
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)
2517 {
2518 *p++ = '0';
2519 *p++ = (format.flags & WPRINTF_UPPER_HEX) ? 'X' : 'x';
2520 len -= 2;
2521 }
2522 /* fall through */
2523 case WPR_SIGNED:
2524 /* Transfer the sign now, just in case it will be zero-padded*/
2525 if (number[0] == '-')
2526 {
2527 *p++ = '-';
2528 sign = 1;
2529 }
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;
2538 }
2539 if (format.flags & WPRINTF_LEFTALIGN)
2540 for (i = format.precision; i < format.width; i++) *p++ = ' ';
2541 }
2542 *p = 0;
2543 return p - buffer;
2544}
2545
2546
2547/***********************************************************************
2548 * _wsprintf (USER.420)
2549 */
2550INT16 WINAPIV wsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 valist )
2551{
2552 return wvsprintf16( buffer, spec, valist );
2553}
2554
2555
89b0f3ae
AJ
2556/***********************************************************************
2557 * lstrcmp (USER.430)
2558 */
2559INT16 WINAPI lstrcmp16( LPCSTR str1, LPCSTR str2 )
2560{
f917cd0e
MM
2561 int ret;
2562 /* Looks too complicated, but in optimized strcpy we might get
2563 * a 32bit wide difference and would truncate it to 16 bit, so
2564 * erroneously returning equality. */
2565 ret = strcmp( str1, str2 );
2566 if (ret < 0) return -1;
2567 if (ret > 0) return 1;
2568 return 0;
89b0f3ae
AJ
2569}
2570
2571
2572/***********************************************************************
2573 * AnsiUpper (USER.431)
2574 */
2575SEGPTR WINAPI AnsiUpper16( SEGPTR strOrChar )
2576{
2577 /* uppercase only one char if strOrChar < 0x10000 */
2578 if (HIWORD(strOrChar))
2579 {
2580 CharUpperA( MapSL(strOrChar) );
2581 return strOrChar;
2582 }
2583 else return (SEGPTR)CharUpperA( (LPSTR)strOrChar );
2584}
2585
2586
2587/***********************************************************************
2588 * AnsiLower (USER.432)
2589 */
2590SEGPTR WINAPI AnsiLower16( SEGPTR strOrChar )
2591{
2592 /* lowercase only one char if strOrChar < 0x10000 */
2593 if (HIWORD(strOrChar))
2594 {
2595 CharLowerA( MapSL(strOrChar) );
2596 return strOrChar;
2597 }
2598 else return (SEGPTR)CharLowerA( (LPSTR)strOrChar );
2599}
2600
2601
2602/***********************************************************************
2603 * AnsiUpperBuff (USER.437)
2604 */
2605UINT16 WINAPI AnsiUpperBuff16( LPSTR str, UINT16 len )
2606{
2607 CharUpperBuffA( str, len ? len : 65536 );
2608 return len;
2609}
2610
2611
2612/***********************************************************************
2613 * AnsiLowerBuff (USER.438)
2614 */
2615UINT16 WINAPI AnsiLowerBuff16( LPSTR str, UINT16 len )
2616{
2617 CharLowerBuffA( str, len ? len : 65536 );
2618 return len;
2619}
2620
2621
7ef66af3
AJ
2622/*******************************************************************
2623 * InsertMenuItem (USER.441)
2624 *
2625 * FIXME: untested
2626 */
2627BOOL16 WINAPI InsertMenuItem16( HMENU16 hmenu, UINT16 pos, BOOL16 byposition,
2628 const MENUITEMINFO16 *mii )
2629{
2630 MENUITEMINFOA miia;
2631
2632 miia.cbSize = sizeof(miia);
2633 miia.fMask = mii->fMask;
2634 miia.dwTypeData = (LPSTR)mii->dwTypeData;
2635 miia.fType = mii->fType;
2636 miia.fState = mii->fState;
2637 miia.wID = mii->wID;
45078fb0
AJ
2638 miia.hSubMenu = HMENU_32(mii->hSubMenu);
2639 miia.hbmpChecked = HBITMAP_32(mii->hbmpChecked);
2640 miia.hbmpUnchecked = HBITMAP_32(mii->hbmpUnchecked);
7ef66af3
AJ
2641 miia.dwItemData = mii->dwItemData;
2642 miia.cch = mii->cch;
2643 if (IS_MENU_STRING_ITEM(miia.fType))
2644 miia.dwTypeData = MapSL(mii->dwTypeData);
2645 return InsertMenuItemA( HMENU_32(hmenu), pos, byposition, &miia );
2646}
2647
2648
7e92c9af
AJ
2649/**********************************************************************
2650 * DrawState (USER.449)
2651 */
2652BOOL16 WINAPI DrawState16( HDC16 hdc, HBRUSH16 hbr, DRAWSTATEPROC16 func, LPARAM ldata,
2653 WPARAM16 wdata, INT16 x, INT16 y, INT16 cx, INT16 cy, UINT16 flags )
2654{
2655 struct draw_state_info info;
2656 UINT opcode = flags & 0xf;
2657
2658 if (opcode == DST_TEXT || opcode == DST_PREFIXTEXT)
2659 {
2660 /* make sure DrawStateA doesn't try to use ldata as a pointer */
2661 if (!wdata) wdata = strlen( MapSL(ldata) );
2662 if (!cx || !cy)
2663 {
2664 SIZE s;
2665 if (!GetTextExtentPoint32A( HDC_32(hdc), MapSL(ldata), wdata, &s )) return FALSE;
2666 if (!cx) cx = s.cx;
2667 if (!cy) cy = s.cy;
2668 }
2669 }
2670 info.proc = func;
2671 info.param = ldata;
2672 return DrawStateA( HDC_32(hdc), HBRUSH_32(hbr), draw_state_callback,
2673 (LPARAM)&info, wdata, x, y, cx, cy, flags );
2674}
2675
2676
2d0acacb
MS
2677/**********************************************************************
2678 * CreateIconFromResourceEx (USER.450)
2679 *
2680 * FIXME: not sure about exact parameter types
2681 */
2682HICON16 WINAPI CreateIconFromResourceEx16(LPBYTE bits, UINT16 cbSize,
2683 BOOL16 bIcon, DWORD dwVersion,
2684 INT16 width, INT16 height,
2685 UINT16 cFlag)
2686{
8fc1fc49 2687 return get_icon_16( CreateIconFromResourceEx( bits, cbSize, bIcon, dwVersion, width, height, cFlag ));
2d0acacb
MS
2688}
2689
3c39a991
AJ
2690
2691/***********************************************************************
2692 * AdjustWindowRectEx (USER.454)
2693 */
2694BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style, BOOL16 menu, DWORD exStyle )
2695{
2696 RECT rect32;
2697 BOOL ret;
2698
2699 rect32.left = rect->left;
2700 rect32.top = rect->top;
2701 rect32.right = rect->right;
2702 rect32.bottom = rect->bottom;
2703 ret = AdjustWindowRectEx( &rect32, style, menu, exStyle );
2704 rect->left = rect32.left;
2705 rect->top = rect32.top;
2706 rect->right = rect32.right;
2707 rect->bottom = rect32.bottom;
2708 return ret;
2709}
2710
2711
3806f9ae
AJ
2712/**********************************************************************
2713 * GetIconID (USER.455)
2714 */
2715WORD WINAPI GetIconID16( HGLOBAL16 hResource, DWORD resType )
2716{
2717 BYTE *dir = GlobalLock16(hResource);
2718
2719 switch (resType)
2720 {
2721 case RT_CURSOR:
2722 return LookupIconIdFromDirectoryEx16( dir, FALSE, GetSystemMetrics(SM_CXCURSOR),
2723 GetSystemMetrics(SM_CYCURSOR), LR_MONOCHROME );
2724 case RT_ICON:
2725 return LookupIconIdFromDirectoryEx16( dir, TRUE, GetSystemMetrics(SM_CXICON),
2726 GetSystemMetrics(SM_CYICON), 0 );
2727 }
2728 return 0;
2729}
2730
2731
2732/**********************************************************************
2733 * LoadIconHandler (USER.456)
2734 */
2735HICON16 WINAPI LoadIconHandler16( HGLOBAL16 hResource, BOOL16 bNew )
2736{
3d55d143
AJ
2737 return CreateIconFromResourceEx16( LockResource16( hResource ), 0, TRUE,
2738 bNew ? 0x00030000 : 0x00020000, 0, 0, LR_DEFAULTCOLOR );
3806f9ae
AJ
2739}
2740
2741
2d0acacb
MS
2742/***********************************************************************
2743 * DestroyIcon (USER.457)
2744 */
2745BOOL16 WINAPI DestroyIcon16(HICON16 hIcon)
2746{
d5b270ea
AJ
2747 int count;
2748
2749 TRACE("%04x\n", hIcon );
2750
2751 count = release_shared_icon( hIcon );
2752 if (count != -1) return !count;
2753 /* assume non-shared */
0280f058 2754 free_icon_handle( hIcon );
d5b270ea 2755 return TRUE;
2d0acacb
MS
2756}
2757
2758/***********************************************************************
2759 * DestroyCursor (USER.458)
2760 */
2761BOOL16 WINAPI DestroyCursor16(HCURSOR16 hCursor)
2762{
d5b270ea 2763 return DestroyIcon16( hCursor );
2d0acacb 2764}
ec5612ee 2765
3806f9ae
AJ
2766
2767/***********************************************************************
2768 * DumpIcon (USER.459)
2769 */
2770DWORD WINAPI DumpIcon16( SEGPTR pInfo, WORD *lpLen,
2771 SEGPTR *lpXorBits, SEGPTR *lpAndBits )
2772{
2773 CURSORICONINFO *info = MapSL( pInfo );
2774 int sizeAnd, sizeXor;
2775
2776 if (!info) return 0;
2777 sizeXor = info->nHeight * info->nWidthBytes;
2778 sizeAnd = info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
2779 if (lpAndBits) *lpAndBits = pInfo + sizeof(CURSORICONINFO);
2780 if (lpXorBits) *lpXorBits = pInfo + sizeof(CURSORICONINFO) + sizeAnd;
2781 if (lpLen) *lpLen = sizeof(CURSORICONINFO) + sizeAnd + sizeXor;
2782 return MAKELONG( sizeXor, sizeXor );
2783}
2784
2785
cf2e57d0
AJ
2786/*******************************************************************
2787 * DRAG_QueryUpdate16
2788 *
2789 * Recursively find a child that contains spDragInfo->pt point
2790 * and send WM_QUERYDROPOBJECT. Helper for DragObject16.
2791 */
2792static BOOL DRAG_QueryUpdate16( HWND hQueryWnd, SEGPTR spDragInfo )
2793{
2794 BOOL bResult = 0;
2795 WPARAM wParam;
2796 POINT pt, old_pt;
2797 LPDRAGINFO16 ptrDragInfo = MapSL(spDragInfo);
2798 RECT tempRect;
2799 HWND child;
2800
2801 if (!IsWindowEnabled(hQueryWnd)) return FALSE;
2802
2803 old_pt.x = ptrDragInfo->pt.x;
2804 old_pt.y = ptrDragInfo->pt.y;
2805 pt = old_pt;
2806 ScreenToClient( hQueryWnd, &pt );
2807 child = ChildWindowFromPointEx( hQueryWnd, pt, CWP_SKIPINVISIBLE );
2808 if (!child) return FALSE;
2809
2810 if (child != hQueryWnd)
2811 {
2812 wParam = 0;
2813 if (DRAG_QueryUpdate16( child, spDragInfo )) return TRUE;
2814 }
2815 else
2816 {
2817 GetClientRect( hQueryWnd, &tempRect );
2818 wParam = !PtInRect( &tempRect, pt );
2819 }
2820
2821 ptrDragInfo->pt.x = pt.x;
2822 ptrDragInfo->pt.y = pt.y;
2823 ptrDragInfo->hScope = HWND_16(hQueryWnd);
2824
2825 bResult = SendMessage16( HWND_16(hQueryWnd), WM_QUERYDROPOBJECT, wParam, spDragInfo );
2826
2827 if (!bResult)
2828 {
2829 ptrDragInfo->pt.x = old_pt.x;
2830 ptrDragInfo->pt.y = old_pt.y;
2831 }
2832 return bResult;
2833}
2834
2835
2836/******************************************************************************
2837 * DragObject (USER.464)
2838 */
2839DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2840 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2841{
2842 MSG msg;
2843 LPDRAGINFO16 lpDragInfo;
2844 SEGPTR spDragInfo;
8fc1fc49 2845 HCURSOR hOldCursor=0, hBummer=0, hCursor32;
cf2e57d0
AJ
2846 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO16));
2847 HCURSOR hCurrentCursor = 0;
2848 HWND16 hCurrentWnd = 0;
2849
2850 lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo);
628939d5 2851 spDragInfo = WOWGlobalLock16(hDragInfo);
cf2e57d0
AJ
2852
2853 if( !lpDragInfo || !spDragInfo ) return 0L;
2854
2855 if (!(hBummer = LoadCursorA(0, MAKEINTRESOURCEA(OCR_NO))))
2856 {
2857 GlobalFree16(hDragInfo);
2858 return 0L;
2859 }
2860
8fc1fc49 2861 if ((hCursor32 = get_icon_32( hCursor ))) SetCursor( hCursor32 );
cf2e57d0
AJ
2862
2863 lpDragInfo->hWnd = hWnd;
2864 lpDragInfo->hScope = 0;
2865 lpDragInfo->wFlags = wObj;
2866 lpDragInfo->hList = szList; /* near pointer! */
2867 lpDragInfo->hOfStruct = hOfStruct;
2868 lpDragInfo->l = 0L;
2869
2870 SetCapture( HWND_32(hWnd) );
2871 ShowCursor( TRUE );
2872
2873 do
2874 {
2875 GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST );
2876
2877 *(lpDragInfo+1) = *lpDragInfo;
2878
2879 lpDragInfo->pt.x = msg.pt.x;
2880 lpDragInfo->pt.y = msg.pt.y;
2881
2882 /* update DRAGINFO struct */
2883 if( DRAG_QueryUpdate16(WIN_Handle32(hwndScope), spDragInfo) > 0 )
8fc1fc49 2884 hCurrentCursor = hCursor32;
cf2e57d0
AJ
2885 else
2886 {
2887 hCurrentCursor = hBummer;
2888 lpDragInfo->hScope = 0;
2889 }
2890 if( hCurrentCursor )
2891 SetCursor(hCurrentCursor);
2892
2893 /* send WM_DRAGLOOP */
453cf859 2894 SendMessage16( hWnd, WM_DRAGLOOP, hCurrentCursor != hBummer, spDragInfo );
cf2e57d0
AJ
2895 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2896 if( hCurrentWnd != lpDragInfo->hScope )
2897 {
2898 if( hCurrentWnd )
2899 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
453cf859
MS
2900 MAKELPARAM(LOWORD(spDragInfo)+sizeof(DRAGINFO16),
2901 HIWORD(spDragInfo)) );
cf2e57d0
AJ
2902 hCurrentWnd = lpDragInfo->hScope;
2903 if( hCurrentWnd )
453cf859 2904 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, spDragInfo);
cf2e57d0
AJ
2905 }
2906 else
2907 if( hCurrentWnd )
453cf859 2908 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, spDragInfo);
cf2e57d0
AJ
2909
2910 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2911
2912 ReleaseCapture();
2913 ShowCursor( FALSE );
2914
2915 if( hCursor ) SetCursor(hOldCursor);
2916
2917 if( hCurrentCursor != hBummer )
2918 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
453cf859 2919 hWnd, spDragInfo );
cf2e57d0
AJ
2920 else
2921 msg.lParam = 0;
2922 GlobalFree16(hDragInfo);
2923
2924 return (DWORD)(msg.lParam);
2925}
2926
2927
c1585509
AJ
2928/***********************************************************************
2929 * DrawFocusRect (USER.466)
2930 */
2931void WINAPI DrawFocusRect16( HDC16 hdc, const RECT16* rc )
2932{
2933 RECT rect32;
3c39a991
AJ
2934
2935 rect32.left = rc->left;
2936 rect32.top = rc->top;
2937 rect32.right = rc->right;
2938 rect32.bottom = rc->bottom;
c1585509
AJ
2939 DrawFocusRect( HDC_32(hdc), &rect32 );
2940}
2941
2942
89b0f3ae
AJ
2943/***********************************************************************
2944 * AnsiNext (USER.472)
2945 */
2946SEGPTR WINAPI AnsiNext16(SEGPTR current)
2947{
2948 char *ptr = MapSL(current);
2949 return current + (CharNextA(ptr) - ptr);
2950}
2951
2952
2953/***********************************************************************
2954 * AnsiPrev (USER.473)
2955 */
2956SEGPTR WINAPI AnsiPrev16( LPCSTR start, SEGPTR current )
2957{
2958 char *ptr = MapSL(current);
2959 return current - (ptr - CharPrevA( start, ptr ));
2960}
2961
2962
6c8e3a85
AJ
2963/****************************************************************************
2964 * GetKeyboardLayoutName (USER.477)
2965 */
2966INT16 WINAPI GetKeyboardLayoutName16( LPSTR name )
2967{
2968 return GetKeyboardLayoutNameA( name );
2969}
2970
2971
57e9244a
AJ
2972/***********************************************************************
2973 * SystemParametersInfo (USER.483)
2974 */
2975BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
2976 LPVOID lpvParam, UINT16 fuWinIni )
2977{
2978 BOOL16 ret;
2979
2980 TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
2981
2982 switch (uAction)
2983 {
2984 case SPI_GETBEEP:
2985 case SPI_GETSCREENSAVEACTIVE:
2986 case SPI_GETICONTITLEWRAP:
2987 case SPI_GETMENUDROPALIGNMENT:
2988 case SPI_GETFASTTASKSWITCH:
2989 case SPI_GETDRAGFULLWINDOWS:
2990 {
2991 BOOL tmp;
2992 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2993 if (ret && lpvParam) *(BOOL16 *)lpvParam = tmp;
2994 break;
2995 }
2996
2997 case SPI_GETBORDER:
2998 case SPI_ICONHORIZONTALSPACING:
2999 case SPI_GETSCREENSAVETIMEOUT:
3000 case SPI_GETGRIDGRANULARITY:
3001 case SPI_GETKEYBOARDDELAY:
3002 case SPI_ICONVERTICALSPACING:
3003 {
3004 INT tmp;
3005 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
3006 if (ret && lpvParam) *(INT16 *)lpvParam = tmp;
3007 break;
3008 }
3009
3010 case SPI_GETKEYBOARDSPEED:
3011 case SPI_GETMOUSEHOVERWIDTH:
3012 case SPI_GETMOUSEHOVERHEIGHT:
3013 case SPI_GETMOUSEHOVERTIME:
3014 {
3015 DWORD tmp;
3016 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
3017 if (ret && lpvParam) *(WORD *)lpvParam = tmp;
3018 break;
3019 }
3020
3021 case SPI_GETICONTITLELOGFONT:
3022 {
3023 LOGFONTA tmp;
3024 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
3025 if (ret && lpvParam) logfont_32_to_16( &tmp, (LPLOGFONT16)lpvParam );
3026 break;
3027 }
3028
3029 case SPI_GETNONCLIENTMETRICS:
3030 {
3031 NONCLIENTMETRICSA tmp;
3032 LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
3033 if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
3034 {
3035 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
3036 ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
3037 if (ret)
3038 {
3039 lpnm16->iBorderWidth = tmp.iBorderWidth;
3040 lpnm16->iScrollWidth = tmp.iScrollWidth;
3041 lpnm16->iScrollHeight = tmp.iScrollHeight;
3042 lpnm16->iCaptionWidth = tmp.iCaptionWidth;
3043 lpnm16->iCaptionHeight = tmp.iCaptionHeight;
3044 lpnm16->iSmCaptionWidth = tmp.iSmCaptionWidth;
3045 lpnm16->iSmCaptionHeight = tmp.iSmCaptionHeight;
3046 lpnm16->iMenuWidth = tmp.iMenuWidth;
3047 lpnm16->iMenuHeight = tmp.iMenuHeight;
3048 logfont_32_to_16( &tmp.lfCaptionFont, &lpnm16->lfCaptionFont );
3049 logfont_32_to_16( &tmp.lfSmCaptionFont, &lpnm16->lfSmCaptionFont );
3050 logfont_32_to_16( &tmp.lfMenuFont, &lpnm16->lfMenuFont );
3051 logfont_32_to_16( &tmp.lfStatusFont, &lpnm16->lfStatusFont );
3052 logfont_32_to_16( &tmp.lfMessageFont, &lpnm16->lfMessageFont );
3053 }
3054 }
3055 else /* winfile 95 sets cbSize to 340 */
3056 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
3057 break;
3058 }
3059
3060 case SPI_GETWORKAREA:
3061 {
3062 RECT tmp;
3063 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
3064 if (ret && lpvParam)
3065 {
3066 RECT16 *r16 = lpvParam;
3067 r16->left = tmp.left;
3068 r16->top = tmp.top;
3069 r16->right = tmp.right;
3070 r16->bottom = tmp.bottom;
3071 }
3072 break;
3073 }
3074
3075 default:
3076 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
3077 break;
3078 }
3079
3080 return ret;
3081}
3082
3083
da57abcb
AJ
3084/***********************************************************************
3085 * USER_489 (USER.489)
3086 */
3087LONG WINAPI stub_USER_489(void)
3088{
3089 FIXME("stub\n");
3090 return 0;
3091}
3092
3093
3094/***********************************************************************
3095 * USER_490 (USER.490)
3096 */
3097LONG WINAPI stub_USER_490(void)
3098{
3099 FIXME("stub\n");
3100 return 0;
3101}
3102
3103
3104/***********************************************************************
3105 * USER_492 (USER.492)
3106 */
3107LONG WINAPI stub_USER_492(void)
3108{
3109 FIXME("stub\n");
3110 return 0;
3111}
3112
3113
3114/***********************************************************************
3115 * USER_496 (USER.496)
3116 */
3117LONG WINAPI stub_USER_496(void)
3118{
3119 FIXME("stub\n");
3120 return 0;
3121}
3122
3123
89b0f3ae
AJ
3124/***********************************************************************
3125 * FormatMessage (USER.606)
3126 */
3127DWORD WINAPI FormatMessage16(
3128 DWORD dwFlags,
3129 SEGPTR lpSource, /* [in] NOTE: not always a valid pointer */
3130 WORD dwMessageId,
3131 WORD dwLanguageId,
3132 LPSTR lpBuffer, /* [out] NOTE: *((HLOCAL16*)) for FORMAT_MESSAGE_ALLOCATE_BUFFER*/
3133 WORD nSize,
3134 LPDWORD args ) /* [in] NOTE: va_list *args */
3135{
89b0f3ae
AJ
3136/* This implementation is completely dependent on the format of the va_list on x86 CPUs */
3137 LPSTR target,t;
3138 DWORD talloced;
3139 LPSTR from,f;
3140 DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
3141 BOOL eos = FALSE;
3142 LPSTR allocstring = NULL;
3143
3c60ce85 3144 TRACE("(0x%x,%x,%d,0x%x,%p,%d,%p)\n",
89b0f3ae
AJ
3145 dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
3146 if ((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
3147 && (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)) return 0;
3148 if ((dwFlags & FORMAT_MESSAGE_FROM_STRING)
3149 &&((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
3150 || (dwFlags & FORMAT_MESSAGE_FROM_HMODULE))) return 0;
3151
3152 if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
3c60ce85 3153 FIXME("line wrapping (%u) not supported.\n", width);
89b0f3ae
AJ
3154 from = NULL;
3155 if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
3156 {
3157 char *source = MapSL(lpSource);
3158 from = HeapAlloc( GetProcessHeap(), 0, strlen(source)+1 );
3159 strcpy( from, source );
3160 }
3161 else if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
3162 from = HeapAlloc( GetProcessHeap(),0,200 );
3163 sprintf(from,"Systemmessage, messageid = 0x%08x\n",dwMessageId);
3164 }
3165 else if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
3166 INT16 bufsize;
3167 HINSTANCE16 hinst16 = ((HINSTANCE16)lpSource & 0xffff);
3168
3169 dwMessageId &= 0xFFFF;
3170 bufsize=LoadString16(hinst16,dwMessageId,NULL,0);
3171 if (bufsize) {
3172 from = HeapAlloc( GetProcessHeap(), 0, bufsize +1);
3173 LoadString16(hinst16,dwMessageId,from,bufsize+1);
3174 }
3175 }
3176 target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
3177 t = target;
3178 talloced= 100;
3179
3180#define ADD_TO_T(c) \
3181 *t++=c;\
3182 if (t-target == talloced) {\
3183 target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
3184 t = target+talloced;\
3185 talloced*=2;\
3186 }
3187
3188 if (from) {
3189 f=from;
3190 while (*f && !eos) {
3191 if (*f=='%') {
3192 int insertnr;
3193 char *fmtstr,*x,*lastf;
3194 DWORD *argliststart;
3195
3196 fmtstr = NULL;
3197 lastf = f;
3198 f++;
3199 if (!*f) {
3200 ADD_TO_T('%');
3201 continue;
3202 }
3203 switch (*f) {
3204 case '1':case '2':case '3':case '4':case '5':
3205 case '6':case '7':case '8':case '9':
3206 insertnr=*f-'0';
3207 switch (f[1]) {
3208 case '0':case '1':case '2':case '3':
3209 case '4':case '5':case '6':case '7':
3210 case '8':case '9':
3211 f++;
3212 insertnr=insertnr*10+*f-'0';
3213 f++;
3214 break;
3215 default:
3216 f++;
3217 break;
3218 }
3219 if (*f=='!') {
3220 f++;
3221 if (NULL!=(x=strchr(f,'!'))) {
3222 *x='\0';
3223 fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
3224 sprintf(fmtstr,"%%%s",f);
3225 f=x+1;
3226 } else {
3227 fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
3228 sprintf(fmtstr,"%%%s",f);
3229 f+=strlen(f); /*at \0*/
3230 }
3231 }
3232 else
3233 {
3234 if(!args) break;
3235 fmtstr=HeapAlloc( GetProcessHeap(), 0, 3 );
3236 strcpy( fmtstr, "%s" );
3237 }
3238 if (args) {
3239 int ret;
3240 int sz;
3241 LPSTR b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 100);
3242
3243 argliststart=args+insertnr-1;
3244
3245 /* CMF - This makes a BIG assumption about va_list */
3246 while ((ret = vsnprintf(b, sz, fmtstr, (va_list) argliststart) < 0) || (ret >= sz)) {
3247 sz = (ret == -1 ? sz + 100 : ret + 1);
3248 b = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, b, sz);
3249 }
3250 for (x=b; *x; x++) ADD_TO_T(*x);
3251 HeapFree(GetProcessHeap(), 0, b);
3252 } else {
3253 /* NULL args - copy formatstr
3254 * (probably wrong)
3255 */
3256 while ((lastf<f)&&(*lastf)) {
3257 ADD_TO_T(*lastf++);
3258 }
3259 }
3260 HeapFree(GetProcessHeap(),0,fmtstr);
3261 break;
3262 case '0': /* Just stop processing format string */
3263 eos = TRUE;
3264 f++;
3265 break;
3266 case 'n': /* 16 bit version just outputs 'n' */
3267 default:
3268 ADD_TO_T(*f++);
3269 break;
3270 }
3271 } else { /* '\n' or '\r' gets mapped to "\r\n" */
3272 if(*f == '\n' || *f == '\r') {
3273 if (width == 0) {
3274 ADD_TO_T('\r');
3275 ADD_TO_T('\n');
3276 if(*f++ == '\r' && *f == '\n')
3277 f++;
3278 }
3279 } else {
3280 ADD_TO_T(*f++);
3281 }
3282 }
3283 }
3284 *t='\0';
3285 }
3286 talloced = strlen(target)+1;
3287 if (nSize && talloced<nSize) {
3288 target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
3289 }
3290 TRACE("-- %s\n",debugstr_a(target));
3291 if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
3292 /* nSize is the MINIMUM size */
3293 HLOCAL16 h = LocalAlloc16(LPTR,talloced);
3294 SEGPTR ptr = LocalLock16(h);
3295 allocstring = MapSL( ptr );
3296 memcpy( allocstring,target,talloced);
3297 LocalUnlock16( h );
3298 *((HLOCAL16*)lpBuffer) = h;
3299 } else
3300 lstrcpynA(lpBuffer,target,nSize);
3301 HeapFree(GetProcessHeap(),0,target);
3302 HeapFree(GetProcessHeap(),0,from);
3303 return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
3304 strlen(allocstring):
3305 strlen(lpBuffer);
89b0f3ae
AJ
3306}
3307#undef ADD_TO_T
3308
3309
1d1f8e2a
AJ
3310/**********************************************************************
3311 * DestroyIcon32 (USER.610)
3312 *
3313 * This routine is actually exported from Win95 USER under the name
3314 * DestroyIcon32 ... The behaviour implemented here should mimic
3315 * the Win95 one exactly, especially the return values, which
3316 * depend on the setting of various flags.
3317 */
3318WORD WINAPI DestroyIcon32( HGLOBAL16 handle, UINT16 flags )
3319{
3320 WORD retv;
3321
3322 /* Check whether destroying active cursor */
3323
3324 if (GetCursor16() == handle)
3325 {
3326 WARN("Destroying active cursor!\n" );
3327 return FALSE;
3328 }
3329
3330 /* Try shared cursor/icon first */
3331
3332 if (!(flags & CID_NONSHARED))
3333 {
3334 INT count = release_shared_icon( handle );
3335 if (count != -1)
3336 return (flags & CID_WIN32) ? TRUE : (count == 0);
3337 }
3338
3339 /* Now assume non-shared cursor/icon */
3340
0280f058 3341 retv = free_icon_handle( handle );
1d1f8e2a
AJ
3342 return (flags & CID_RESOURCE)? retv : TRUE;
3343}
3344
3345
d646c7ed
AJ
3346/***********************************************************************
3347 * ChangeDisplaySettings (USER.620)
3348 */
3349LONG WINAPI ChangeDisplaySettings16( LPDEVMODEA devmode, DWORD flags )
3350{
3351 return ChangeDisplaySettingsA( devmode, flags );
3352}
3353
3354
3355/***********************************************************************
3356 * EnumDisplaySettings (USER.621)
3357 */
3358BOOL16 WINAPI EnumDisplaySettings16( LPCSTR name, DWORD n, LPDEVMODEA devmode )
3359{
3360 return EnumDisplaySettingsA( name, n, devmode );
3361}
3362
ec5612ee
MS
3363/**********************************************************************
3364 * DrawFrameControl (USER.656)
3365 */
3366BOOL16 WINAPI DrawFrameControl16( HDC16 hdc, LPRECT16 rc, UINT16 uType, UINT16 uState )
3367{
3368 RECT rect32;
3369 BOOL ret;
3370
3c39a991
AJ
3371 rect32.left = rc->left;
3372 rect32.top = rc->top;
3373 rect32.right = rc->right;
3374 rect32.bottom = rc->bottom;
ec5612ee 3375 ret = DrawFrameControl( HDC_32(hdc), &rect32, uType, uState );
3c39a991
AJ
3376 rc->left = rect32.left;
3377 rc->top = rect32.top;
3378 rc->right = rect32.right;
3379 rc->bottom = rect32.bottom;
ec5612ee
MS
3380 return ret;
3381}
3382
3383/**********************************************************************
3384 * DrawEdge (USER.659)
3385 */
3386BOOL16 WINAPI DrawEdge16( HDC16 hdc, LPRECT16 rc, UINT16 edge, UINT16 flags )
3387{
3388 RECT rect32;
3389 BOOL ret;
3390
3c39a991
AJ
3391 rect32.left = rc->left;
3392 rect32.top = rc->top;
3393 rect32.right = rc->right;
3394 rect32.bottom = rc->bottom;
ec5612ee 3395 ret = DrawEdge( HDC_32(hdc), &rect32, edge, flags );
3c39a991
AJ
3396 rc->left = rect32.left;
3397 rc->top = rect32.top;
3398 rc->right = rect32.right;
3399 rc->bottom = rect32.bottom;
ec5612ee
MS
3400 return ret;
3401}
b6aad502
EP
3402
3403/**********************************************************************
7ef66af3 3404 * CheckMenuRadioItem (USER.666)
b6aad502 3405 */
7ef66af3
AJ
3406BOOL16 WINAPI CheckMenuRadioItem16(HMENU16 hMenu, UINT16 first, UINT16 last,
3407 UINT16 check, BOOL16 bypos)
b6aad502 3408{
7ef66af3 3409 return CheckMenuRadioItem( HMENU_32(hMenu), first, last, check, bypos );
b6aad502 3410}