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

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

Allocate space the two missing RGB2 entries

File size: 28.4 KB
Line 
1/* $Id: oslibres.cpp,v 1.31 2002-06-25 07:11:10 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 <stdio.h>
17#include <string.h>
18
19#include <misc.h>
20#include <winconst.h>
21#include "oslibwin.h"
22#include "oslibutil.h"
23#include "oslibmsg.h"
24#include "oslibgdi.h"
25#include "oslibres.h"
26#include "pmwindow.h"
27#include <wingdi32.h>
28
29#define DBG_LOCALLOG DBG_oslibres
30#include "dbglocal.h"
31
32//******************************************************************************
33//******************************************************************************
34HANDLE OSLibWinSetAccelTable(HWND hwnd, HANDLE hAccel, PVOID acceltemplate)
35{
36 HAB hab = WinQueryAnchorBlock(hwnd);
37
38 if(hAccel == 0) {
39 hAccel = WinCreateAccelTable(hab, (PACCELTABLE)acceltemplate);
40 if(hAccel == 0) {
41 dprintf(("OSLibWinSetAccelTable: WinCreateAccelTable returned 0"));
42 return FALSE;
43 }
44 }
45 if(WinSetAccelTable(hab, hAccel, hwnd) == TRUE) {
46 return hAccel;
47 }
48 else return 0;
49}
50#if 0
51//******************************************************************************
52//TODO: change search method for icon array (cxDesired, cyDesired)
53//TODO: PM rescales the icon internally!!! ($W(#*&$(*%&)
54//******************************************************************************
55HANDLE OSLibWinCreateIcon(PVOID iconbitmap, ULONG cxDesired, ULONG cyDesired)
56{
57 POINTERINFO pointerInfo = {0};
58 HBITMAP hbmColor, hbmMask;
59 BITMAPARRAYFILEHEADER2 *bafh = (BITMAPARRAYFILEHEADER2 *)iconbitmap;
60 BITMAPFILEHEADER2 *bfhBW;
61 BITMAPFILEHEADER2 *bfhColor;
62 HPS hps;
63 HANDLE hIcon;
64
65 if(iconbitmap == NULL) {
66 dprintf(("OSLibWinCreateIcon iconbitmap == NULL!!"));
67 return 0;
68 }
69 if(bafh->usType == BFT_BITMAPARRAY && bafh->cbSize == sizeof(BITMAPARRAYFILEHEADER2)) {
70 // search best icon for the current screen,
71 // TODO: maybe compare icon size with screen size.
72 // Some bugs with black/white Icons ?
73 BITMAPARRAYFILEHEADER2 *next, *found;
74 LONG bitcountScreen, bitcountIcon=-1, cxIcon=-1, cyIcon=-1;
75
76 HPS hps = WinGetPS(HWND_DESKTOP);
77 HDC hdc = GpiQueryDevice(hps);
78 DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1, &bitcountScreen);
79 WinReleasePS(hps);
80
81 next = found = bafh;
82 while(TRUE)
83 {
84 bfhColor = (BITMAPFILEHEADER2 *)((char *)&next->bfh2 + sizeof(RGB2)*2 + sizeof(BITMAPFILEHEADER2));
85 if(bfhColor->bmp2.cBitCount <= bitcountScreen &&
86 bfhColor->bmp2.cBitCount > bitcountIcon ||
87 (bfhColor->bmp2.cBitCount == bitcountIcon &&
88 (cxIcon < bfhColor->bmp2.cx || cyIcon < bfhColor->bmp2.cy)))
89 {
90 found = next;
91 bitcountIcon = bfhColor->bmp2.cBitCount;
92 cxIcon = bfhColor->bmp2.cx;
93 cyIcon = bfhColor->bmp2.cy;
94 }
95 if(next->offNext != 0)
96 next = (BITMAPARRAYFILEHEADER2 *) ((char *)bafh + next->offNext);
97 else
98 break;
99 }
100 bfhBW = &found->bfh2;
101 bfhColor = (BITMAPFILEHEADER2 *)((char *)bfhBW + sizeof(RGB2)*2 + sizeof(BITMAPFILEHEADER2));
102 }
103 else {//single icon
104 bfhBW = (BITMAPFILEHEADER2 *)iconbitmap;
105 bfhColor = (BITMAPFILEHEADER2 *)((char *)bfhBW + sizeof(RGB2)*2 + sizeof(BITMAPFILEHEADER2));
106 bafh = (BITMAPARRAYFILEHEADER2 *)bfhBW; //for calculation bitmap offset
107 }
108 hps = WinGetScreenPS(HWND_DESKTOP);
109
110 //Resize icon bitmap if requested size is different
111 if(cxDesired != bfhColor->bmp2.cx|| cyDesired != bfhColor->bmp2.cy)
112 {
113 BITMAPINFOHEADER2 infohdr = bfhColor->bmp2;
114
115 infohdr.cx = cxDesired;
116 infohdr.cy = cyDesired;
117 hbmColor = GpiCreateBitmap(hps, &infohdr, CBM_INIT,
118 (char *)bafh + bfhColor->offBits,
119 (BITMAPINFO2 *)&bfhColor->bmp2);
120 }
121 else {
122 hbmColor = GpiCreateBitmap(hps, &bfhColor->bmp2, CBM_INIT,
123 (char *)bafh + bfhColor->offBits,
124 (BITMAPINFO2 *)&bfhColor->bmp2);
125 }
126 if(hbmColor == GPI_ERROR) {
127 dprintf(("OSLibWinCreateIcon: GpiCreateBitmap failed!"));
128 WinReleasePS(hps);
129 return 0;
130 }
131 //Resize icon mask if requested size is different
132 if(cxDesired != bfhBW->bmp2.cx|| cyDesired*2 != bfhBW->bmp2.cy)
133 {
134 BITMAPINFOHEADER2 infohdr = bfhBW->bmp2;
135
136 infohdr.cx = cxDesired;
137 infohdr.cy = cyDesired;
138 hbmMask = GpiCreateBitmap(hps, &infohdr, CBM_INIT,
139 (char *)bafh + bfhBW->offBits,
140 (BITMAPINFO2 *)&bfhBW->bmp2);
141 }
142 else {
143 hbmMask = GpiCreateBitmap(hps, &bfhBW->bmp2, CBM_INIT,
144 (char *)bafh + bfhBW->offBits,
145 (BITMAPINFO2 *)&bfhBW->bmp2);
146 }
147 if(hbmMask == GPI_ERROR) {
148 dprintf(("OSLibWinCreateIcon: GpiCreateBitmap hbmMask failed!"));
149 GpiDeleteBitmap(hbmColor);
150 WinReleasePS(hps);
151 return 0;
152 }
153
154 pointerInfo.fPointer = FALSE; //icon
155 pointerInfo.xHotspot = bfhBW->xHotspot;
156 pointerInfo.yHotspot = bfhBW->yHotspot;
157 pointerInfo.hbmColor = hbmColor;
158 pointerInfo.hbmPointer = hbmMask;
159 hIcon = WinCreatePointerIndirect(HWND_DESKTOP, &pointerInfo);
160 if(hIcon == NULL) {
161 dprintf(("OSLibWinCreateIcon: WinCreatePointerIndirect failed!"));
162 }
163 GpiDeleteBitmap(hbmMask);
164 GpiDeleteBitmap(hbmColor);
165 WinReleasePS(hps);
166
167 return hIcon;
168}
169//******************************************************************************
170//TODO: change cursor size if required!! (cxDesired, cyDesired)
171//******************************************************************************
172HANDLE OSLibWinCreatePointer(PVOID cursorbitmap, ULONG cxDesired, ULONG cyDesired)
173{
174 POINTERINFO pointerInfo = {0};
175 HBITMAP hbmColor = 0, hbmMask = 0;
176 BITMAPARRAYFILEHEADER2 *bafh = (BITMAPARRAYFILEHEADER2 *)cursorbitmap;
177 BITMAPFILEHEADER2 *bfh = (BITMAPFILEHEADER2 *)cursorbitmap, *bfhColor = 0;
178 HPS hps;
179 HANDLE hPointer;
180
181 if(cursorbitmap == NULL) {
182 dprintf(("OSLibWinCreatePointer cursorbitmap == NULL!!"));
183 return 0;
184 }
185 if(bafh->usType == BFT_BITMAPARRAY && bafh->cbSize == sizeof(BITMAPARRAYFILEHEADER2)) {
186 bfh = &bafh->bfh2;
187 bfhColor = (BITMAPFILEHEADER2 *)((char *)bfh + sizeof(RGB2)*2 + sizeof(BITMAPFILEHEADER2));
188 }
189 else {//single cursor
190 bfh = (BITMAPFILEHEADER2 *)cursorbitmap;
191 bfhColor = (BITMAPFILEHEADER2 *)((char *)bfh + sizeof(RGB2)*2 + sizeof(BITMAPFILEHEADER2));
192 bafh = (BITMAPARRAYFILEHEADER2 *)bfh; //for calculation bitmap offset
193 }
194 //skip xor/and mask
195 hps = WinGetScreenPS(HWND_DESKTOP);
196 hbmMask = GpiCreateBitmap(hps, &bfh->bmp2, CBM_INIT,
197 (char *)bafh + bfh->offBits,
198 (BITMAPINFO2 *)&bfh->bmp2);
199 if(hbmMask == GPI_ERROR) {
200 dprintf(("OSLibWinCreatePointer: GpiCreateBitmap failed!"));
201 WinReleasePS(hps);
202 return 0;
203 }
204
205 if((ULONG)((char *)bafh+bfh->offBits) != (ULONG)bfhColor)
206 {//color bitmap present
207 hbmColor = GpiCreateBitmap(hps, &bfhColor->bmp2, CBM_INIT,
208 (char *)bafh + bfhColor->offBits,
209 (BITMAPINFO2 *)&bfhColor->bmp2);
210 if(hbmColor == GPI_ERROR) {
211 dprintf(("OSLibWinCreateIcon: GpiCreateBitmap failed!"));
212 GpiDeleteBitmap(hbmMask);
213 WinReleasePS(hps);
214 return 0;
215 }
216 }
217
218 pointerInfo.fPointer = TRUE;
219 pointerInfo.xHotspot = bfh->xHotspot;
220 pointerInfo.yHotspot = bfh->yHotspot;
221 pointerInfo.hbmColor = hbmColor;
222 pointerInfo.hbmPointer = hbmMask;
223 hPointer = WinCreatePointerIndirect(HWND_DESKTOP, &pointerInfo);
224
225 if(hPointer == NULL) {
226 dprintf(("OSLibWinCreatePointer: WinCreatePointerIndirect failed!"));
227 }
228 GpiDeleteBitmap(hbmMask);
229 if(hbmColor) GpiDeleteBitmap(hbmColor);
230 WinReleasePS(hps);
231 return hPointer;
232}
233#endif
234//******************************************************************************
235//******************************************************************************
236BOOL isMonoBitmap(BITMAP_W *pXorBmp, PBYTE os2rgb)
237{
238 ULONG pixel, color[2];
239 char *bmpdata;
240 int i, j, nrcolors = 0, increment;
241
242 increment = pXorBmp->bmBitsPixel/8;
243
244 for(i=0;i<pXorBmp->bmHeight;i++) {
245 bmpdata = (char *)os2rgb;
246 for(j=0;j<pXorBmp->bmWidth;j++) {
247 pixel = 0;
248 memcpy(&pixel, os2rgb, increment);
249 if(nrcolors == 0) {
250 color[0] = pixel;
251 nrcolors = 1;
252 }
253 else
254 if(nrcolors == 1 && color[0] != pixel) {
255 color[1] = pixel;
256 nrcolors = 2;
257 }
258 else {
259 if(color[0] != pixel && color[1] != pixel)
260 {
261 return FALSE;
262 }
263 }
264 os2rgb += increment;
265 }
266 os2rgb = bmpdata + pXorBmp->bmWidthBytes;
267 }
268 return TRUE;
269}
270//******************************************************************************
271//******************************************************************************
272char *colorToMonoBitmap(HBITMAP bmpsrc, BITMAPINFO2 *pBmpDest)
273{
274 HDC hdcDest = 0; /* device context handle */
275 HPS hpsDest = 0;
276 SIZEL sizl = { 0, 0 }; /* use same page size as device */
277 DEVOPENSTRUC dop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
278 LONG lHits;
279 char *bmpbuffer = 0;
280 BITMAPINFO2 *bmpinfo = NULL;
281 HAB hab;
282
283 dprintf2(("Convert color bitmap to mono (%d,%d) %d", pBmpDest->cx, pBmpDest->cy, pBmpDest->cBitCount));
284
285 hab = GetThreadHAB();
286
287 /* create memory device context */
288 hdcDest = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
289
290 /* Create the presentation and associate the memory device
291 context. */
292 hpsDest = GpiCreatePS(hab, hdcDest, &sizl, PU_PELS |
293 GPIT_MICRO | GPIA_ASSOC);
294 if(!hpsDest) goto fail;
295
296 GpiSetBitmap(hpsDest, bmpsrc);
297
298 bmpinfo = (BITMAPINFO2 *)malloc(2*sizeof(BITMAPINFOHEADER2) + sizeof(RGB2));
299 bmpbuffer = (char *)malloc(pBmpDest->cy*pBmpDest->cx);
300 memset(bmpinfo, 0, sizeof(BITMAPINFOHEADER2) + sizeof(RGB2));
301 bmpinfo->cbFix = sizeof(BITMAPINFOHEADER2);
302 bmpinfo->cx = pBmpDest->cx;
303 bmpinfo->cy = pBmpDest->cy;
304 bmpinfo->cPlanes = 1;
305 bmpinfo->cBitCount = 1;
306 bmpinfo->ulCompression = BCA_UNCOMP;
307 bmpinfo->ulColorEncoding = BCE_RGB;
308
309 lHits = GpiQueryBitmapBits(hpsDest, 0, pBmpDest->cy, bmpbuffer, bmpinfo);
310 if(lHits == GPI_ERROR) goto fail;
311
312//#define DEBUG_CURSOR
313#ifdef DEBUG_CURSOR
314 {
315 dprintf(("colorToMonoBitmap %d %d (%x,%x,%x)(%x,%x,%x)", pBmpDest->cx, pBmpDest->cy, bmpinfo->argbColor[0].bRed, bmpinfo->argbColor[0].bGreen, bmpinfo->argbColor[0].bBlue, bmpinfo->argbColor[1].bRed, bmpinfo->argbColor[1].bGreen, bmpinfo->argbColor[1].bBlue));
316 for(int i=pBmpDest->cy-1;i>=0;i--) {
317 for(int j=0;j<pBmpDest->cx;j++) {
318 if(j<8) {
319 if((*(bmpbuffer+i*4)) & (1<<(7-j))) {
320 WriteLogNoEOL("X");
321 }
322 else WriteLogNoEOL(".");
323 }
324 else
325 if(j<16) {
326 if((*(bmpbuffer+1+i*4)) & (1<<(15-j))) {
327 WriteLogNoEOL("X");
328 }
329 else WriteLogNoEOL(".");
330 }
331 else
332 if(j<24) {
333 if((*(bmpbuffer+2+i*4)) & (1<<(23-j))) {
334 WriteLogNoEOL("X");
335 }
336 else WriteLogNoEOL(".");
337 }
338 else {
339 if((*(bmpbuffer+3+i*4)) & (1<<(31-j))) {
340 WriteLogNoEOL("X");
341 }
342 else WriteLogNoEOL(".");
343 }
344 }
345 WriteLogNoEOL("\n");
346 }
347}
348#endif
349
350 GpiSetBitmap(hpsDest, NULL);
351
352 GpiAssociate(hpsDest, NULLHANDLE); /* disassociate device context */
353 GpiDestroyPS(hpsDest); /* destroys presentation space */
354 DevCloseDC(hdcDest); /* closes device context */
355 free(bmpinfo);
356
357 return bmpbuffer;
358
359fail:
360 if(bmpinfo) free(bmpinfo);
361 if(bmpbuffer) free(bmpbuffer);
362
363 if(hpsDest) {
364 GpiSetBitmap(hpsDest, NULL);
365 GpiAssociate(hpsDest, NULLHANDLE); /* disassociate device context */
366 GpiDestroyPS(hpsDest); /* destroys presentation space */
367 }
368 if(hdcDest) DevCloseDC(hdcDest); /* closes device context */
369 return 0;
370}
371//******************************************************************************
372//******************************************************************************
373//NOTE: Depends on origin of bitmap data!!!
374// Assumes 1 bpp bitmaps have a top left origin and all others have a bottom left origin
375//******************************************************************************
376HANDLE OSLibWinCreatePointer(CURSORICONINFO *pInfo, char *pAndBits, BITMAP_W *pAndBmp, char *pXorBits,
377 BITMAP_W *pXorBmp, BOOL fCursor)
378{
379 POINTERINFO pointerInfo = {0};
380 HANDLE hPointer;
381 HBITMAP hbmColor = 0, hbmMask = 0;
382 BITMAPINFO2 *pBmpColor = 0, *pBmpMask = 0;
383 int masksize, colorsize, rgbsize, i;
384 HPS hps;
385 char *dest, *src, *pOS2XorBits = 0;
386
387 hps = WinGetScreenPS(HWND_DESKTOP);
388
389 if(pXorBits)
390 {//color bitmap present
391 RGBQUAD *rgb;
392 RGB2 *os2rgb;
393
394 if(pXorBmp->bmBitsPixel <= 8)
395 rgbsize = (1<<pXorBmp->bmBitsPixel)*sizeof(RGB2);
396 else rgbsize = 0;
397
398 colorsize = sizeof(BITMAPINFO2) + (pXorBmp->bmHeight * pXorBmp->bmWidthBytes) + rgbsize;
399 pBmpColor = (BITMAPINFO2 *)malloc(colorsize);
400 if(pBmpColor == NULL) {
401 DebugInt3();
402 return 0;
403 }
404 memset(pBmpColor, 0, colorsize);
405 pBmpColor->cbFix = sizeof(BITMAPINFOHEADER2);
406 pBmpColor->cx = (USHORT)pXorBmp->bmWidth;
407 pBmpColor->cy = (USHORT)pXorBmp->bmHeight;
408 pBmpColor->cPlanes = pXorBmp->bmPlanes;
409 pBmpColor->cBitCount = pXorBmp->bmBitsPixel;
410 pBmpColor->ulCompression = BCA_UNCOMP;
411 pBmpColor->ulColorEncoding = BCE_RGB;
412
413 os2rgb = &pBmpColor->argbColor[0];
414 rgb = (RGBQUAD *)(pXorBits);
415
416 if(pXorBmp->bmBitsPixel <= 8) {
417 for(i=0;i<(1<<pXorBmp->bmBitsPixel);i++) {
418 os2rgb->bRed = rgb->rgbRed;
419 os2rgb->bBlue = rgb->rgbBlue;
420 os2rgb->bGreen = rgb->rgbGreen;
421 os2rgb++;
422 rgb++;
423 }
424 }
425
426 if(pXorBmp->bmBitsPixel == 1) {
427 //copy Xor bits (must reverse scanlines because origin is top left instead of bottom left)
428 src = (char *)rgb;
429 dest = ((char *)os2rgb) + (pXorBmp->bmHeight - 1) * pXorBmp->bmWidthBytes;
430 for(i=0;i<pXorBmp->bmHeight;i++) {
431 memcpy(dest, src, pXorBmp->bmWidthBytes);
432 dest -= pXorBmp->bmWidthBytes;
433 src += pXorBmp->bmWidthBytes;
434 }
435 }
436 else
437 if(pXorBmp->bmBitsPixel == 16) {
438 ConvertRGB555to565(os2rgb, rgb, pXorBmp->bmHeight * pXorBmp->bmWidthBytes);
439 }
440 else memcpy(os2rgb, rgb, pXorBmp->bmHeight * pXorBmp->bmWidthBytes);
441
442 hbmColor = GpiCreateBitmap(hps, (BITMAPINFOHEADER2 *)pBmpColor, CBM_INIT,
443 (PBYTE)os2rgb, pBmpColor);
444
445 if(hbmColor == GPI_ERROR) {
446 dprintf(("OSLibWinCreateIcon: GpiCreateBitmap failed!"));
447 goto fail;
448 }
449 if(fCursor && pXorBmp->bmBitsPixel >= 8)
450 {
451 if(fForceMonoCursor || isMonoBitmap(pXorBmp, (PBYTE)os2rgb) == TRUE)
452 {
453 pOS2XorBits = colorToMonoBitmap(hbmColor, pBmpColor);
454 if(pOS2XorBits) {
455 GpiDeleteBitmap(hbmColor);
456 hbmColor = 0;
457 }
458 }
459 }
460 if(hbmColor) {
461 dprintf2(("OSLibWinCreatePointer: using real color cursor/icon (fCursor %d)", fCursor));
462 }
463 else dprintf2(("OSLibWinCreatePointer: converted color cursor/icon to mono (fCursor %d)", fCursor));
464 }
465
466 //SvL: 2*sizeof(RGB2) is enough, but GpiCreateBitmap seems to touch more
467 // memory. (Adobe Photoshop 6 running in the debugger)
468 //bird: We should reserve the amount required anythingelse is stupid.
469 // Looks like it's reading 3 bytes too much... Hopefully that's due to the
470 // &pBmpMask->argbColor[2] which it assumes is 16 colors long. But no proofs.
471 masksize = sizeof(BITMAPINFO2) + (pAndBmp->bmHeight * 2 * pAndBmp->bmWidthBytes) + (16+2)*sizeof(RGB2);
472 pBmpMask = (BITMAPINFO2 *)malloc(masksize);
473 if(pBmpMask == NULL) {
474 DebugInt3();
475 return 0;
476 }
477 memset(pBmpMask, 0, masksize);
478 pBmpMask->cbFix = sizeof(BITMAPINFOHEADER2);
479 pBmpMask->cx = (USHORT)pAndBmp->bmWidth;
480 pBmpMask->cy = (USHORT)pAndBmp->bmHeight*2;
481 pBmpMask->cPlanes = pAndBmp->bmPlanes;
482 pBmpMask->cBitCount = 1;
483 pBmpMask->ulCompression = BCA_UNCOMP;
484 pBmpMask->ulColorEncoding = BCE_RGB;
485 memset(&pBmpMask->argbColor[0], 0, sizeof(RGB2));
486 memset(&pBmpMask->argbColor[1], 0xff, sizeof(RGB)); //not the reserved byte
487 if(pOS2XorBits) {
488 dest = ((char *)&pBmpMask->argbColor[2]);
489 memcpy(dest, pOS2XorBits, pAndBmp->bmWidthBytes*pAndBmp->bmHeight);
490 free(pOS2XorBits);
491 pOS2XorBits = NULL;
492 }
493 // else Xor bits are already 0
494
495 //copy And bits (must reverse scanlines because origin is top left instead of bottom left)
496 src = pAndBits;
497 dest = ((char *)&pBmpMask->argbColor[2]) + (pAndBmp->bmHeight * 2 - 1) * (pAndBmp->bmWidthBytes);
498 for(i=0;i<pAndBmp->bmHeight;i++) {
499 memcpy(dest, src, pAndBmp->bmWidthBytes);
500 dest -= pAndBmp->bmWidthBytes;
501 src += pAndBmp->bmWidthBytes;
502 }
503 hbmMask = GpiCreateBitmap(hps, (BITMAPINFOHEADER2 *)pBmpMask, CBM_INIT,
504 (PBYTE)&pBmpMask->argbColor[2], pBmpMask);
505
506 if(hbmMask == GPI_ERROR) {
507 dprintf(("OSLibWinCreatePointer: GpiCreateBitmap failed!"));
508 goto fail;
509 }
510
511 pointerInfo.fPointer = fCursor; //FALSE = icon
512 pointerInfo.xHotspot = pInfo->ptHotSpot.x;
513 pointerInfo.yHotspot = mapY(pInfo->nHeight, pInfo->ptHotSpot.y);
514 pointerInfo.hbmColor = hbmColor;
515 pointerInfo.hbmPointer = hbmMask;
516 dprintf2(("WinCreatePointerIndirect %d (%d,%d) (org %d,%d)", pointerInfo.fPointer, pointerInfo.xHotspot, pointerInfo.yHotspot, pInfo->ptHotSpot.x, pInfo->ptHotSpot.y));
517 hPointer = WinCreatePointerIndirect(HWND_DESKTOP, &pointerInfo);
518
519 if(hPointer == NULL) {
520 dprintf(("OSLibWinCreateCursor: WinCreatePointerIndirect failed! (lasterr=%x)", WinGetLastError(GetThreadHAB())));
521 }
522 GpiDeleteBitmap(hbmMask);
523 if(hbmColor) GpiDeleteBitmap(hbmColor);
524 WinReleasePS(hps);
525
526 free(pBmpMask);
527 free(pBmpColor);
528
529 dprintf2(("OSLibWinCreatePointer: PM pointer %x", hPointer));
530 return hPointer;
531
532fail:
533 if(hbmMask) GpiDeleteBitmap(hbmMask);
534 if(hbmColor) GpiDeleteBitmap(hbmColor);
535 WinReleasePS(hps);
536 if(pBmpMask) free(pBmpMask);
537 if(pBmpColor) free(pBmpColor);
538 return 0;
539}
540//******************************************************************************
541//******************************************************************************
542HANDLE OSLibWinQuerySysIcon(ULONG type,INT w,INT h)
543{
544 ULONG os2type = 0;
545 HPOINTER hPointer;
546
547 switch(type) {
548 case IDI_APPLICATION_W:
549 os2type = SPTR_PROGRAM;
550 break;
551 case IDI_HAND_W:
552 os2type = SPTR_ICONWARNING;
553 break;
554 case IDI_QUESTION_W:
555 os2type = SPTR_ICONQUESTION;
556 break;
557 case IDI_EXCLAMATION_W:
558 os2type = SPTR_ICONWARNING;
559 break;
560 case IDI_ASTERISK_W:
561 os2type = SPTR_ICONINFORMATION;
562 break;
563 default:
564 return 0;
565 }
566
567 hPointer = WinQuerySysPointer(HWND_DESKTOP, os2type, TRUE);
568
569 if (hPointer)
570 {
571 INT sysW = WinQuerySysValue(HWND_DESKTOP,SV_CXICON),sysH = WinQuerySysValue(HWND_DESKTOP,SV_CYICON);
572
573 if (sysW != w || sysH != h)
574 {
575 POINTERINFO pi;
576
577 WinQueryPointerInfo(hPointer,&pi);
578 //CB: todo: change icon size
579
580 }
581 }
582
583 return hPointer;
584}
585//******************************************************************************
586//******************************************************************************
587HANDLE OSLibWinQuerySysPointer(ULONG type,INT w,INT h)
588{
589 ULONG os2type = 0;
590
591 switch(type) {
592 case IDC_ARROW_W:
593 os2type = SPTR_ARROW;
594 break;
595 case IDC_UPARROW_W:
596 os2type = SPTR_ARROW;
597 break;
598 case IDC_IBEAM_W:
599 os2type = SPTR_TEXT;
600 break;
601 case IDC_ICON_W:
602 os2type = SPTR_PROGRAM;
603 break;
604 case IDC_NO_W:
605 os2type = SPTR_ILLEGAL;
606 break;
607 case IDC_CROSS_W:
608 os2type = SPTR_MOVE;
609 break;
610 case IDC_SIZE_W:
611 os2type = SPTR_MOVE;
612 break;
613 case IDC_SIZEALL_W:
614 os2type = SPTR_MOVE;
615 break;
616 case IDC_SIZENESW_W:
617 os2type = SPTR_SIZENESW;
618 break;
619 case IDC_SIZENS_W:
620 os2type = SPTR_SIZENS;
621 break;
622 case IDC_SIZENWSE_W:
623 os2type = SPTR_SIZENWSE;
624 break;
625 case IDC_SIZEWE_W:
626 os2type = SPTR_SIZEWE;
627 break;
628 case IDC_WAIT_W:
629 os2type = SPTR_WAIT;
630 break;
631 case IDC_APPSTARTING_W:
632 os2type = SPTR_WAIT;
633 break;
634 case IDC_HELP_W: //TODO: Create a cursor for this one
635 os2type = SPTR_WAIT;
636 break;
637 default:
638 return 0;
639 }
640 //Note: Does not create a copy
641 return WinQuerySysPointer(HWND_DESKTOP, os2type, FALSE);
642}
643//******************************************************************************
644//******************************************************************************
645VOID OSLibWinDestroyPointer(HANDLE hPointer)
646{
647 WinDestroyPointer(hPointer);
648}
649//******************************************************************************
650//******************************************************************************
651BOOL OSLibWinSetPointer(HANDLE hPointer)
652{
653 return WinSetPointer(HWND_DESKTOP, hPointer);
654}
655//******************************************************************************
656//******************************************************************************
657HANDLE OSLibWinQueryPointer()
658{
659 return WinQueryPointer(HWND_DESKTOP);
660}
661//******************************************************************************
662//******************************************************************************
663BOOL OSLibWinClipCursor(const RECT * pRect)
664{
665 RECTL rectl;
666 PRECTL ptr = NULL;
667
668 if (pRect != NULL)
669 {
670 rectl.xLeft = max(pRect->left, 0);
671 rectl.xRight = min(pRect->right, ScreenWidth-1);
672 rectl.yBottom = max(ScreenHeight - pRect->bottom, 0);
673 rectl.yTop = min(ScreenHeight - pRect->top, ScreenHeight-1);
674 ptr = &rectl;
675 }
676 return WinSetPointerClipRect (HWND_DESKTOP, ptr);
677}
678//******************************************************************************
679//******************************************************************************
680BOOL OSLibWinGetClipCursor(LPRECT pRect)
681{
682 RECTL rectl;
683
684 if (WinQueryPointerClipRect(HWND_DESKTOP, &rectl))
685 {
686 pRect->left = rectl.xLeft;
687 pRect->right = rectl.xRight;
688 pRect->bottom = ScreenHeight - rectl.yBottom;
689 pRect->top = ScreenHeight - rectl.yTop;
690 return TRUE;
691 }
692 return FALSE;
693}
694//******************************************************************************
695//******************************************************************************
696static char *OSLibStripPath(char *path)
697{
698 char *pszFilename;
699 char *pszFilename1;
700
701 pszFilename = strrchr(path, '\\'); /* find rightmost backslash */
702 pszFilename1 = strrchr(path, '/'); /* find rightmost slash */
703 if(pszFilename > pszFilename1 && pszFilename != NULL)
704 return (++pszFilename); /* return pointer to next character */
705
706 if (pszFilename1 != NULL)
707 return (++pszFilename1); /* return pointer to next character */
708
709 return (path); /* default return value */
710}
711//******************************************************************************
712//******************************************************************************
713void OSLibStripFile(char *path)
714{
715 char *pszFilename;
716 char *pszFilename1;
717
718 pszFilename = strrchr(path, '\\'); /* find rightmost backslash */
719 pszFilename1 = strrchr(path, '/'); /* find rightmost slash */
720 if(pszFilename > pszFilename1 && pszFilename != NULL)
721 *pszFilename = 0;
722 else
723 if (pszFilename1 != NULL)
724 *pszFilename1 = 0;
725}
726//******************************************************************************
727//******************************************************************************
728BOOL WIN32API OSLibWinCreateObject(LPSTR pszPath, LPSTR pszArgs,
729 LPSTR pszWorkDir, LPSTR pszLink,
730 LPSTR pszDescription, LPSTR pszIcoPath,
731 INT iIcoNdx, BOOL fDesktop)
732{
733 HOBJECT hObject = 0;
734 LPSTR pszName;
735 LPSTR pszSetupString;
736 LPSTR pszFolder;
737 char szSystemDir[256];
738 char temp[128];
739 char szWorkDir[256];
740
741 if(pszName) {
742 char *tmp;
743 pszName = OSLibStripPath(pszLink);
744 tmp = pszName;
745 while(*tmp) {
746 if(*tmp == '.') {
747 *tmp = 0;
748 break;
749 }
750 tmp++;
751 }
752 }
753 dprintf(("OSLibWinCreateObject %s %s %s\n %s %s %s %d %d", pszPath, pszArgs,
754 pszWorkDir, pszName, pszDescription, pszIcoPath, iIcoNdx, fDesktop));
755 dprintf(("Link path %s", pszLink));
756
757 GetSystemDirectoryA(szSystemDir, sizeof(szSystemDir));
758 if(pszWorkDir && *pszWorkDir) {
759 strcpy(szWorkDir, pszWorkDir);
760 }
761 else {
762 strcpy(szWorkDir, pszPath);
763 OSLibStripFile(szWorkDir);
764 }
765
766 pszSetupString = (LPSTR)malloc(128 + strlen(pszPath) + strlen(pszName) +
767 strlen(pszLink) + 2*strlen(szSystemDir) +
768 strlen(szWorkDir) + strlen(pszIcoPath) +
769 ((pszArgs) ? strlen(pszArgs) : 0) +
770 ((pszWorkDir) ? strlen(pszWorkDir) : 0));
771
772 sprintf(pszSetupString, "PROGTYPE=PM;OBJECTID=<%s>;EXENAME=%s\\PE.EXE;SET BEGINLIBPATH=%s;STARTUPDIR=%s;ICONFILE=%s;PARAMETERS=\"%s\"", pszName, szSystemDir, szSystemDir, szWorkDir, pszIcoPath, pszPath);
773 if(pszArgs && *pszArgs) {
774 strcat(pszSetupString, " ");
775 strcat(pszSetupString, pszArgs);
776 }
777 strcat(pszSetupString, ";");
778
779 if(fDesktop) {
780 dprintf(("Name = %s", pszName));
781 dprintf(("Setup string = %s", pszSetupString));
782 hObject = WinCreateObject("WPProgram", pszName, pszSetupString,
783 "<WP_DESKTOP>", CO_REPLACEIFEXISTS);
784 }
785 else {
786 //e.g.: Link path k:\source\odin32\bin\win\Start Menu\Programs\Winamp\Winamp
787 OSLibStripFile(pszLink);
788 pszFolder = OSLibStripPath(pszLink);
789 sprintf(temp, "<FOLDER_%s>", pszFolder);
790 sprintf(szWorkDir, "OBJECTID=%s;", temp);
791 hObject = WinCreateObject("WPFolder", pszFolder, szWorkDir,
792 "<ODINFOLDER>", CO_UPDATEIFEXISTS);
793 hObject = WinCreateObject("WPProgram", pszName, pszSetupString,
794 temp, CO_REPLACEIFEXISTS);
795 }
796// If SysCreateObject("WPProgram", "WarpMix", "<ICHAUDIO>",,
797// "PROGTYPE=PM;OBJECTID=<WARPMIX>;ICONFILE=WARPMIX.ICO;EXENAME="||bootDrive||"\MMOS2\WARPMIX.EXE")
798
799 free(pszSetupString);
800 if(!hObject) {
801 dprintf(("ERROR: WinCreateObject failed!!"));
802 }
803 return hObject != 0;
804}
805//******************************************************************************
806//******************************************************************************
807
Note: See TracBrowser for help on using the repository browser.