]> git.saurik.com Git - wxWidgets.git/blob - src/msw/xpmhand.cpp
merged Ctrl-Space fix from 2.2 branch
[wxWidgets.git] / src / msw / xpmhand.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: xpmhand.cpp
3 // Purpose: wxBitmap: XPM handler and constructors
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "xpmhand.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/list.h"
25 #include "wx/utils.h"
26 #include "wx/app.h"
27 #include "wx/palette.h"
28 #include "wx/dcmemory.h"
29 #include "wx/bitmap.h"
30 #include "wx/icon.h"
31 #endif
32
33 #include "wx/msw/private.h"
34 #include "wx/log.h"
35
36 #if wxUSE_XPM_IN_MSW
37 #define FOR_MSW 1
38
39 // allow the user to use the system-wide xpm.h by defining
40 // wxUSE_XPM_H_IN_PATH (and always use xpm.h in path if __WX_SETUP_H__ is
41 // defined which means that we use configure as it always add -I../xpm to
42 // the include path if needed)
43 #if !defined(__WX_SETUP_H__) && !defined(wxUSE_XPM_H_IN_PATH)
44 #include "../xpm/xpm.h"
45 #else
46 #include <xpm.h>
47 #endif
48 #endif
49
50 #include "wx/xpmhand.h"
51 #include "wx/msw/dib.h"
52
53 #if wxUSE_XPM_IN_MSW
54
55 static void XpmToBitmap(wxBitmap *bitmap,
56 const XImage *ximage,
57 const XImage *xmask,
58 const XpmAttributes& xpmAttr)
59 {
60 wxBitmapRefData *refData = bitmap->GetBitmapData();
61 refData->m_hBitmap = (WXHBITMAP)ximage->bitmap;
62
63 // first set the bitmap width, height, depth...
64 BITMAP bm;
65 if ( !::GetObject(GetHbitmapOf(*bitmap), sizeof(bm), (LPSTR) & bm) )
66 {
67 wxLogLastError(wxT("GetObject(bitmap)"));
68 }
69
70 refData->m_width = bm.bmWidth;
71 refData->m_height = bm.bmHeight;
72 refData->m_depth = bm.bmPlanes * bm.bmBitsPixel;
73 refData->m_numColors = xpmAttr.npixels;
74
75 // GRG Jan/2000, mask support
76 if (xmask)
77 {
78 wxMask *mask = new wxMask();
79 mask->SetMaskBitmap((WXHBITMAP) wxInvertMask(xmask->bitmap,
80 bm.bmWidth, bm.bmHeight));
81 bitmap->SetMask(mask);
82 }
83 }
84
85 #endif // wxUSE_XPM_IN_MSW
86
87 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
88
89 bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap,
90 const wxString& name,
91 long flags,
92 int desiredWidth, int desiredHeight)
93 {
94 #if wxUSE_XPM_IN_MSW
95 XImage *ximage = NULL;
96 XImage *xmask = NULL;
97 XpmAttributes xpmAttr;
98 HDC dc;
99
100 dc = CreateCompatibleDC(NULL);
101 if (dc)
102 {
103 xpmAttr.valuemask = XpmReturnPixels | XpmColorTable;
104 int errorStatus = XpmReadFileToImage(&dc,
105 wxMBSTRINGCAST name.fn_str(),
106 &ximage,
107 &xmask,
108 &xpmAttr);
109 DeleteDC(dc);
110 if (errorStatus == XpmSuccess)
111 {
112 XpmToBitmap(bitmap, ximage, xmask, xpmAttr);
113
114 XpmFree(xpmAttr.pixels);
115 XpmFreeAttributes(&xpmAttr);
116 XImageFree(ximage);
117 if (xmask)
118 XDestroyImage(xmask);
119 }
120
121 #if WXWIN_COMPATIBILITY_2
122 bitmap->SetOk(errorStatus == XpmSuccess);
123 #endif // WXWIN_COMPATIBILITY_2
124
125 return bitmap->Ok();
126 }
127 #endif // wxUSE_XPM_IN_MSW
128
129 return FALSE;
130 }
131
132 bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap,
133 const wxString& name,
134 int type,
135 const wxPalette *palette)
136 {
137 #if wxUSE_XPM_IN_MSW
138 XImage ximage;
139 XImage xmask;
140 bool hasmask = FALSE;
141
142 HDC dc = CreateCompatibleDC(NULL);
143 if (dc)
144 {
145 /* fill the XImage struct 'by hand' */
146 wxBitmapRefData *refData = bitmap->GetBitmapData();
147 ximage.width = refData->m_width;
148 ximage.height = refData->m_height;
149 ximage.depth = refData->m_depth;
150 ximage.bitmap = (HBITMAP)refData->m_hBitmap;
151
152 // GRG Jan/2000, mask support
153 hasmask = (refData->m_bitmapMask != NULL);
154 if (hasmask)
155 {
156 /* Strangely enough, the MSW version of xpmlib is not
157 * coherent with itself regarding masks; we have to invert
158 * the mask we get when loading, but we still must pass it
159 * 'as is' when saving...
160 */
161 xmask.bitmap = (HBITMAP) refData->m_bitmapMask->GetMaskBitmap();
162 xmask.width = refData->m_width;
163 xmask.height = refData->m_height;
164 xmask.depth = 1;
165 }
166
167 int errorStatus = XpmWriteFileFromImage(
168 &dc,
169 wxMBSTRINGCAST name.fn_str(),
170 &ximage,
171 (hasmask? &xmask : (XImage *)NULL),
172 (XpmAttributes *) NULL);
173
174 DeleteDC(dc);
175
176 return (errorStatus == XpmSuccess);
177 }
178 #endif // !wxUSE_XPM_IN_MSW
179
180 return FALSE;
181 }
182
183 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
184
185 bool wxXPMDataHandler::Create(wxBitmap *bitmap,
186 void *data,
187 long flags,
188 int width,
189 int height,
190 int depth)
191 {
192 #if wxUSE_XPM_IN_MSW
193 XImage *ximage = NULL;
194 XImage *xmask = NULL;
195 XpmAttributes xpmAttr;
196
197 HDC dc = CreateCompatibleDC(NULL); /* memory DC */
198
199 if (dc)
200 {
201 xpmAttr.valuemask = XpmReturnInfos | XpmColorTable;
202 int errorStatus = XpmCreateImageFromData(&dc, (char **)data,
203 &ximage,
204 &xmask,
205 &xpmAttr);
206 DeleteDC(dc);
207
208 if ( errorStatus == XpmSuccess )
209 {
210 XpmToBitmap(bitmap, ximage, xmask, xpmAttr);
211
212 XpmFree(xpmAttr.pixels);
213 XpmFreeAttributes(&xpmAttr);
214 XImageFree(ximage); // releases the malloc, but does not destroy bitmap
215 if (xmask)
216 XDestroyImage(xmask);
217 }
218
219 #if WXWIN_COMPATIBILITY_2
220 bitmap->SetOk(errorStatus == XpmSuccess);
221 #endif // WXWIN_COMPATIBILITY_2
222
223 return bitmap->Ok();
224 }
225 #endif // wxUSE_XPM_IN_MSW
226
227 return FALSE;
228 }
229