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