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