source: trunk/src/user32/oslibres.cpp@ 6348

Last change on this file since 6348 was 6348, checked in by sandervl, 24 years ago

allocate more memory for GpiCreateBitmap (icon)

File size: 17.9 KB
Line 
1/* $Id: oslibres.cpp,v 1.16 2001-07-16 19:32:55 sandervl Exp $ */
2/*
3 * Window API wrappers for OS/2
4 *
5 *
6 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#define INCL_WIN
13#define INCL_PM
14#include <os2wrap.h>
15#include <stdlib.h>
16#include <string.h>
17
18#include <misc.h>
19#include <winconst.h>
20#include "oslibwin.h"
21#include "oslibutil.h"
22#include "oslibmsg.h"
23#include "oslibgdi.h"
24#include "oslibres.h"
25#include "pmwindow.h"
26
27#define DBG_LOCALLOG DBG_oslibres
28#include "dbglocal.h"
29
30//******************************************************************************
31//******************************************************************************
32HANDLE OSLibWinSetAccelTable(HWND hwnd, HANDLE hAccel, PVOID acceltemplate)
33{
34 HAB hab = WinQueryAnchorBlock(hwnd);
35
36 if(hAccel == 0) {
37 hAccel = WinCreateAccelTable(hab, (PACCELTABLE)acceltemplate);
38 if(hAccel == 0) {
39 dprintf(("OSLibWinSetAccelTable: WinCreateAccelTable returned 0"));
40 return FALSE;
41 }
42 }
43 if(WinSetAccelTable(hab, hAccel, hwnd) == TRUE) {
44 return hAccel;
45 }
46 else return 0;
47}
48#if 0
49//******************************************************************************
50//TODO: change search method for icon array (cxDesired, cyDesired)
51//TODO: PM rescales the icon internally!!! ($W(#*&$(*%&)
52//******************************************************************************
53HANDLE OSLibWinCreateIcon(PVOID iconbitmap, ULONG cxDesired, ULONG cyDesired)
54{
55 POINTERINFO pointerInfo = {0};
56 HBITMAP hbmColor, hbmMask;
57 BITMAPARRAYFILEHEADER2 *bafh = (BITMAPARRAYFILEHEADER2 *)iconbitmap;
58 BITMAPFILEHEADER2 *bfhBW;
59 BITMAPFILEHEADER2 *bfhColor;
60 HPS hps;
61 HANDLE hIcon;
62
63 if(iconbitmap == NULL) {
64 dprintf(("OSLibWinCreateIcon iconbitmap == NULL!!"));
65 return 0;
66 }
67 if(bafh->usType == BFT_BITMAPARRAY && bafh->cbSize == sizeof(BITMAPARRAYFILEHEADER2)) {
68 // search best icon for the current screen,
69 // TODO: maybe compare icon size with screen size.
70 // Some bugs with black/white Icons ?
71 BITMAPARRAYFILEHEADER2 *next, *found;
72 LONG bitcountScreen, bitcountIcon=-1, cxIcon=-1, cyIcon=-1;
73
74 HPS hps = WinGetPS(HWND_DESKTOP);
75 HDC hdc = GpiQueryDevice(hps);
76 DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1, &bitcountScreen);
77 WinReleasePS(hps);
78
79 next = found = bafh;
80 while(TRUE)
81 {
82 bfhColor = (BITMAPFILEHEADER2 *)((char *)&next->bfh2 + sizeof(RGB2)*2 + sizeof(BITMAPFILEHEADER2));
83 if(bfhColor->bmp2.cBitCount <= bitcountScreen &&
84 bfhColor->bmp2.cBitCount > bitcountIcon ||
85 (bfhColor->bmp2.cBitCount == bitcountIcon &&
86 (cxIcon < bfhColor->bmp2.cx || cyIcon < bfhColor->bmp2.cy)))
87 {
88 found = next;
89 bitcountIcon = bfhColor->bmp2.cBitCount;
90 cxIcon = bfhColor->bmp2.cx;
91 cyIcon = bfhColor->bmp2.cy;
92 }
93 if(next->offNext != 0)
94 next = (BITMAPARRAYFILEHEADER2 *) ((char *)bafh + next->offNext);
95 else
96 break;
97 }
98 bfhBW = &found->bfh2;
99 bfhColor = (BITMAPFILEHEADER2 *)((char *)bfhBW + sizeof(RGB2)*2 + sizeof(BITMAPFILEHEADER2));
100 }
101 else {//single icon
102 bfhBW = (BITMAPFILEHEADER2 *)iconbitmap;
103 bfhColor = (BITMAPFILEHEADER2 *)((char *)bfhBW + sizeof(RGB2)*2 + sizeof(BITMAPFILEHEADER2));
104 bafh = (BITMAPARRAYFILEHEADER2 *)bfhBW; //for calculation bitmap offset
105 }
106 hps = WinGetScreenPS(HWND_DESKTOP);
107
108 //Resize icon bitmap if requested size is different
109 if(cxDesired != bfhColor->bmp2.cx|| cyDesired != bfhColor->bmp2.cy)
110 {
111 BITMAPINFOHEADER2 infohdr = bfhColor->bmp2;
112
113 infohdr.cx = cxDesired;
114 infohdr.cy = cyDesired;
115 hbmColor = GpiCreateBitmap(hps, &infohdr, CBM_INIT,
116 (char *)bafh + bfhColor->offBits,
117 (BITMAPINFO2 *)&bfhColor->bmp2);
118 }
119 else {
120 hbmColor = GpiCreateBitmap(hps, &bfhColor->bmp2, CBM_INIT,
121 (char *)bafh + bfhColor->offBits,
122 (BITMAPINFO2 *)&bfhColor->bmp2);
123 }
124 if(hbmColor == GPI_ERROR) {
125 dprintf(("OSLibWinCreateIcon: GpiCreateBitmap failed!"));
126 WinReleasePS(hps);
127 return 0;
128 }
129 //Resize icon mask if requested size is different
130 if(cxDesired != bfhBW->bmp2.cx|| cyDesired*2 != bfhBW->bmp2.cy)
131 {
132 BITMAPINFOHEADER2 infohdr = bfhBW->bmp2;
133
134 infohdr.cx = cxDesired;
135 infohdr.cy = cyDesired;
136 hbmMask = GpiCreateBitmap(hps, &infohdr, CBM_INIT,
137 (char *)bafh + bfhBW->offBits,
138 (BITMAPINFO2 *)&bfhBW->bmp2);
139 }
140 else {
141 hbmMask = GpiCreateBitmap(hps, &bfhBW->bmp2, CBM_INIT,
142 (char *)bafh + bfhBW->offBits,
143 (BITMAPINFO2 *)&bfhBW->bmp2);
144 }
145 if(hbmMask == GPI_ERROR) {
146 dprintf(("OSLibWinCreateIcon: GpiCreateBitmap hbmMask failed!"));
147 GpiDeleteBitmap(hbmColor);
148 WinReleasePS(hps);
149 return 0;
150 }
151
152 pointerInfo.fPointer = FALSE; //icon
153 pointerInfo.xHotspot = bfhBW->xHotspot;
154 pointerInfo.yHotspot = bfhBW->yHotspot;
155 pointerInfo.hbmColor = hbmColor;
156 pointerInfo.hbmPointer = hbmMask;
157 hIcon = WinCreatePointerIndirect(HWND_DESKTOP, &pointerInfo);
158 if(hIcon == NULL) {
159 dprintf(("OSLibWinCreateIcon: WinCreatePointerIndirect failed!"));
160 }
161 GpiDeleteBitmap(hbmMask);
162 GpiDeleteBitmap(hbmColor);
163 WinReleasePS(hps);
164
165 return hIcon;
166}
167//******************************************************************************
168//TODO: change cursor size if required!! (cxDesired, cyDesired)
169//******************************************************************************
170HANDLE OSLibWinCreatePointer(PVOID cursorbitmap, ULONG cxDesired, ULONG cyDesired)
171{
172 POINTERINFO pointerInfo = {0};
173 HBITMAP hbmColor = 0, hbmMask = 0;
174 BITMAPARRAYFILEHEADER2 *bafh = (BITMAPARRAYFILEHEADER2 *)cursorbitmap;
175 BITMAPFILEHEADER2 *bfh = (BITMAPFILEHEADER2 *)cursorbitmap, *bfhColor = 0;
176 HPS hps;
177 HANDLE hPointer;
178
179 if(cursorbitmap == NULL) {
180 dprintf(("OSLibWinCreatePointer cursorbitmap == NULL!!"));
181 return 0;
182 }
183 if(bafh->usType == BFT_BITMAPARRAY && bafh->cbSize == sizeof(BITMAPARRAYFILEHEADER2)) {
184 bfh = &bafh->bfh2;
185 bfhColor = (BITMAPFILEHEADER2 *)((char *)bfh + sizeof(RGB2)*2 + sizeof(BITMAPFILEHEADER2));
186 }
187 else {//single cursor
188 bfh = (BITMAPFILEHEADER2 *)cursorbitmap;
189 bfhColor = (BITMAPFILEHEADER2 *)((char *)bfh + sizeof(RGB2)*2 + sizeof(BITMAPFILEHEADER2));
190 bafh = (BITMAPARRAYFILEHEADER2 *)bfh; //for calculation bitmap offset
191 }
192 //skip xor/and mask
193 hps = WinGetScreenPS(HWND_DESKTOP);
194 hbmMask = GpiCreateBitmap(hps, &bfh->bmp2, CBM_INIT,
195 (char *)bafh + bfh->offBits,
196 (BITMAPINFO2 *)&bfh->bmp2);
197 if(hbmMask == GPI_ERROR) {
198 dprintf(("OSLibWinCreatePointer: GpiCreateBitmap failed!"));
199 WinReleasePS(hps);
200 return 0;
201 }
202
203 if((ULONG)((char *)bafh+bfh->offBits) != (ULONG)bfhColor)
204 {//color bitmap present
205 hbmColor = GpiCreateBitmap(hps, &bfhColor->bmp2, CBM_INIT,
206 (char *)bafh + bfhColor->offBits,
207 (BITMAPINFO2 *)&bfhColor->bmp2);
208 if(hbmColor == GPI_ERROR) {
209 dprintf(("OSLibWinCreateIcon: GpiCreateBitmap failed!"));
210 GpiDeleteBitmap(hbmMask);
211 WinReleasePS(hps);
212 return 0;
213 }
214 }
215
216 pointerInfo.fPointer = TRUE;
217 pointerInfo.xHotspot = bfh->xHotspot;
218 pointerInfo.yHotspot = bfh->yHotspot;
219 pointerInfo.hbmColor = hbmColor;
220 pointerInfo.hbmPointer = hbmMask;
221 hPointer = WinCreatePointerIndirect(HWND_DESKTOP, &pointerInfo);
222
223 if(hPointer == NULL) {
224 dprintf(("OSLibWinCreatePointer: WinCreatePointerIndirect failed!"));
225 }
226 GpiDeleteBitmap(hbmMask);
227 if(hbmColor) GpiDeleteBitmap(hbmColor);
228 WinReleasePS(hps);
229 return hPointer;
230}
231#endif
232//******************************************************************************
233//NOTE: Depends on origin of bitmap data!!!
234// Assumes 1 bpp bitmaps have a top left origin and all others have a bottom left origin
235//******************************************************************************
236HANDLE OSLibWinCreatePointer(CURSORICONINFO *pInfo, char *pAndBits, BITMAP_W *pAndBmp, char *pXorBits,
237 BITMAP_W *pXorBmp, BOOL fCursor)
238{
239 POINTERINFO pointerInfo = {0};
240 HANDLE hPointer;
241 HBITMAP hbmColor = 0, hbmMask = 0;
242 BITMAPINFO2 *pBmpColor, *pBmpMask;
243 int masksize, colorsize, rgbsize, i;
244 HPS hps;
245 char *dest, *src;
246
247 hps = WinGetScreenPS(HWND_DESKTOP);
248 //SvL: 2*sizeof(RGB2) is enough, but GpiCreateBitmap seems to touch more
249 // memory. (Adobe Photoshop 6 running in the debugger)
250 masksize = sizeof(BITMAPINFO2) + (pAndBmp->bmHeight * 2 * pAndBmp->bmWidthBytes) + 16*sizeof(RGB2);
251 pBmpMask = (BITMAPINFO2 *)malloc(masksize);
252 if(pBmpMask == NULL) {
253 DebugInt3();
254 return 0;
255 }
256 memset(pBmpMask, 0, masksize);
257 pBmpMask->cbFix = sizeof(BITMAPINFOHEADER2);
258 pBmpMask->cx = (USHORT)pAndBmp->bmWidth;
259 pBmpMask->cy = (USHORT)pAndBmp->bmHeight*2;
260 pBmpMask->cPlanes = pAndBmp->bmPlanes;
261 pBmpMask->cBitCount = 1;
262 pBmpMask->ulCompression = BCA_UNCOMP;
263 pBmpMask->ulColorEncoding = BCE_RGB;
264 memset(&pBmpMask->argbColor[0], 0, sizeof(RGB2));
265 memset(&pBmpMask->argbColor[1], 0xff, sizeof(RGB)); //not the reserved byte
266 //Xor bits are already 0
267 //copy And bits (must reverse scanlines because origin is top left instead of bottom left)
268 src = pAndBits;
269 dest = ((char *)&pBmpMask->argbColor[2]) + (pAndBmp->bmHeight * 2 - 1) * (pAndBmp->bmWidthBytes);
270 for(i=0;i<pAndBmp->bmHeight;i++) {
271 memcpy(dest, src, pAndBmp->bmWidthBytes);
272 dest -= pAndBmp->bmWidthBytes;
273 src += pAndBmp->bmWidthBytes;
274 }
275 hbmMask = GpiCreateBitmap(hps, (BITMAPINFOHEADER2 *)pBmpMask, CBM_INIT,
276 (PBYTE)&pBmpMask->argbColor[2], pBmpMask);
277
278 if(hbmMask == GPI_ERROR) {
279 dprintf(("OSLibWinCreatePointer: GpiCreateBitmap failed!"));
280 WinReleasePS(hps);
281 free(pBmpMask);
282 return 0;
283 }
284 if(pXorBits)
285 {//color bitmap present
286 RGBQUAD *rgb;
287 RGB2 *os2rgb;
288
289 if(pXorBmp->bmBitsPixel <= 8)
290 rgbsize = (1<<pXorBmp->bmBitsPixel)*sizeof(RGB2);
291 else rgbsize = 0;
292
293 colorsize = sizeof(BITMAPINFO2) + (pXorBmp->bmHeight * pXorBmp->bmWidthBytes) + rgbsize;
294 pBmpColor = (BITMAPINFO2 *)malloc(colorsize);
295 if(pBmpColor == NULL) {
296 DebugInt3();
297 return 0;
298 }
299 memset(pBmpColor, 0, colorsize);
300 pBmpColor->cbFix = sizeof(BITMAPINFOHEADER2);
301 pBmpColor->cx = (USHORT)pXorBmp->bmWidth;
302 pBmpColor->cy = (USHORT)pXorBmp->bmHeight;
303 pBmpColor->cPlanes = pXorBmp->bmPlanes;
304 pBmpColor->cBitCount = pXorBmp->bmBitsPixel;
305 pBmpColor->ulCompression = BCA_UNCOMP;
306 pBmpColor->ulColorEncoding = BCE_RGB;
307
308 os2rgb = &pBmpColor->argbColor[0];
309 rgb = (RGBQUAD *)(pXorBits);
310
311 if(pXorBmp->bmBitsPixel <= 8) {
312 for(i=0;i<(1<<pXorBmp->bmBitsPixel);i++) {
313 os2rgb->bRed = rgb->rgbRed;
314 os2rgb->bBlue = rgb->rgbBlue;
315 os2rgb->bGreen = rgb->rgbGreen;
316 os2rgb++;
317 rgb++;
318 }
319 }
320
321 if(pXorBmp->bmBitsPixel == 1) {
322 //copy Xor bits (must reverse scanlines because origin is top left instead of bottom left)
323 src = (char *)rgb;
324 dest = ((char *)os2rgb) + (pXorBmp->bmHeight - 1) * pXorBmp->bmWidthBytes;
325 for(i=0;i<pXorBmp->bmHeight;i++) {
326 memcpy(dest, src, pXorBmp->bmWidthBytes);
327 dest -= pXorBmp->bmWidthBytes;
328 src += pXorBmp->bmWidthBytes;
329 }
330 }
331 else memcpy(os2rgb, rgb, pXorBmp->bmHeight * pXorBmp->bmWidthBytes);
332
333 hbmColor = GpiCreateBitmap(hps, (BITMAPINFOHEADER2 *)pBmpColor, CBM_INIT,
334 (PBYTE)os2rgb, pBmpColor);
335
336 if(hbmColor == GPI_ERROR) {
337 dprintf(("OSLibWinCreateIcon: GpiCreateBitmap failed!"));
338 GpiDeleteBitmap(hbmMask);
339 WinReleasePS(hps);
340 free(pBmpMask);
341 return 0;
342 }
343 }
344
345 pointerInfo.fPointer = fCursor; //FALSE = icon
346 pointerInfo.xHotspot = pInfo->ptHotSpot.x;
347 pointerInfo.yHotspot = mapY(pInfo->nHeight, pInfo->ptHotSpot.y);
348 pointerInfo.hbmColor = hbmColor;
349 pointerInfo.hbmPointer = hbmMask;
350 hPointer = WinCreatePointerIndirect(HWND_DESKTOP, &pointerInfo);
351
352 if(hPointer == NULL) {
353 dprintf(("OSLibWinCreateCursor: WinCreatePointerIndirect failed! (lasterr=%x)", WinGetLastError(GetThreadHAB())));
354 }
355 GpiDeleteBitmap(hbmMask);
356 if(hbmColor) GpiDeleteBitmap(hbmColor);
357 WinReleasePS(hps);
358
359 free(pBmpMask);
360 free(pBmpColor);
361 return hPointer;
362}
363//******************************************************************************
364//******************************************************************************
365HANDLE OSLibWinQuerySysIcon(ULONG type,INT w,INT h)
366{
367 ULONG os2type = 0;
368 HPOINTER hPointer;
369
370 switch(type) {
371 case IDI_APPLICATION_W:
372 os2type = SPTR_PROGRAM;
373 break;
374 case IDI_HAND_W:
375 os2type = SPTR_ICONWARNING;
376 break;
377 case IDI_QUESTION_W:
378 os2type = SPTR_ICONQUESTION;
379 break;
380 case IDI_EXCLAMATION_W:
381 os2type = SPTR_ICONWARNING;
382 break;
383 case IDI_ASTERISK_W:
384 os2type = SPTR_ICONINFORMATION;
385 break;
386 default:
387 return 0;
388 }
389
390 hPointer = WinQuerySysPointer(HWND_DESKTOP, os2type, TRUE);
391
392 if (hPointer)
393 {
394 INT sysW = WinQuerySysValue(HWND_DESKTOP,SV_CXICON),sysH = WinQuerySysValue(HWND_DESKTOP,SV_CYICON);
395
396 if (sysW != w || sysH != h)
397 {
398 POINTERINFO pi;
399
400 WinQueryPointerInfo(hPointer,&pi);
401 //CB: todo: change icon size
402
403 }
404 }
405
406 return hPointer;
407}
408//******************************************************************************
409//******************************************************************************
410HANDLE OSLibWinQuerySysPointer(ULONG type,INT w,INT h)
411{
412 ULONG os2type = 0;
413
414 switch(type) {
415 case IDC_ARROW_W:
416 os2type = SPTR_ARROW;
417 break;
418 case IDC_UPARROW_W:
419 os2type = SPTR_ARROW;
420 break;
421 case IDC_IBEAM_W:
422 os2type = SPTR_TEXT;
423 break;
424 case IDC_ICON_W:
425 os2type = SPTR_PROGRAM;
426 break;
427 case IDC_NO_W:
428 os2type = SPTR_ILLEGAL;
429 break;
430 case IDC_CROSS_W:
431 os2type = SPTR_MOVE;
432 break;
433 case IDC_SIZE_W:
434 os2type = SPTR_MOVE;
435 break;
436 case IDC_SIZEALL_W:
437 os2type = SPTR_MOVE;
438 break;
439 case IDC_SIZENESW_W:
440 os2type = SPTR_SIZENESW;
441 break;
442 case IDC_SIZENS_W:
443 os2type = SPTR_SIZENS;
444 break;
445 case IDC_SIZENWSE_W:
446 os2type = SPTR_SIZENWSE;
447 break;
448 case IDC_SIZEWE_W:
449 os2type = SPTR_SIZEWE;
450 break;
451 case IDC_WAIT_W:
452 os2type = SPTR_WAIT;
453 break;
454 case IDC_APPSTARTING_W:
455 os2type = SPTR_WAIT;
456 break;
457 case IDC_HELP_W: //TODO: Create a cursor for this one
458 os2type = SPTR_WAIT;
459 break;
460 default:
461 return 0;
462 }
463 //Note: Does not create a copy
464 return WinQuerySysPointer(HWND_DESKTOP, os2type, FALSE);
465}
466//******************************************************************************
467//******************************************************************************
468VOID OSLibWinDestroyPointer(HANDLE hPointer)
469{
470 WinDestroyPointer(hPointer);
471}
472//******************************************************************************
473//******************************************************************************
474BOOL OSLibWinSetPointer(HANDLE hPointer)
475{
476 return WinSetPointer(HWND_DESKTOP, hPointer);
477}
478//******************************************************************************
479//******************************************************************************
480HANDLE OSLibWinQueryPointer()
481{
482 return WinQueryPointer(HWND_DESKTOP);
483}
484//******************************************************************************
485//******************************************************************************
486BOOL OSLibWinClipCursor(const RECT * pRect)
487{
488 RECTL rectl;
489 PRECTL ptr = NULL;
490
491 if (pRect != NULL)
492 {
493 rectl.xLeft = max(pRect->left, 0);
494 rectl.xRight = min(pRect->right, ScreenWidth-1);
495 rectl.yBottom = max(ScreenHeight - pRect->bottom, 0);
496 rectl.yTop = min(ScreenHeight - pRect->top, ScreenHeight-1);
497 ptr = &rectl;
498 }
499 return WinSetPointerClipRect (HWND_DESKTOP, ptr);
500}
501//******************************************************************************
502//******************************************************************************
503BOOL OSLibWinGetClipCursor(LPRECT pRect)
504{
505 RECTL rectl;
506
507 if (WinQueryPointerClipRect(HWND_DESKTOP, &rectl))
508 {
509 pRect->left = rectl.xLeft;
510 pRect->right = rectl.xRight;
511 pRect->bottom = ScreenHeight - rectl.yBottom;
512 pRect->top = ScreenHeight - rectl.yTop;
513 return TRUE;
514 }
515 return FALSE;
516}
517//******************************************************************************
518//******************************************************************************
Note: See TracBrowser for help on using the repository browser.