source: trunk/src/user32/loadres.cpp@ 10367

Last change on this file since 10367 was 9796, checked in by sandervl, 23 years ago

update for new WGSS

File size: 19.0 KB
Line 
1/* $Id: loadres.cpp,v 1.41 2003-02-13 13:10:49 sandervl Exp $ */
2
3/*
4 * Win32 resource API functions for OS/2
5 *
6 * Copyright 1998 Sander van Leeuwen
7 *
8 * Parts based on Wine code (objects\bitmap.c, loader\resource.c, objects\cursoricon.c):
9 *
10 * Copyright 1993 Alexandre Julliard
11 * 1993 Robert J. Amstadt
12 * 1996 Martin Von Loewis
13 * 1997 Alex Korobka
14 * 1998 Turchanov Sergey
15 * 1998 Huw D M Davies
16 *
17 * Project Odin Software License can be found in LICENSE.TXT
18 *
19 */
20#include <os2win.h>
21#include <user32.h>
22#include <heapstring.h>
23#include <oslibres.h>
24#include <win\virtual.h>
25#include "dib.h"
26#include "initterm.h"
27#include <winres.h>
28#include <custombuild.h>
29#include "pmwindow.h"
30
31#define DBG_LOCALLOG DBG_loadres
32#include "dbglocal.h"
33
34//******************************************************************************
35//******************************************************************************
36INT WIN32API LoadStringA(HINSTANCE instance, UINT resource_id,
37 LPSTR buffer, INT buflen )
38{
39 INT retval;
40 LPWSTR buffer2 = NULL;
41
42 if (buffer && buflen)
43 buffer2 = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, buflen * 2 );
44
45 retval = LoadStringW(instance,resource_id,buffer2,buflen);
46
47 if (buffer2)
48 {
49 if (retval) {
50 lstrcpynWtoA( buffer, buffer2, buflen );
51 retval = lstrlenA( buffer );
52 }
53 else
54 *buffer = 0; //NT4, SP6 clears first character
55 HeapFree( GetProcessHeap(), 0, buffer2 );
56 }
57 return retval;
58}
59//******************************************************************************
60//******************************************************************************
61int WIN32API LoadStringW(HINSTANCE hinst, UINT wID, LPWSTR lpBuffer, int cchBuffer)
62{
63 WCHAR *p;
64 int string_num;
65 int i = 0;
66 HRSRC hRes;
67
68 /* Use bits 4 - 19 (incremented by 1) as resourceid, mask out
69 * 20 - 31. */
70 hRes = FindResourceW(hinst, (LPWSTR)(((wID>>4)&0xffff)+1), RT_STRINGW);
71 if(hRes == NULL) {
72 dprintf(("LoadStringW NOT FOUND from %X, id %d buffersize %d\n", hinst, wID, cchBuffer));
73 *lpBuffer = 0; //NT4, SP6 clears first character
74 return 0;
75 }
76
77 p = (LPWSTR)LockResource(LoadResource(hinst, hRes));
78 if(p) {
79 string_num = wID & 0x000f;
80 for (i = 0; i < string_num; i++)
81 p += *p + 1;
82
83 if (lpBuffer == NULL) return *p;
84 i = min(cchBuffer - 1, *p);
85 if (i > 0) {
86 memcpy(lpBuffer, p + 1, i * sizeof (WCHAR));
87 lpBuffer[i] = (WCHAR) 0;
88 }
89 else {
90 if (cchBuffer > 1) {
91 lpBuffer[0] = (WCHAR) 0; //NT4, SP6 clears first character
92 return 0;
93 }
94 }
95 }
96
97 if(i) {
98 dprintf(("LoadStringW from %X, id %d %ls buffersize %d", hinst, wID, lpBuffer, cchBuffer));
99 }
100 else dprintf(("LoadStringW from %X, id %d buffersize %d", hinst, wID, cchBuffer));
101 return(i);
102}
103//******************************************************************************
104//******************************************************************************
105HICON WIN32API LoadIconA(HINSTANCE hinst, LPCSTR lpszIcon)
106{
107 if(HIWORD(lpszIcon)) {
108 dprintf(("LoadIconA %x %s", hinst, lpszIcon));
109 }
110 else dprintf(("LoadIconA %x %x", hinst, lpszIcon));
111 return LoadImageA(hinst, lpszIcon, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
112}
113//******************************************************************************
114//******************************************************************************
115HICON WIN32API LoadIconW(HINSTANCE hinst, LPCWSTR lpszIcon)
116{
117 if(HIWORD(lpszIcon)) {
118 dprintf(("LoadIconW %x %ls", hinst, lpszIcon));
119 }
120 else dprintf(("LoadIconW %x %x", hinst, lpszIcon));
121 return LoadImageW(hinst, lpszIcon, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
122}
123//******************************************************************************
124//******************************************************************************
125HCURSOR WIN32API LoadCursorA(HINSTANCE hinst, LPCSTR lpszCursor)
126{
127 return LoadImageA(hinst, lpszCursor, IMAGE_CURSOR, 0, 0,
128 LR_SHARED | LR_DEFAULTSIZE );
129}
130//******************************************************************************
131//******************************************************************************
132HCURSOR WIN32API LoadCursorW(HINSTANCE hinst, LPCWSTR lpszCursor)
133{
134 return LoadImageW(hinst, lpszCursor, IMAGE_CURSOR, 0, 0,
135 LR_SHARED | LR_DEFAULTSIZE );
136}
137/***********************************************************************
138* LoadCursorFromFileW (USER32.361)
139*/
140HCURSOR WIN32API LoadCursorFromFileW (LPCWSTR name)
141{
142 return LoadImageW(0, name, IMAGE_CURSOR, 0, 0,
143 LR_LOADFROMFILE | LR_DEFAULTSIZE );
144}
145/***********************************************************************
146* LoadCursorFromFileA (USER32.360)
147*/
148HCURSOR WIN32API LoadCursorFromFileA (LPCSTR name)
149{
150 return LoadImageA(0, name, IMAGE_CURSOR, 0, 0,
151 LR_LOADFROMFILE | LR_DEFAULTSIZE );
152}
153//******************************************************************************
154//NOTE: LR_CREATEDIBSECTION flag doesn't work (crash in GDI32)! (still??)
155//******************************************************************************
156HANDLE LoadBitmapW(HINSTANCE hinst, LPCWSTR lpszName, int cxDesired, int cyDesired,
157 UINT fuLoad)
158{
159 HBITMAP hbitmap = 0;
160 HDC hdc;
161 HRSRC hRsrc;
162 HGLOBAL handle, hMapping = 0;
163 char *ptr = NULL;
164 BITMAPINFO *info, *fix_info=NULL;
165 HGLOBAL hFix;
166 int size;
167
168 //if in OS/2 mode, then we must replace the standard button bitmaps
169 //(min, max, restore, close)
170 if(fOS2Look && (hinst == hInstanceUser32 || !hinst)) {
171 switch((ULONG)lpszName) {
172 case OBM_CLOSE:
173 return CopyImage(hBmpCloseButton, IMAGE_BITMAP, 0, 0, 0);
174 case OBM_CLOSED:
175 return CopyImage(hBmpCloseButtonDown, IMAGE_BITMAP, 0, 0, 0);
176 case OBM_RESTORE:
177 return CopyImage(hBmpRestoreButton, IMAGE_BITMAP, 0, 0, 0);
178 case OBM_RESTORED:
179 return CopyImage(hBmpRestoreButtonDown, IMAGE_BITMAP, 0, 0, 0);
180 case OBM_REDUCE:
181 return CopyImage(hBmpMinButton, IMAGE_BITMAP, 0, 0, 0);
182 case OBM_REDUCED:
183 return CopyImage(hBmpMinButtonDown, IMAGE_BITMAP, 0, 0, 0);
184 case OBM_ZOOM:
185 return CopyImage(hBmpMaxButton, IMAGE_BITMAP, 0, 0, 0);
186 case OBM_ZOOMD:
187 return CopyImage(hBmpMaxButtonDown, IMAGE_BITMAP, 0, 0, 0);
188 }
189 }
190 if (!(fuLoad & LR_LOADFROMFILE))
191 {
192 handle = 0;
193 if(!hinst)
194 {
195 hRsrc = FindResourceW( hInstanceUser32, lpszName, RT_BITMAPW );
196 if(hRsrc) {
197 handle = LoadResource( hInstanceUser32, hRsrc );
198 }
199 }
200 if(handle == 0)
201 {
202 if (!(hRsrc = FindResourceW( hinst, lpszName, RT_BITMAPW ))) return 0;
203 if (!(handle = LoadResource( hinst, hRsrc ))) return 0;
204 }
205
206 if ((info = (BITMAPINFO *)LockResource( handle )) == NULL) return 0;
207 }
208 else
209 {
210 hMapping = VIRTUAL_MapFileW( lpszName, (LPVOID *)&ptr, TRUE);
211 if (hMapping == INVALID_HANDLE_VALUE) {
212 //TODO: last err set to ERROR_OPEN_FAILED if file not found; correct??
213 dprintf(("LoadBitmapW: failed to load file %x (lasterr=%x)", lpszName, GetLastError()));
214 return 0;
215 }
216 info = (BITMAPINFO *)(ptr + sizeof(BITMAPFILEHEADER));
217 }
218
219 //TODO: This has to be removed once pe2lx stores win32 resources!!!
220 if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER) &&
221 info->bmiHeader.biSize != sizeof(BITMAPINFOHEADER))
222 {//assume it contains a file header first
223 info = (BITMAPINFO *)((char *)info + sizeof(BITMAPFILEHEADER));
224 }
225
226 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
227 {//determine size of converted header
228 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
229
230 int colors = 0;
231 if (core->bcBitCount <= 8) {
232 colors = (1 << core->bcBitCount);
233 }
234 size = sizeof(BITMAPINFOHEADER) + colors * sizeof(RGBQUAD);
235 }
236 else size = DIB_BitmapInfoSize(info, DIB_RGB_COLORS);
237
238 if ((hFix = GlobalAlloc(0, size)) != NULL) fix_info = (BITMAPINFO *)GlobalLock(hFix);
239 if (fix_info)
240 {
241 BYTE pix;
242
243 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
244 {//convert old bitmap header to new format
245 ULONG colors;
246 ULONG *p, *q;
247
248 memset (fix_info, 0, sizeof (BITMAPINFOHEADER));
249 fix_info->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
250 fix_info->bmiHeader.biWidth = ((BITMAPCOREHEADER *)info)->bcWidth;
251 fix_info->bmiHeader.biHeight = ((BITMAPCOREHEADER *)info)->bcHeight;
252 fix_info->bmiHeader.biPlanes = ((BITMAPCOREHEADER *)info)->bcPlanes;
253 fix_info->bmiHeader.biBitCount = ((BITMAPCOREHEADER *)info)->bcBitCount;
254
255 if(fix_info->bmiHeader.biBitCount <= 8)
256 {
257 p = (PULONG)((char *)info + sizeof(BITMAPCOREHEADER));
258 q = (PULONG)((char *)fix_info + sizeof(BITMAPINFOHEADER));
259 //convert RGBTRIPLE to RGBQUAD
260 for (colors = 1 << fix_info->bmiHeader.biBitCount; colors > 0; colors--) {
261 *q = *p & 0x00FFFFFFUL;
262 q++;
263 p = (PULONG)((char *)p + sizeof (RGBTRIPLE));
264 }
265 }
266 }
267 else {
268 memcpy(fix_info, info, size);
269 }
270
271 size = DIB_BitmapInfoSize(info, DIB_RGB_COLORS);
272
273 pix = *((LPBYTE)info + size);
274 DIB_FixColorsToLoadflags(fix_info, fuLoad, pix);
275 if ((hdc = CreateCompatibleDC(0)) != 0)
276 {
277 char *bits = (char *)info + size;
278 if (fuLoad & LR_CREATEDIBSECTION) {
279 DIBSECTION dib;
280 hbitmap = CreateDIBSection(hdc, fix_info, DIB_RGB_COLORS, NULL, 0, 0);
281 GetObjectA(hbitmap, sizeof(DIBSECTION), &dib);
282 SetDIBits(hdc, hbitmap, 0, dib.dsBm.bmHeight, bits, info,
283 DIB_RGB_COLORS);
284 }
285 else
286 {
287#if 0
288 if(fix_info->bmiHeader.biBitCount == 1) {
289 hbitmap = CreateBitmap(fix_info->bmiHeader.biWidth,
290 fix_info->bmiHeader.biHeight,
291 fix_info->bmiHeader.biPlanes,
292 fix_info->bmiHeader.biBitCount,
293 (PVOID)bits);
294 }
295 else {
296#endif
297 hbitmap = CreateDIBitmap(hdc, &fix_info->bmiHeader, CBM_INIT,
298 bits, fix_info, DIB_RGB_COLORS );
299// }
300 if(hbitmap == 0) {
301 dprintf(("LoadBitmapW: CreateDIBitmap failed!!"));
302 }
303 }
304 DeleteDC(hdc);
305 }
306 GlobalUnlock(hFix);
307 GlobalFree(hFix);
308 }
309 if(fuLoad & LR_LOADFROMFILE) {
310 UnmapViewOfFile(ptr);
311 CloseHandle(hMapping);
312 }
313 return hbitmap;
314}
315//******************************************************************************
316//TODO: scale bitmap
317//******************************************************************************
318HANDLE CopyBitmap(HANDLE hBitmap, DWORD desiredx, DWORD desiredy)
319{
320 HBITMAP res = 0;
321 BITMAP bm;
322
323 if(GetObjectA(hBitmap, sizeof(BITMAP), &bm) == FALSE) {
324 dprintf(("CopyBitmap: GetObject failed!!"));
325 return 0;
326 }
327
328#ifdef __WIN32OS2__
329 BITMAPINFO* pInfo;
330 HBITMAP oldbmp;
331 HDC hdc;
332 int colortablesize, bmpsize, headersize;
333 char *pBitmapData;
334
335 colortablesize = 0;
336
337 if(bm.bmBitsPixel <= 8) {
338 colortablesize = sizeof(RGBQUAD)*(1<<bm.bmBitsPixel);
339 }
340 bmpsize = DIB_GetDIBImageBytes(bm.bmWidth, bm.bmHeight, bm.bmBitsPixel);
341 headersize = sizeof(BITMAPINFO)+colortablesize+3*sizeof(DWORD); //+ extra space for > 8bpp images
342
343 pInfo = (BITMAPINFO *)malloc(headersize+bmpsize);
344 if(pInfo == NULL) {
345 DebugInt3();
346 return 0;
347 }
348 pBitmapData = (char*)((char *)pInfo + headersize);
349 memset(pInfo, 0, headersize+bmpsize);
350
351 hdc = CreateCompatibleDC(0);
352
353 pInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
354 pInfo->bmiHeader.biPlanes = bm.bmPlanes;
355 pInfo->bmiHeader.biBitCount = bm.bmBitsPixel;
356 pInfo->bmiHeader.biWidth = bm.bmWidth;
357 pInfo->bmiHeader.biHeight = bm.bmHeight;
358
359 GetDIBits(hdc, hBitmap, 0, bm.bmHeight, pBitmapData, pInfo, DIB_RGB_COLORS);
360
361 res = CreateDIBitmap(hdc, &pInfo->bmiHeader, CBM_INIT, pBitmapData,
362 pInfo, DIB_RGB_COLORS );
363
364 DeleteDC(hdc);
365 free(pInfo);
366#else
367 bm.bmBits = NULL;
368 res = CreateBitmapIndirect(&bm);
369
370 if(res)
371 {
372 char *buf = (char *)HeapAlloc( GetProcessHeap(), 0, bm.bmWidthBytes *
373 bm.bmHeight );
374 GetBitmapBits (hBitmap, bm.bmWidthBytes * bm.bmHeight, buf);
375 SetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf);
376 HeapFree( GetProcessHeap(), 0, buf );
377 }
378#endif
379 return res;
380}
381//******************************************************************************
382//TODO: No support for RT_NEWBITMAP
383//******************************************************************************
384HBITMAP WIN32API LoadBitmapA(HINSTANCE hinst, LPCSTR lpszBitmap)
385{
386 HBITMAP hBitmap = 0;
387
388 hBitmap = LoadImageA(hinst, lpszBitmap, IMAGE_BITMAP, 0, 0, 0);
389
390 if(HIWORD(lpszBitmap)) {
391 dprintf(("LoadBitmapA %x %s returned %08xh\n", hinst, lpszBitmap, hBitmap));
392 }
393 else dprintf(("LoadBitmapA %x %x returned %08xh\n", hinst, lpszBitmap, hBitmap));
394
395 return(hBitmap);
396}
397//******************************************************************************
398//TODO: No support for RT_NEWBITMAP
399//******************************************************************************
400HBITMAP WIN32API LoadBitmapW(HINSTANCE hinst, LPCWSTR lpszBitmap)
401{
402 HBITMAP hBitmap = 0;
403
404 hBitmap = LoadBitmapW((hinst == 0) ? hInstanceUser32:hinst, lpszBitmap, 0, 0, 0);
405
406 if(HIWORD(lpszBitmap)) {
407 dprintf(("LoadBitmapW %x %ls returned %08xh\n", hinst, lpszBitmap, hBitmap));
408 }
409 else dprintf(("LoadBitmapW %x %x returned %08xh\n", hinst, lpszBitmap, hBitmap));
410
411 return(hBitmap);
412}
413//******************************************************************************
414//******************************************************************************
415static PFNLOADIMAGEW pfnCustomLoadImageW = NULL;
416//******************************************************************************
417//Called by custom Odin builds to hook LoadImageW
418//******************************************************************************
419BOOL WIN32API SetCustomLoadImage(PFNLOADIMAGEW pfnLoadImageW)
420{
421 pfnCustomLoadImageW = pfnLoadImageW;
422 return TRUE;
423}
424//******************************************************************************
425//******************************************************************************
426HANDLE WIN32API LoadImageA(HINSTANCE hinst, LPCSTR lpszName, UINT uType,
427 int cxDesired, int cyDesired, UINT fuLoad)
428{
429 HANDLE res = 0;
430 LPCWSTR u_name;
431
432 if(HIWORD(lpszName)) {
433 dprintf(("LoadImageA %x %s %d (%d,%d)\n", hinst, lpszName, uType, cxDesired, cyDesired));
434 }
435 else dprintf(("LoadImageA %x %x %d (%d,%d)\n", hinst, lpszName, uType, cxDesired, cyDesired));
436
437 if (HIWORD(lpszName)) {
438 u_name = HEAP_strdupAtoW(GetProcessHeap(), 0, lpszName);
439 }
440 else u_name=(LPWSTR)lpszName;
441
442 res = LoadImageW(hinst, u_name, uType, cxDesired, cyDesired, fuLoad);
443
444 if (HIWORD(lpszName))
445 HeapFree(GetProcessHeap(), 0, (LPVOID)u_name);
446
447 return res;
448}
449//******************************************************************************
450//******************************************************************************
451HANDLE WIN32API LoadImageW(HINSTANCE hinst, LPCWSTR lpszName, UINT uType,
452 int cxDesired, int cyDesired, UINT fuLoad)
453{
454 HANDLE hRet = 0;
455
456 if(pfnCustomLoadImageW) {
457 pfnCustomLoadImageW(&hinst, (LPWSTR *)&lpszName, &uType);
458 }
459
460 if(HIWORD(lpszName)) {
461 dprintf(("LoadImageW %x %ls %d (%d,%d)\n", hinst, lpszName, uType, cxDesired, cyDesired));
462 }
463 else dprintf(("LoadImageW %x %x %d (%d,%d)\n", hinst, lpszName, uType, cxDesired, cyDesired));
464
465 if (fuLoad & LR_DEFAULTSIZE) {
466 if (uType == IMAGE_ICON) {
467 if (!cxDesired) cxDesired = GetSystemMetrics(SM_CXICON);
468 if (!cyDesired) cyDesired = GetSystemMetrics(SM_CYICON);
469 }
470 else if (uType == IMAGE_CURSOR) {
471 if (!cxDesired) cxDesired = GetSystemMetrics(SM_CXCURSOR);
472 if (!cyDesired) cyDesired = GetSystemMetrics(SM_CYCURSOR);
473 }
474 }
475 if (fuLoad & LR_LOADFROMFILE) fuLoad &= ~LR_SHARED;
476
477 switch (uType)
478 {
479 case IMAGE_BITMAP:
480 {
481 hRet = (HANDLE)LoadBitmapW(hinst, lpszName, cxDesired, cyDesired, fuLoad);
482 break;
483 }
484 case IMAGE_ICON:
485 {
486#ifdef __WIN32OS2__
487 ULONG palEnts = (1 << ScreenBitsPerPel);
488#else
489 HDC hdc = GetDC(0);
490 UINT palEnts = GetSystemPaletteEntries(hdc, 0, 0, NULL);
491 if (palEnts == 0)
492 palEnts = 256;
493 ReleaseDC(0, hdc);
494#endif
495
496 hRet = CURSORICON_Load(hinst, lpszName, cxDesired, cyDesired, palEnts, FALSE, fuLoad);
497 break;
498 }
499
500 case IMAGE_CURSOR:
501 return CURSORICON_Load(hinst, lpszName, cxDesired, cyDesired, 1, TRUE, fuLoad);
502
503 default:
504 dprintf(("LoadImageW: unsupported type %d!!", uType));
505 return 0;
506 }
507 dprintf(("LoadImageW returned %x\n", (int)hRet));
508
509 return(hRet);
510}
511/******************************************************************************
512 * CopyImage32 [USER32.61] Creates new image and copies attributes to it
513 *
514 * PARAMS
515 * hnd [I] Handle to image to copy
516 * type [I] Type of image to copy
517 * desiredx [I] Desired width of new image
518 * desiredy [I] Desired height of new image
519 * flags [I] Copy flags
520 *
521 * RETURNS
522 * Success: Handle to newly created image
523 * Failure: NULL
524 *
525 * FIXME: implementation still lacks nearly all features, see LR_*
526 * defines in windows.h
527 *
528 */
529HICON WINAPI CopyImage(HANDLE hnd, UINT type, INT desiredx,
530 INT desiredy, UINT flags )
531{
532 dprintf(("CopyImage %x %d (%d,%d) %x", hnd, type, desiredx, desiredy, flags));
533 switch (type)
534 {
535 case IMAGE_BITMAP:
536 return CopyBitmap(hnd, desiredx, desiredy);
537 case IMAGE_ICON:
538 return (HANDLE)CURSORICON_ExtCopy(hnd, type, desiredx, desiredy, flags);
539 case IMAGE_CURSOR:
540 /* Should call CURSORICON_ExtCopy but more testing
541 * needs to be done before we change this
542 */
543 return CURSORICON_ExtCopy(hnd,type, desiredx, desiredy, flags);
544 default:
545 dprintf(("CopyImage: Unsupported type"));
546 }
547 return 0;
548}
549//******************************************************************************
550//******************************************************************************
Note: See TracBrowser for help on using the repository browser.