]> git.saurik.com Git - wxWidgets.git/blame - src/motif/bmpmotif.cpp
correcting CGImage handling to be always correctly initialized and freed on OSX build...
[wxWidgets.git] / src / motif / bmpmotif.cpp
CommitLineData
aae91497
MB
1/////////////////////////////////////////////////////////////////////////////
2// Name: bitmap.cpp
3// Purpose: wxBitmap
4// Author: Julian Smart, originally in bitmap.cpp
5// Modified by:
6// Created: 25/03/2003
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
aae91497
MB
10/////////////////////////////////////////////////////////////////////////////
11
1248b41f
MB
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
aae91497
MB
15#ifdef __VMS
16#define XtParent XTPARENT
d171743e 17#define XtDisplay XTDISPLAY
aae91497
MB
18#endif
19
20#include "wx/defs.h"
21#include "wx/motif/bmpmotif.h"
22
23#ifdef __VMS__
24#pragma message disable nosimpint
25#endif
26#include <Xm/Xm.h>
27#ifdef __VMS__
28#pragma message enable nosimpint
29#endif
30
31#include "wx/motif/private.h"
32
33#if wxHAVE_LIB_XPM
34 #include <X11/xpm.h>
35#endif
463c4d71
WS
36
37#include "wx/math.h"
aae91497
MB
38
39Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap );
40
2263a14e
VZ
41static inline wxCharBuffer GetCacheImageName(WXImage image)
42{
43 return wxString::Format(_T("wxBitmap_%p"), image).ToAscii();
44}
45
aae91497
MB
46wxBitmapCache::~wxBitmapCache()
47{
48 if( m_display )
49 {
50 Screen* screen = DefaultScreenOfDisplay( (Display*)m_display );
51
52 if( m_labelPixmap )
53 XmDestroyPixmap( screen, (Pixmap)m_labelPixmap );
54
55 if( m_armPixmap )
56 XmDestroyPixmap( screen, (Pixmap)m_armPixmap );
57
58 if( m_insensPixmap )
59 XmDestroyPixmap( screen, (Pixmap)m_insensPixmap );
60
61 }
62
63 if( m_image )
64 {
65 XmUninstallImage( (XImage*)m_image );
66 XtFree( (char*)(XImage*)m_image );
67 }
68}
69
70void wxBitmapCache::SetBitmap( const wxBitmap& bitmap )
71{
72 if( m_bitmap != bitmap )
73 {
74 InvalidateCache();
75 m_bitmap = bitmap;
76
77 if( m_image )
78 {
79 XmUninstallImage( (XImage*)m_image );
80 XtFree( (char*)(XImage*)m_image );
81 m_image = (WXImage*)NULL;
82 }
83 }
84}
85
86void wxBitmapCache::InvalidateCache()
87{
88 m_recalcPixmaps.label = true;
89 m_recalcPixmaps.arm = true;
90 m_recalcPixmaps.insens = true;
91}
92
93void wxBitmapCache::SetColoursChanged()
94{
95 InvalidateCache();
96}
97
98void wxBitmapCache::CreateImageIfNeeded( WXWidget w )
99{
100 if( m_image )
101 return;
102
103 m_display = w ?
104 (WXDisplay*)XtDisplay( (Widget)w ) :
105 (WXDisplay*)wxGetDisplay();
106
107 XImage *ximage = XGetImage( (Display*)m_display,
aae0472b 108 (Drawable)m_bitmap.GetDrawable(),
aae91497
MB
109 0, 0,
110 m_bitmap.GetWidth(), m_bitmap.GetHeight(),
111 AllPlanes, ZPixmap );
112
113 m_image = (WXImage*)ximage;
114
115 if( m_image )
116 {
2263a14e 117 XmInstallImage( ximage, GetCacheImageName(m_image).data() );
aae91497
MB
118 }
119}
120
2263a14e
VZ
121WXPixmap wxBitmapCache::GetPixmapFromCache(WXWidget w)
122{
123 Widget widget = (Widget)w;
124 while( XmIsGadget( widget ) )
125 widget = XtParent( widget );
126
127 Pixel fg, bg;
128 XtVaGetValues( widget,
129 XmNbackground, &bg,
130 XmNforeground, &fg,
131 NULL );
132
133 Screen* screen = DefaultScreenOfDisplay( (Display*)m_display );
134 return (WXPixmap)XmGetPixmap(screen, GetCacheImageName(m_image).data(), fg, bg);
135}
136
aae91497
MB
137WXPixmap wxBitmapCache::GetLabelPixmap( WXWidget w )
138{
139 if( m_labelPixmap && !m_recalcPixmaps.label )
140 return m_labelPixmap;
141
142 CreateImageIfNeeded( w );
143
144 Screen* screen = DefaultScreenOfDisplay( (Display*)m_display );
145
146 if( m_labelPixmap )
147 XmDestroyPixmap( screen, (Pixmap)m_labelPixmap );
148
149 if( !m_image )
150 return (WXPixmap)NULL;
151
2263a14e 152 m_labelPixmap = GetPixmapFromCache(w);
aae91497
MB
153 m_recalcPixmaps.label = !m_labelPixmap;
154 return m_labelPixmap;
155}
156
157WXPixmap wxBitmapCache::GetArmPixmap( WXWidget w )
158{
159 if( m_armPixmap && !m_recalcPixmaps.arm )
160 return m_armPixmap;
161
162 CreateImageIfNeeded( w );
163
164 Screen* screen = DefaultScreenOfDisplay( (Display*)m_display );
165
166 if( m_armPixmap )
167 XmDestroyPixmap( screen, (Pixmap)m_armPixmap );
168
169 if( !m_image )
170 return (WXPixmap)NULL;
171
2263a14e 172 m_armPixmap = GetPixmapFromCache(w);
aae91497
MB
173 m_recalcPixmaps.arm = !m_armPixmap;
174 return m_armPixmap;
175}
176
177WXPixmap wxBitmapCache::GetInsensPixmap( WXWidget w )
178{
179 if( m_insensPixmap && !m_recalcPixmaps.insens )
180 return m_insensPixmap;
181
182 CreateImageIfNeeded( w );
183
184 Screen* screen = DefaultScreenOfDisplay( (Display*)m_display );
185
186 if( m_insensPixmap )
187 XmDestroyPixmap( screen, (Pixmap)m_insensPixmap );
188
189 if( !m_image )
190 return (WXPixmap)NULL;
191
192 m_insensPixmap =
193 (WXPixmap)XCreateInsensitivePixmap( (Display*)m_display,
aae0472b 194 (Pixmap)m_bitmap.GetDrawable() );
aae91497
MB
195
196 m_recalcPixmaps.insens = !m_insensPixmap;
197 return m_insensPixmap;
198}
e8508ea8
MB
199
200//////////////////////////////////////////////////////////////////////////////
201// Utility function
202//////////////////////////////////////////////////////////////////////////////
203
204/****************************************************************************
205
206 NAME
207 XCreateInsensitivePixmap - create a grayed-out copy of a pixmap
208
209 SYNOPSIS
210 Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
211
212 DESCRIPTION
213 This function creates a grayed-out copy of the argument pixmap, suitable
214 for use as a XmLabel's XmNlabelInsensitivePixmap resource.
215
216 RETURN VALUES
217 The return value is the new Pixmap id or zero on error. Errors include
218 a NULL display argument or an invalid Pixmap argument.
219
220 ERRORS
221 If one of the XLib functions fail, it will produce a X error. The
222 default X error handler prints a diagnostic and calls exit().
223
224 SEE ALSO
225 XCopyArea(3), XCreateBitmapFromData(3), XCreateGC(3), XCreatePixmap(3),
226 XFillRectangle(3), exit(2)
227
228 AUTHOR
229 John R Veregge - john@puente.jpl.nasa.gov
230 Advanced Engineering and Prototyping Group (AEG)
231 Information Systems Technology Section (395)
232 Jet Propulsion Lab - Calif Institute of Technology
233
234*****************************************************************************/
235
236Pixmap
237XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
238
239{
240 static char stipple_data[] =
241 {
242 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
243 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
244 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
245 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA
246 };
247 GC gc;
248 Pixmap ipixmap, stipple;
249 unsigned width, height, depth;
250
251 Window window; /* These return values */
252 unsigned border; /* from XGetGeometry() */
253 int x, y; /* are not needed. */
254
255 ipixmap = 0;
256
257 if ( NULL == display || 0 == pixmap )
258 return ipixmap;
259
260 if ( 0 == XGetGeometry( display, pixmap, &window, &x, &y,
261 &width, &height, &border, &depth )
262 )
263 return ipixmap; /* BadDrawable: probably an invalid pixmap */
264
265 /* Get the stipple pixmap to be used to 'gray-out' the argument pixmap.
266 */
267 stipple = XCreateBitmapFromData( display, pixmap, stipple_data, 16, 16 );
268 if ( 0 != stipple )
269 {
270 gc = XCreateGC( display, pixmap, (XtGCMask)0, (XGCValues*)NULL );
271 if ( NULL != gc )
272 {
273 /* Create an identical copy of the argument pixmap.
274 */
275 ipixmap = XCreatePixmap( display, pixmap, width, height, depth );
276 if ( 0 != ipixmap )
277 {
278 /* Copy the argument pixmap into the new pixmap.
279 */
280 XCopyArea( display, pixmap, ipixmap,
281 gc, 0, 0, width, height, 0, 0 );
282
283 /* Refill the new pixmap using the stipple algorithm/pixmap.
284 */
285 XSetStipple( display, gc, stipple );
286 XSetFillStyle( display, gc, FillStippled );
287 XFillRectangle( display, ipixmap, gc, 0, 0, width, height );
288 }
289 XFreeGC( display, gc );
290 }
291 XFreePixmap( display, stipple );
292 }
293 return ipixmap;
294}