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

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

Rewrote (Get)ClipCursor

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