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