]> git.saurik.com Git - wxWidgets.git/blame - src/os2/utilsgui.cpp
wxGTK1 : wx/private/eventloopsourcesmanager.h was missing in evtloop.cpp
[wxWidgets.git] / src / os2 / utilsgui.cpp
CommitLineData
bd3b171d 1///////////////////////////////////////////////////////////////////////////////
521bf4ff 2// Name: src/os2/utilsgui.cpp
bd3b171d
SN
3// Purpose: Various utility functions only available in GUI
4// Author: David Webster
5// Modified by:
6// Created: 20.08.2003 (extracted from os2/utils.cpp)
bd3b171d 7// Copyright: (c) David Webster
526954c5 8// Licence: wxWindows licence
bd3b171d
SN
9///////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
19// for compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#ifndef WX_PRECOMP
bd3b171d
SN
27 #include "wx/utils.h"
28 #include "wx/app.h"
29 #include "wx/cursor.h"
ec9f5895 30 #include "wx/font.h"
c0badb70 31 #include "wx/timer.h"
bd3b171d
SN
32#endif //WX_PRECOMP
33
ceb8f94a 34#include "wx/apptrait.h"
c2ca375c 35#include "wx/os2/private/timer.h"
b46b1d59 36#include "wx/evtloop.h"
ceb8f94a 37
bd3b171d
SN
38#include "wx/os2/private.h" // includes <windows.h>
39
40// ============================================================================
41// implementation
42// ============================================================================
43
598fe99d
VZ
44// Emit a beeeeeep
45void wxBell()
46{
47 DosBeep(1000,1000); // 1kHz during 1 sec.
48}
49
bd3b171d
SN
50// ----------------------------------------------------------------------------
51// functions to work with .INI files
52// ----------------------------------------------------------------------------
53
54// Sleep for nSecs seconds. Attempt a Windows implementation using timers.
c0badb70 55static bool inTimer = false;
bd3b171d
SN
56
57class wxSleepTimer: public wxTimer
58{
59public:
60 inline void Notify()
61 {
c0badb70 62 inTimer = false;
bd3b171d
SN
63 Stop();
64 }
65};
66
bd3b171d
SN
67// ---------------------------------------------------------------------------
68// helper functions for showing a "busy" cursor
69// ---------------------------------------------------------------------------
70
71HCURSOR gs_wxBusyCursor = 0; // new, busy cursor
72HCURSOR gs_wxBusyCursorOld = 0; // old cursor
73static int gs_wxBusyCursorCount = 0;
74
75// Set the cursor to the busy cursor for all windows
f516d986 76void wxBeginBusyCursor(const wxCursor* pCursor)
bd3b171d
SN
77{
78 if ( gs_wxBusyCursorCount++ == 0 )
79 {
80 gs_wxBusyCursor = (HCURSOR)pCursor->GetHCURSOR();
81 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursor);
82 }
83 //else: nothing to do, already set
84}
85
86// Restore cursor to normal
87void wxEndBusyCursor()
88{
89 wxCHECK_RET( gs_wxBusyCursorCount > 0
9a83f860 90 ,wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()")
bd3b171d
SN
91 );
92
93 if (--gs_wxBusyCursorCount == 0)
94 {
95 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursorOld);
96 gs_wxBusyCursorOld = 0;
97 }
98}
99
c0badb70 100// true if we're between the above two calls
bd3b171d
SN
101bool wxIsBusy()
102{
103 return (gs_wxBusyCursorCount > 0);
104}
105
106// Check whether this window wants to process messages, e.g. Stop button
107// in long calculations.
c0badb70 108bool wxCheckForInterrupt( wxWindow* pWnd )
bd3b171d
SN
109{
110 if(pWnd)
111 {
c0badb70
WS
112 QMSG vMsg;
113 HAB hab = 0;
114 HWND hwndFilter = NULLHANDLE;
bd3b171d
SN
115
116 while(::WinPeekMsg(hab, &vMsg, hwndFilter, 0, 0, PM_REMOVE))
117 {
118 ::WinDispatchMsg(hab, &vMsg);
119 }
c0badb70 120 return true;//*** temporary?
bd3b171d
SN
121 }
122 else
123 {
9a83f860 124 wxFAIL_MSG(wxT("pWnd==NULL !!!"));
c0badb70 125 return false;//*** temporary?
bd3b171d
SN
126 }
127}
128
129// ----------------------------------------------------------------------------
130// get display info
131// ----------------------------------------------------------------------------
132
133// See also the wxGetMousePosition in window.cpp
134// Deprecated: use wxPoint wxGetMousePosition() instead
135void wxGetMousePosition(
136 int* pX
137, int* pY
138)
139{
140 POINTL vPt;
141
142 ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
143 *pX = vPt.x;
144 *pY = vPt.y;
145};
146
c0badb70 147// Return true if we have a colour display
bd3b171d
SN
148bool wxColourDisplay()
149{
150#if 0
151 HPS hpsScreen;
152 HDC hdcScreen;
153 LONG lColors;
154
155 hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
156 hdcScreen = ::GpiQueryDevice(hpsScreen);
157 ::DevQueryCaps(hdcScreen, CAPS_COLORS, 1L, &lColors);
158 return(lColors > 1L);
159#else
160 // I don't see how the PM display could not be color. Besides, this
161 // was leaking DCs and PSs!!! MN
c0badb70 162 return true;
bd3b171d
SN
163#endif
164}
165
166// Returns depth of screen
167int wxDisplayDepth()
168{
169 HPS hpsScreen;
170 HDC hdcScreen;
171 LONG lPlanes;
172 LONG lBitsPerPixel;
173 static LONG nDepth = 0;
174
175 // The screen colordepth ain't gonna change. No reason to query
176 // it over and over!
177 if (!nDepth) {
178 hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
179 hdcScreen = ::GpiQueryDevice(hpsScreen);
180 ::DevQueryCaps(hdcScreen, CAPS_COLOR_PLANES, 1L, &lPlanes);
181 ::DevQueryCaps(hdcScreen, CAPS_COLOR_BITCOUNT, 1L, &lBitsPerPixel);
182
183 nDepth = (int)(lPlanes * lBitsPerPixel);
184 ::DevCloseDC(hdcScreen);
185 ::WinReleasePS(hpsScreen);
186 }
187 return (nDepth);
188}
189
190// Get size of display
191void wxDisplaySize(
192 int* pWidth
193, int* pHeight
194)
195{
196 HPS hpsScreen;
197 HDC hdcScreen;
198 static LONG lWidth = 0;
199 static LONG lHeight = 0;
200
201 // The screen size ain't gonna change either so just cache the values
202 if (!lWidth) {
203 hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
204 hdcScreen = ::GpiQueryDevice(hpsScreen);
205 ::DevQueryCaps(hdcScreen, CAPS_WIDTH, 1L, &lWidth);
206 ::DevQueryCaps(hdcScreen, CAPS_HEIGHT, 1L, &lHeight);
207 ::DevCloseDC(hdcScreen);
208 ::WinReleasePS(hpsScreen);
209 }
42782237
SN
210 if (pWidth)
211 *pWidth = (int)lWidth;
212 if (pHeight)
213 *pHeight = (int)lHeight;
bd3b171d
SN
214}
215
216void wxDisplaySizeMM(
217 int* pWidth
218, int* pHeight
219)
220{
221 HPS hpsScreen;
222 HDC hdcScreen;
223
224 hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
225 hdcScreen = ::GpiQueryDevice(hpsScreen);
226
227 if (pWidth)
228 ::DevQueryCaps( hdcScreen
229 ,CAPS_HORIZONTAL_RESOLUTION
230 ,1L
231 ,(PLONG)pWidth
232 );
233 if (pHeight)
234 ::DevQueryCaps( hdcScreen
235 ,CAPS_VERTICAL_RESOLUTION
236 ,1L
237 ,(PLONG)pHeight
238 );
239 ::DevCloseDC(hdcScreen);
240 ::WinReleasePS(hpsScreen);
241}
242
243void wxClientDisplayRect(int *x, int *y, int *width, int *height)
244{
245 // This is supposed to return desktop dimensions minus any window
246 // manager panels, menus, taskbars, etc. If there is a way to do that
247 // for this platform please fix this function, otherwise it defaults
248 // to the entire desktop.
249 if (x) *x = 0;
250 if (y) *y = 0;
251 wxDisplaySize(width, height);
252}
253
8329e6c7
SN
254void wxGUIAppTraits::InitializeGui(unsigned long &ulHab)
255{
256 ulHab = ::WinInitialize(0);
257}
258
259void wxGUIAppTraits::TerminateGui(unsigned long ulHab)
260{
261 ::WinTerminate(ulHab);
262}
263
930a9efa 264wxPortId wxGUIAppTraits::GetToolkitVersion(int *verMaj, int *verMin) const
621ccd8a 265{
930a9efa
SN
266 // How to get version of PM ? I guess, just reusing the OS version is OK.
267 (void) wxGetOsVersion(verMaj, verMin);
8bb6b2c0 268 return wxPORT_OS2;
621ccd8a
SN
269}
270
c2ca375c
VZ
271wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
272{
273 return new wxOS2TimerImpl(timer);
274}
275
2ddff00c 276wxEventLoopBase* wxGUIAppTraits::CreateEventLoop()
b46b1d59
VZ
277{
278 return new wxEventLoop;
279}
8bb6b2c0 280
bd3b171d
SN
281// ---------------------------------------------------------------------------
282// window information functions
283// ---------------------------------------------------------------------------
284
521bf4ff 285wxString WXDLLEXPORT wxGetWindowText( WXHWND hWnd )
bd3b171d 286{
521bf4ff 287 wxString vStr;
bd3b171d 288
2461cfa0
SN
289 if ( hWnd )
290 {
521bf4ff
WS
291 long lLen = ::WinQueryWindowTextLength((HWND)hWnd) + 1;
292 ::WinQueryWindowText((HWND)hWnd, lLen, (PSZ)(wxChar*)wxStringBuffer(vStr, lLen));
2461cfa0 293 }
bd3b171d
SN
294
295 return vStr;
296}
297
521bf4ff 298wxString WXDLLEXPORT wxGetWindowClass( WXHWND hWnd )
bd3b171d 299{
521bf4ff 300 wxString vStr;
2461cfa0 301 if ( hWnd )
bd3b171d 302 {
521bf4ff
WS
303 int nLen = 256; // some starting value
304
305 for ( ;; )
306 {
307 int nCount = ::WinQueryClassName((HWND)hWnd, nLen, (PSZ)(wxChar*)wxStringBuffer(vStr, nLen));
308
309 if (nCount == nLen )
310 {
311 // the class name might have been truncated, retry with larger
312 // buffer
313 nLen *= 2;
314 }
315 else
316 {
317 break;
318 }
bd3b171d
SN
319 }
320 }
321 return vStr;
322}
323
324WXWORD WXDLLEXPORT wxGetWindowId(
325 WXHWND hWnd
326)
327{
328 return ::WinQueryWindowUShort((HWND)hWnd, QWS_ID);
329}
330
331void wxDrawBorder(
332 HPS hPS
333, RECTL& rRect
334, WXDWORD dwStyle
335)
336{
337 POINTL vPoint[2];
338
339 vPoint[0].x = rRect.xLeft;
340 vPoint[0].y = rRect.yBottom;
341 ::GpiMove(hPS, &vPoint[0]);
342 if (dwStyle & wxSIMPLE_BORDER ||
343 dwStyle & wxSTATIC_BORDER)
344 {
345 vPoint[1].x = rRect.xRight - 1;
346 vPoint[1].y = rRect.yTop - 1;
347 ::GpiBox( hPS
348 ,DRO_OUTLINE
349 ,&vPoint[1]
350 ,0L
351 ,0L
352 );
353 }
354 if (dwStyle & wxSUNKEN_BORDER)
355 {
356 LINEBUNDLE vLineBundle;
357
358 vLineBundle.lColor = 0x00FFFFFF; // WHITE
359 vLineBundle.usMixMode = FM_OVERPAINT;
360 vLineBundle.fxWidth = 2;
361 vLineBundle.lGeomWidth = 2;
362 vLineBundle.usType = LINETYPE_SOLID;
363 vLineBundle.usEnd = 0;
364 vLineBundle.usJoin = 0;
365 ::GpiSetAttrs( hPS
366 ,PRIM_LINE
367 ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
368 ,0L
369 ,&vLineBundle
370 );
371 vPoint[1].x = rRect.xRight - 1;
372 vPoint[1].y = rRect.yTop - 1;
373 ::GpiBox( hPS
374 ,DRO_OUTLINE
375 ,&vPoint[1]
376 ,0L
377 ,0L
378 );
379 vPoint[0].x = rRect.xLeft + 1;
380 vPoint[0].y = rRect.yBottom + 1;
381 ::GpiMove(hPS, &vPoint[0]);
382 vPoint[1].x = rRect.xRight - 2;
383 vPoint[1].y = rRect.yTop - 2;
384 ::GpiBox( hPS
385 ,DRO_OUTLINE
386 ,&vPoint[1]
387 ,0L
388 ,0L
389 );
390
391 vLineBundle.lColor = 0x00000000; // BLACK
392 vLineBundle.usMixMode = FM_OVERPAINT;
393 vLineBundle.fxWidth = 2;
394 vLineBundle.lGeomWidth = 2;
395 vLineBundle.usType = LINETYPE_SOLID;
396 vLineBundle.usEnd = 0;
397 vLineBundle.usJoin = 0;
398 ::GpiSetAttrs( hPS
399 ,PRIM_LINE
400 ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
401 ,0L
402 ,&vLineBundle
403 );
404 vPoint[0].x = rRect.xLeft + 2;
405 vPoint[0].y = rRect.yBottom + 2;
406 ::GpiMove(hPS, &vPoint[0]);
407 vPoint[1].x = rRect.xLeft + 2;
408 vPoint[1].y = rRect.yTop - 3;
409 ::GpiLine(hPS, &vPoint[1]);
410 vPoint[1].x = rRect.xRight - 3;
411 vPoint[1].y = rRect.yTop - 3;
412 ::GpiLine(hPS, &vPoint[1]);
413
414 vPoint[0].x = rRect.xLeft + 3;
415 vPoint[0].y = rRect.yBottom + 3;
416 ::GpiMove(hPS, &vPoint[0]);
417 vPoint[1].x = rRect.xLeft + 3;
418 vPoint[1].y = rRect.yTop - 4;
419 ::GpiLine(hPS, &vPoint[1]);
420 vPoint[1].x = rRect.xRight - 4;
421 vPoint[1].y = rRect.yTop - 4;
422 ::GpiLine(hPS, &vPoint[1]);
423 }
424 if (dwStyle & wxDOUBLE_BORDER)
425 {
426 LINEBUNDLE vLineBundle;
427
428 vLineBundle.lColor = 0x00FFFFFF; // WHITE
429 vLineBundle.usMixMode = FM_OVERPAINT;
430 vLineBundle.fxWidth = 2;
431 vLineBundle.lGeomWidth = 2;
432 vLineBundle.usType = LINETYPE_SOLID;
433 vLineBundle.usEnd = 0;
434 vLineBundle.usJoin = 0;
435 ::GpiSetAttrs( hPS
436 ,PRIM_LINE
437 ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
438 ,0L
439 ,&vLineBundle
440 );
441 vPoint[1].x = rRect.xRight - 1;
442 vPoint[1].y = rRect.yTop - 1;
443 ::GpiBox( hPS
444 ,DRO_OUTLINE
445 ,&vPoint[1]
446 ,0L
447 ,0L
448 );
449 vLineBundle.lColor = 0x00000000; // WHITE
450 vLineBundle.usMixMode = FM_OVERPAINT;
451 vLineBundle.fxWidth = 2;
452 vLineBundle.lGeomWidth = 2;
453 vLineBundle.usType = LINETYPE_SOLID;
454 vLineBundle.usEnd = 0;
455 vLineBundle.usJoin = 0;
456 ::GpiSetAttrs( hPS
457 ,PRIM_LINE
458 ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
459 ,0L
460 ,&vLineBundle
461 );
462 vPoint[0].x = rRect.xLeft + 2;
463 vPoint[0].y = rRect.yBottom + 2;
464 ::GpiMove(hPS, &vPoint[0]);
465 vPoint[1].x = rRect.xRight - 2;
466 vPoint[1].y = rRect.yTop - 2;
467 ::GpiBox( hPS
468 ,DRO_OUTLINE
469 ,&vPoint[1]
470 ,0L
471 ,0L
472 );
473 vLineBundle.lColor = 0x00FFFFFF; // BLACK
474 vLineBundle.usMixMode = FM_OVERPAINT;
475 vLineBundle.fxWidth = 2;
476 vLineBundle.lGeomWidth = 2;
477 vLineBundle.usType = LINETYPE_SOLID;
478 vLineBundle.usEnd = 0;
479 vLineBundle.usJoin = 0;
480 ::GpiSetAttrs( hPS
481 ,PRIM_LINE
482 ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
483 ,0L
484 ,&vLineBundle
485 );
486 vPoint[0].x = rRect.xLeft + 3;
487 vPoint[0].y = rRect.yBottom + 3;
488 ::GpiMove(hPS, &vPoint[0]);
489 vPoint[1].x = rRect.xRight - 3;
490 vPoint[1].y = rRect.yTop - 3;
491 ::GpiBox( hPS
492 ,DRO_OUTLINE
493 ,&vPoint[1]
494 ,0L
495 ,0L
496 );
497 }
498 if (dwStyle & wxRAISED_BORDER)
499 {
500 LINEBUNDLE vLineBundle;
501
502 vLineBundle.lColor = 0x00000000; // BLACK
503 vLineBundle.usMixMode = FM_OVERPAINT;
504 vLineBundle.fxWidth = 2;
505 vLineBundle.lGeomWidth = 2;
506 vLineBundle.usType = LINETYPE_SOLID;
507 vLineBundle.usEnd = 0;
508 vLineBundle.usJoin = 0;
509 ::GpiSetAttrs( hPS
510 ,PRIM_LINE
511 ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
512 ,0L
513 ,&vLineBundle
514 );
515 vPoint[1].x = rRect.xRight - 1;
516 vPoint[1].y = rRect.yTop - 1;
517 ::GpiBox( hPS
518 ,DRO_OUTLINE
519 ,&vPoint[1]
520 ,0L
521 ,0L
522 );
523 vPoint[0].x = rRect.xLeft + 1;
524 vPoint[0].y = rRect.yBottom + 1;
525 ::GpiMove(hPS, &vPoint[0]);
526 vPoint[1].x = rRect.xRight - 2;
527 vPoint[1].y = rRect.yTop - 2;
528 ::GpiBox( hPS
529 ,DRO_OUTLINE
530 ,&vPoint[1]
531 ,0L
532 ,0L
533 );
534
535 vLineBundle.lColor = 0x00FFFFFF; // WHITE
536 vLineBundle.usMixMode = FM_OVERPAINT;
537 vLineBundle.fxWidth = 2;
538 vLineBundle.lGeomWidth = 2;
539 vLineBundle.usType = LINETYPE_SOLID;
540 vLineBundle.usEnd = 0;
541 vLineBundle.usJoin = 0;
542 ::GpiSetAttrs( hPS
543 ,PRIM_LINE
544 ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
545 ,0L
546 ,&vLineBundle
547 );
548 vPoint[0].x = rRect.xLeft + 2;
549 vPoint[0].y = rRect.yBottom + 2;
550 ::GpiMove(hPS, &vPoint[0]);
551 vPoint[1].x = rRect.xLeft + 2;
552 vPoint[1].y = rRect.yTop - 3;
553 ::GpiLine(hPS, &vPoint[1]);
554 vPoint[1].x = rRect.xRight - 3;
555 vPoint[1].y = rRect.yTop - 3;
556 ::GpiLine(hPS, &vPoint[1]);
557
558 vPoint[0].x = rRect.xLeft + 3;
559 vPoint[0].y = rRect.yBottom + 3;
560 ::GpiMove(hPS, &vPoint[0]);
561 vPoint[1].x = rRect.xLeft + 3;
562 vPoint[1].y = rRect.yTop - 4;
563 ::GpiLine(hPS, &vPoint[1]);
564 vPoint[1].x = rRect.xRight - 4;
565 vPoint[1].y = rRect.yTop - 4;
566 ::GpiLine(hPS, &vPoint[1]);
567 }
568} // end of wxDrawBorder
569
570void wxOS2SetFont(
571 HWND hWnd
572, const wxFont& rFont
573)
574{
575 char zFont[128];
576 char zFacename[30];
577 char zWeight[30];
578 char zStyle[30];
579
580 if (hWnd == NULLHANDLE)
581 return;
582
583 //
584 // The fonts available for Presentation Params are just a few
585 // outline fonts, the rest are available to the GPI, so we must
586 // map the families to one of these three
587 //
588 switch(rFont.GetFamily())
589 {
590 case wxSCRIPT:
591 strcpy(zFacename, "Script");
592 break;
593
594 case wxDECORATIVE:
595 strcpy(zFacename, "WarpSans");
596 break;
597
598 case wxROMAN:
599 strcpy(zFacename,"Times New Roman");
600 break;
601
602 case wxTELETYPE:
603 strcpy(zFacename, "Courier New");
604 break;
605
606 case wxMODERN:
607 strcpy(zFacename, "Courier New");
608 break;
609
610 case wxDEFAULT:
611 default:
612 case wxSWISS:
613 strcpy(zFacename, "Helvetica");
614 break;
615 }
616
617 switch(rFont.GetWeight())
618 {
619 default:
620 case wxNORMAL:
621 case wxLIGHT:
622 zWeight[0] = '\0';
623 break;
624
625 case wxBOLD:
626 case wxFONTWEIGHT_MAX:
627 strcpy(zWeight, "Bold");
628 break;
629 }
630
631 switch(rFont.GetStyle())
632 {
633 case wxITALIC:
634 case wxSLANT:
635 strcpy(zStyle, "Italic");
636 break;
637
638 default:
639 zStyle[0] = '\0';
640 break;
641 }
642 sprintf(zFont, "%d.%s", rFont.GetPointSize(), zFacename);
643 if (zWeight[0] != '\0')
644 {
645 strcat(zFont, " ");
646 strcat(zFont, zWeight);
647 }
648 if (zStyle[0] != '\0')
649 {
650 strcat(zFont, " ");
651 strcat(zFont, zStyle);
652 }
653 ::WinSetPresParam(hWnd, PP_FONTNAMESIZE, strlen(zFont) + 1, (PVOID)zFont);
654} // end of wxOS2SetFont
655
656// ---------------------------------------------------------------------------
657// Helper for taking a regular bitmap and giving it a disabled look
658// ---------------------------------------------------------------------------
659wxBitmap wxDisableBitmap(
660 const wxBitmap& rBmp
661, long lColor
662)
663{
664 wxMask* pMask = rBmp.GetMask();
665
666 if (!pMask)
667 return(wxNullBitmap);
668
669 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
670 SIZEL vSize = {0, 0};
671 HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
672 HPS hPS = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC);
673 BITMAPINFOHEADER2 vHeader;
674 BITMAPINFO2 vInfo;
675 ERRORID vError;
676 wxString sError;
677 HBITMAP hBitmap = (HBITMAP)rBmp.GetHBITMAP();
678 HBITMAP hOldBitmap = NULLHANDLE;
679 HBITMAP hOldMask = NULLHANDLE;
680 HBITMAP hMask = (HBITMAP)rBmp.GetMask()->GetMaskBitmap();
681 unsigned char* pucBits; // buffer that will contain the bitmap data
682 unsigned char* pucData; // pointer to use to traverse bitmap data
683 unsigned char* pucBitsMask; // buffer that will contain the mask data
684 unsigned char* pucDataMask; // pointer to use to traverse mask data
685 LONG lScans = 0L;
686 LONG lScansSet = 0L;
687 bool bpp16 = (wxDisplayDepth() == 16);
688
689 memset(&vHeader, '\0', 16);
690 vHeader.cbFix = 16;
691
692 memset(&vInfo, '\0', 16);
693 vInfo.cbFix = 16;
694 vInfo.cx = (ULONG)rBmp.GetWidth();
695 vInfo.cy = (ULONG)rBmp.GetHeight();
696 vInfo.cPlanes = 1;
697 vInfo.cBitCount = 24; // Set to desired count going in
698
699 //
700 // Create the buffers for data....all wxBitmaps are 24 bit internally
701 //
702 int nBytesPerLine = rBmp.GetWidth() * 3;
703 int nSizeDWORD = sizeof(DWORD);
704 int nLineBoundary = nBytesPerLine % nSizeDWORD;
705 int nPadding = 0;
706 int i;
707 int j;
708
709 //
d6922577 710 // Bitmap must be in a double-word aligned address so we may
bd3b171d
SN
711 // have some padding to worry about
712 //
713 if (nLineBoundary > 0)
714 {
715 nPadding = nSizeDWORD - nLineBoundary;
716 nBytesPerLine += nPadding;
717 }
718 pucBits = (unsigned char *)malloc(nBytesPerLine * rBmp.GetHeight());
719 memset(pucBits, '\0', (nBytesPerLine * rBmp.GetHeight()));
720 pucBitsMask = (unsigned char *)malloc(nBytesPerLine * rBmp.GetHeight());
721 memset(pucBitsMask, '\0', (nBytesPerLine * rBmp.GetHeight()));
722
723 //
724 // Extract the bitmap and mask data
725 //
726 if ((hOldBitmap = ::GpiSetBitmap(hPS, hBitmap)) == HBM_ERROR)
727 {
728 vError = ::WinGetLastError(vHabmain);
729 sError = wxPMErrorToStr(vError);
730 }
731 ::GpiQueryBitmapInfoHeader(hBitmap, &vHeader);
732 vInfo.cBitCount = 24;
733 if ((lScans = ::GpiQueryBitmapBits( hPS
734 ,0L
735 ,(LONG)rBmp.GetHeight()
736 ,(PBYTE)pucBits
737 ,&vInfo
738 )) == GPI_ALTERROR)
739 {
740 vError = ::WinGetLastError(vHabmain);
741 sError = wxPMErrorToStr(vError);
742 }
743 if ((hOldMask = ::GpiSetBitmap(hPS, hMask)) == HBM_ERROR)
744 {
745 vError = ::WinGetLastError(vHabmain);
746 sError = wxPMErrorToStr(vError);
747 }
748 ::GpiQueryBitmapInfoHeader(hMask, &vHeader);
749 vInfo.cBitCount = 24;
750 if ((lScans = ::GpiQueryBitmapBits( hPS
751 ,0L
752 ,(LONG)rBmp.GetHeight()
753 ,(PBYTE)pucBitsMask
754 ,&vInfo
755 )) == GPI_ALTERROR)
756 {
757 vError = ::WinGetLastError(vHabmain);
758 sError = wxPMErrorToStr(vError);
759 }
760 if (( hMask = ::GpiSetBitmap(hPS, hOldMask)) == HBM_ERROR)
761 {
762 vError = ::WinGetLastError(vHabmain);
763 sError = wxPMErrorToStr(vError);
764 }
765 pucData = pucBits;
766 pucDataMask = pucBitsMask;
767
768 //
769 // Get the mask value
770 //
771 for (i = 0; i < rBmp.GetHeight(); i++)
772 {
773 for (j = 0; j < rBmp.GetWidth(); j++)
774 {
775 // Byte 1
776 if (bpp16 && *pucDataMask == 0xF8) // 16 bit display gobblygook
777 {
778 *pucData = 0x7F;
779 pucData++;
780 }
781 else if (*pucDataMask == 0xFF) // set to grey
782 {
783 *pucData = 0x7F;
784 pucData++;
785 }
786 else
787 {
788 *pucData = ((unsigned char)(lColor >> 16));
789 pucData++;
790 }
791
792 // Byte 2
793 if (bpp16 && *(pucDataMask + 1) == 0xFC) // 16 bit display gobblygook
794 {
795 *pucData = 0x7F;
796 pucData++;
797 }
798 else if (*(pucDataMask + 1) == 0xFF) // set to grey
799 {
800 *pucData = 0x7F;
801 pucData++;
802 }
803 else
804 {
805 *pucData = ((unsigned char)(lColor >> 8));
806 pucData++;
807 }
808
809 // Byte 3
810 if (bpp16 && *(pucDataMask + 2) == 0xF8) // 16 bit display gobblygook
811 {
812 *pucData = 0x7F;
813 pucData++;
814 }
815 else if (*(pucDataMask + 2) == 0xFF) // set to grey
816 {
817 *pucData = 0x7F;
818 pucData++;
819 }
820 else
821 {
822 *pucData = ((unsigned char)lColor);
823 pucData++;
824 }
825 pucDataMask += 3;
826 }
827 for (j = 0; j < nPadding; j++)
828 {
829 pucData++;
830 pucDataMask++;
831 }
832 }
833
834 //
835 // Create a new bitmap and set the modified bits
836 //
837 wxBitmap vNewBmp( rBmp.GetWidth()
838 ,rBmp.GetHeight()
839 ,24
840 );
841 HBITMAP hNewBmp = (HBITMAP)vNewBmp.GetHBITMAP();
842
843 if ((hOldBitmap = ::GpiSetBitmap(hPS, hNewBmp)) == HBM_ERROR)
844 {
845 vError = ::WinGetLastError(vHabmain);
846 sError = wxPMErrorToStr(vError);
847 }
848 if ((lScansSet = ::GpiSetBitmapBits( hPS
849 ,0L
850 ,(LONG)rBmp.GetHeight()
851 ,(PBYTE)pucBits
852 ,&vInfo
853 )) == GPI_ALTERROR)
854
855 {
856 vError = ::WinGetLastError(vHabmain);
857 sError = wxPMErrorToStr(vError);
858 }
859 wxMask* pNewMask;
860
861 pNewMask = new wxMask(pMask->GetMaskBitmap());
862 vNewBmp.SetMask(pNewMask);
863 free(pucBits);
864 ::GpiSetBitmap(hPS, NULLHANDLE);
865 ::GpiDestroyPS(hPS);
866 ::DevCloseDC(hDC);
a1b806b9 867 if (vNewBmp.IsOk())
bd3b171d
SN
868 return(vNewBmp);
869 return(wxNullBitmap);
870} // end of wxDisableBitmap
871
872COLORREF wxColourToRGB(
873 const wxColour& rColor
874)
875{
876 return(OS2RGB(rColor.Red(), rColor.Green(), rColor.Blue()));
877} // end of wxColourToRGB