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