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