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