1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/os2/icon.cpp
3 // Purpose:     wxIcon class
4 // Author:      David Webster
5 // Modified by:
6 // Created:     10/09/99
7 // Copyright:   (c) David Webster
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13 
14 #ifdef __BORLANDC__
15     #pragma hdrstop
16 #endif
17 
18 #include "wx/icon.h"
19 
20 #ifndef WX_PRECOMP
21     #include "wx/list.h"
22     #include "wx/utils.h"
23     #include "wx/app.h"
24     #include "wx/log.h"
25 #endif
26 
27 #include "wx/os2/private.h"
28 #include "assert.h"
29 
IMPLEMENT_DYNAMIC_CLASS(wxIcon,wxGDIObject)30 IMPLEMENT_DYNAMIC_CLASS(wxIcon, wxGDIObject)
31 
32 // ============================================================================
33 // implementation
34 // ============================================================================
35 
36 // ----------------------------------------------------------------------------
37 // wxIconRefData
38 // ----------------------------------------------------------------------------
39 
40 void wxIconRefData::Free()
41 {
42     if (m_hIcon)
43         ::WinFreeFileIcon((HPOINTER)m_hIcon);
44 }
45 
46 // ----------------------------------------------------------------------------
47 // wxIcon
48 // ----------------------------------------------------------------------------
49 
wxIcon()50 wxIcon::wxIcon()
51        :m_bIsXpm(false)
52 {
53 }
54 
wxIcon(const char WXUNUSED (bits)[],int WXUNUSED (nWidth),int WXUNUSED (nHeight))55 wxIcon::wxIcon( const char WXUNUSED(bits)[],
56                 int        WXUNUSED(nWidth),
57                 int        WXUNUSED(nHeight) )
58        :m_bIsXpm(false)
59 {
60 }
61 
wxIcon(const wxString & rIconFile,wxBitmapType lFlags,int nDesiredWidth,int nDesiredHeight)62 wxIcon::wxIcon( const wxString& rIconFile,
63                 wxBitmapType    lFlags,
64                 int             nDesiredWidth,
65                 int             nDesiredHeight )
66        :m_bIsXpm(false)
67 {
68     //
69     // A very poor hack, but we have to have separate icon files from windows
70     // So we have a modified name where replace the last three characters
71     // with os2.  Also need the extension.
72     //
73     wxString sOs2Name = rIconFile.Mid(0, rIconFile.length() - 3);
74 
75     sOs2Name += wxT("Os2.ico");
76     LoadFile( sOs2Name
77              ,lFlags
78              ,nDesiredWidth
79              ,nDesiredHeight
80             );
81 }
82 
~wxIcon()83 wxIcon::~wxIcon()
84 {
85 }
86 
CreateIconFromXpm(const char * const * ppData)87 void wxIcon::CreateIconFromXpm(const char* const* ppData)
88 {
89     wxBitmap                        vBmp(ppData);
90 
91     CopyFromBitmap(vBmp);
92     if (GetHICON())
93     {
94         m_bIsXpm = true;
95         m_vXpmSrc = vBmp;
96     }
97 } // end of wxIcon::CreateIconFromXpm
98 
CopyFromBitmap(const wxBitmap & rBmp)99 void wxIcon::CopyFromBitmap( const wxBitmap& rBmp )
100 {
101     wxMask*                         pMask = rBmp.GetMask();
102     HBITMAP                         hBmp = NULLHANDLE;
103     HBITMAP                         hBmpMask = NULLHANDLE;
104     HBITMAP                         hOldBitmap = NULLHANDLE;
105     ERRORID                         vError;
106     wxString                        sError;
107     LONG                            lHits;
108 
109     if (!pMask)
110     {
111         //
112         // We must have a mask for an icon, so even if it's probably incorrect,
113         // do create it (grey is the "standard" transparent colour)
114         //
115         pMask = new wxMask( rBmp
116                            ,*wxLIGHT_GREY
117                           );
118     }
119 
120     BITMAPINFOHEADER2 vHeader;
121     SIZEL             vSize = {0, 0};
122     DEVOPENSTRUC      vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
123     HDC               hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
124     HDC               hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
125     HPS               hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
126     HPS               hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
127     POINTL            vPoint[4] = { {0, 0}, {rBmp.GetWidth(), rBmp.GetHeight()},
128                                     {0, 0}, {rBmp.GetWidth(), rBmp.GetHeight()}
129                                   };
130     POINTL            vPointMask[4] = { {0, 0}, {rBmp.GetWidth(), rBmp.GetHeight() * 2},
131                                         {0, 0}, {rBmp.GetWidth(), rBmp.GetHeight()}
132                                     };
133     POINTERINFO       vIconInfo;
134 
135     memset(&vIconInfo, '\0', sizeof(POINTERINFO));
136     vIconInfo.fPointer = FALSE;  // we want an icon, not a pointer
137 
138     memset(&vHeader, '\0', 16);
139     vHeader.cbFix           = 16;
140     vHeader.cx              = (ULONG)rBmp.GetWidth();
141     vHeader.cy              = (ULONG)rBmp.GetHeight();
142     vHeader.cPlanes         = 1L;
143     vHeader.cBitCount       = 24;
144 
145     hBmp = ::GpiCreateBitmap( hPSDst
146                              ,&vHeader
147                              ,0L
148                              ,NULL
149                              ,NULL
150                             );
151 
152     if ((hOldBitmap = ::GpiSetBitmap(hPSDst, hBmp)) == HBM_ERROR)
153     {
154         vError = ::WinGetLastError(vHabmain);
155         sError = wxPMErrorToStr(vError);
156     }
157     if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, (HBITMAP)rBmp.GetHBITMAP())) == HBM_ERROR)
158     {
159         vError = ::WinGetLastError(vHabmain);
160         sError = wxPMErrorToStr(vError);
161     }
162     if ((lHits = ::GpiBitBlt( hPSDst
163                              ,hPSSrc
164                              ,4L
165                              ,vPoint
166                              ,ROP_SRCCOPY
167                              ,BBO_IGNORE
168                             )) == GPI_ERROR)
169     {
170         vError = ::WinGetLastError(vHabmain);
171         sError = wxPMErrorToStr(vError);
172     }
173     if ((hOldBitmap = ::GpiSetBitmap(hPSDst, NULLHANDLE)) == HBM_ERROR)
174     {
175         vError = ::WinGetLastError(vHabmain);
176         sError = wxPMErrorToStr(vError);
177     }
178     if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, NULLHANDLE)) == HBM_ERROR)
179     {
180         vError = ::WinGetLastError(vHabmain);
181         sError = wxPMErrorToStr(vError);
182     }
183     vIconInfo.hbmColor = hBmp;
184 
185     vHeader.cy              = (ULONG)rBmp.GetHeight() * 2;
186     hBmpMask = ::GpiCreateBitmap( hPSDst
187                                  ,&vHeader
188                                  ,0L
189                                  ,NULL
190                                  ,NULL
191                                 );
192 
193     if ((hOldBitmap = ::GpiSetBitmap(hPSDst, hBmpMask)) == HBM_ERROR)
194     {
195         vError = ::WinGetLastError(vHabmain);
196         sError = wxPMErrorToStr(vError);
197     }
198     if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, (HBITMAP)pMask->GetMaskBitmap())) == HBM_ERROR)
199     {
200         vError = ::WinGetLastError(vHabmain);
201         sError = wxPMErrorToStr(vError);
202     }
203     if ((lHits = ::GpiBitBlt( hPSDst
204                              ,hPSSrc
205                              ,4L
206                              ,vPointMask
207                              ,ROP_SRCCOPY
208                              ,BBO_IGNORE
209                             )) == GPI_ERROR)
210     {
211         vError = ::WinGetLastError(vHabmain);
212         sError = wxPMErrorToStr(vError);
213     }
214     if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, NULLHANDLE)) == HBM_ERROR)
215     {
216         vError = ::WinGetLastError(vHabmain);
217         sError = wxPMErrorToStr(vError);
218     }
219     if ((hOldBitmap = ::GpiSetBitmap(hPSDst, NULLHANDLE)) == HBM_ERROR)
220     {
221         vError = ::WinGetLastError(vHabmain);
222         sError = wxPMErrorToStr(vError);
223     }
224 
225     vIconInfo.hbmPointer = hBmpMask;
226 
227     HICON hIcon = ::WinCreatePointerIndirect( HWND_DESKTOP, &vIconInfo);
228 
229     if (!hIcon)
230     {
231         wxLogLastError(wxT("WinCreatePointerIndirect"));
232         vError = ::WinGetLastError(vHabmain);
233         sError = wxPMErrorToStr(vError);
234     }
235     else
236     {
237         SetHICON((WXHICON)hIcon);
238         SetSize( rBmp.GetWidth()
239                 ,rBmp.GetHeight()
240                );
241     }
242 
243     if (!rBmp.GetMask())
244     {
245         //
246         // We created the mask, now delete it
247         //
248         delete pMask;
249     }
250     ::GpiSetBitmap(hPSSrc, NULL);
251     ::GpiSetBitmap(hPSDst, NULL);
252     ::GpiDestroyPS(hPSSrc);
253     ::GpiDestroyPS(hPSDst);
254     ::DevCloseDC(hDCSrc);
255     ::DevCloseDC(hDCDst);
256 } // end of wxIcon::CopyFromBitmap
257 
LoadFile(const wxString & rFilename,wxBitmapType lType,int nDesiredWidth,int nDesiredHeight)258 bool wxIcon::LoadFile( const wxString& rFilename,
259                        wxBitmapType lType,
260                        int nDesiredWidth,
261                        int nDesiredHeight )
262 {
263     HPS                             hPs = NULLHANDLE;
264 
265     UnRef();
266 
267     wxGDIImageHandler*              pHandler = FindHandler(lType);
268 
269     if (pHandler)
270         return(pHandler->Load( this
271                               ,rFilename
272                               ,hPs
273                               ,lType
274                               ,nDesiredWidth
275                               ,nDesiredHeight
276                              ));
277     else
278         return false;
279 }
280