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