]> git.saurik.com Git - wxWidgets.git/blob - src/motif/bmpmotif.cpp
XRC spec: relax requirements on some commonly omitted properties.
[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 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13
14 #include "wx/motif/bmpmotif.h"
15
16 #ifndef WX_PRECOMP
17 #include "wx/math.h"
18 #endif
19
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
33
34 Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap );
35
36 static inline wxCharBuffer GetCacheImageName(WXImage image)
37 {
38 return wxString::Format(wxT("wxBitmap_%p"), image).ToAscii();
39 }
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.IsSameAs(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 = 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 XmInstallImage( ximage, GetCacheImageName(m_image).data() );
113 }
114 }
115
116 WXPixmap wxBitmapCache::GetPixmapFromCache(WXWidget w)
117 {
118 Widget widget = (Widget)w;
119 while( XmIsGadget( widget ) )
120 widget = XtParent( widget );
121
122 WXPixel fg, bg;
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
132 WXPixmap 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
147 m_labelPixmap = GetPixmapFromCache(w);
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 m_armPixmap = GetPixmapFromCache(w);
168 m_recalcPixmaps.arm = !m_armPixmap;
169 return m_armPixmap;
170 }
171
172 WXPixmap 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,
189 (Pixmap)m_bitmap.GetDrawable() );
190
191 m_recalcPixmaps.insens = !m_insensPixmap;
192 return m_insensPixmap;
193 }
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
231 Pixmap
232 XCreateInsensitivePixmap( 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 {
265 gc = XCreateGC( display, pixmap, (XtGCMask)0, NULL );
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 }