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