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