git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50982 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
291 lines
7.8 KiB
C++
291 lines
7.8 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/motif/bmpmotif.cpp
|
|
// Purpose: wxBitmap
|
|
// Author: Julian Smart, originally in bitmap.cpp
|
|
// Modified by:
|
|
// Created: 25/03/2003
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) Julian Smart
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#include "wx/motif/bmpmotif.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/math.h"
|
|
#endif
|
|
|
|
#ifdef __VMS__
|
|
#pragma message disable nosimpint
|
|
#endif
|
|
#include <Xm/Xm.h>
|
|
#ifdef __VMS__
|
|
#pragma message enable nosimpint
|
|
#endif
|
|
|
|
#include "wx/motif/private.h"
|
|
|
|
#if wxHAVE_LIB_XPM
|
|
#include <X11/xpm.h>
|
|
#endif
|
|
|
|
Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap );
|
|
|
|
static inline wxCharBuffer GetCacheImageName(WXImage image)
|
|
{
|
|
return wxString::Format(_T("wxBitmap_%p"), image).ToAscii();
|
|
}
|
|
|
|
wxBitmapCache::~wxBitmapCache()
|
|
{
|
|
if( m_display )
|
|
{
|
|
Screen* screen = DefaultScreenOfDisplay( (Display*)m_display );
|
|
|
|
if( m_labelPixmap )
|
|
XmDestroyPixmap( screen, (Pixmap)m_labelPixmap );
|
|
|
|
if( m_armPixmap )
|
|
XmDestroyPixmap( screen, (Pixmap)m_armPixmap );
|
|
|
|
if( m_insensPixmap )
|
|
XmDestroyPixmap( screen, (Pixmap)m_insensPixmap );
|
|
|
|
}
|
|
|
|
if( m_image )
|
|
{
|
|
XmUninstallImage( (XImage*)m_image );
|
|
XtFree( (char*)(XImage*)m_image );
|
|
}
|
|
}
|
|
|
|
void wxBitmapCache::SetBitmap( const wxBitmap& bitmap )
|
|
{
|
|
if ( !m_bitmap.IsSameAs(bitmap) )
|
|
{
|
|
InvalidateCache();
|
|
m_bitmap = bitmap;
|
|
|
|
if( m_image )
|
|
{
|
|
XmUninstallImage( (XImage*)m_image );
|
|
XtFree( (char*)(XImage*)m_image );
|
|
m_image = (WXImage*)NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
void wxBitmapCache::InvalidateCache()
|
|
{
|
|
m_recalcPixmaps.label = true;
|
|
m_recalcPixmaps.arm = true;
|
|
m_recalcPixmaps.insens = true;
|
|
}
|
|
|
|
void wxBitmapCache::SetColoursChanged()
|
|
{
|
|
InvalidateCache();
|
|
}
|
|
|
|
void wxBitmapCache::CreateImageIfNeeded( WXWidget w )
|
|
{
|
|
if( m_image )
|
|
return;
|
|
|
|
m_display = w ?
|
|
(WXDisplay*)XtDisplay( (Widget)w ) :
|
|
(WXDisplay*)wxGetDisplay();
|
|
|
|
XImage *ximage = XGetImage( (Display*)m_display,
|
|
(Drawable)m_bitmap.GetDrawable(),
|
|
0, 0,
|
|
m_bitmap.GetWidth(), m_bitmap.GetHeight(),
|
|
AllPlanes, ZPixmap );
|
|
|
|
m_image = (WXImage*)ximage;
|
|
|
|
if( m_image )
|
|
{
|
|
XmInstallImage( ximage, GetCacheImageName(m_image).data() );
|
|
}
|
|
}
|
|
|
|
WXPixmap wxBitmapCache::GetPixmapFromCache(WXWidget w)
|
|
{
|
|
Widget widget = (Widget)w;
|
|
while( XmIsGadget( widget ) )
|
|
widget = XtParent( widget );
|
|
|
|
WXPixel fg, bg;
|
|
XtVaGetValues( widget,
|
|
XmNbackground, &bg,
|
|
XmNforeground, &fg,
|
|
NULL );
|
|
|
|
Screen* screen = DefaultScreenOfDisplay( (Display*)m_display );
|
|
return (WXPixmap)XmGetPixmap(screen, GetCacheImageName(m_image).data(), fg, bg);
|
|
}
|
|
|
|
WXPixmap wxBitmapCache::GetLabelPixmap( WXWidget w )
|
|
{
|
|
if( m_labelPixmap && !m_recalcPixmaps.label )
|
|
return m_labelPixmap;
|
|
|
|
CreateImageIfNeeded( w );
|
|
|
|
Screen* screen = DefaultScreenOfDisplay( (Display*)m_display );
|
|
|
|
if( m_labelPixmap )
|
|
XmDestroyPixmap( screen, (Pixmap)m_labelPixmap );
|
|
|
|
if( !m_image )
|
|
return (WXPixmap)NULL;
|
|
|
|
m_labelPixmap = GetPixmapFromCache(w);
|
|
m_recalcPixmaps.label = !m_labelPixmap;
|
|
return m_labelPixmap;
|
|
}
|
|
|
|
WXPixmap wxBitmapCache::GetArmPixmap( WXWidget w )
|
|
{
|
|
if( m_armPixmap && !m_recalcPixmaps.arm )
|
|
return m_armPixmap;
|
|
|
|
CreateImageIfNeeded( w );
|
|
|
|
Screen* screen = DefaultScreenOfDisplay( (Display*)m_display );
|
|
|
|
if( m_armPixmap )
|
|
XmDestroyPixmap( screen, (Pixmap)m_armPixmap );
|
|
|
|
if( !m_image )
|
|
return (WXPixmap)NULL;
|
|
|
|
m_armPixmap = GetPixmapFromCache(w);
|
|
m_recalcPixmaps.arm = !m_armPixmap;
|
|
return m_armPixmap;
|
|
}
|
|
|
|
WXPixmap wxBitmapCache::GetInsensPixmap( WXWidget w )
|
|
{
|
|
if( m_insensPixmap && !m_recalcPixmaps.insens )
|
|
return m_insensPixmap;
|
|
|
|
CreateImageIfNeeded( w );
|
|
|
|
Screen* screen = DefaultScreenOfDisplay( (Display*)m_display );
|
|
|
|
if( m_insensPixmap )
|
|
XmDestroyPixmap( screen, (Pixmap)m_insensPixmap );
|
|
|
|
if( !m_image )
|
|
return (WXPixmap)NULL;
|
|
|
|
m_insensPixmap =
|
|
(WXPixmap)XCreateInsensitivePixmap( (Display*)m_display,
|
|
(Pixmap)m_bitmap.GetDrawable() );
|
|
|
|
m_recalcPixmaps.insens = !m_insensPixmap;
|
|
return m_insensPixmap;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Utility function
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
/****************************************************************************
|
|
|
|
NAME
|
|
XCreateInsensitivePixmap - create a grayed-out copy of a pixmap
|
|
|
|
SYNOPSIS
|
|
Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
|
|
|
|
DESCRIPTION
|
|
This function creates a grayed-out copy of the argument pixmap, suitable
|
|
for use as a XmLabel's XmNlabelInsensitivePixmap resource.
|
|
|
|
RETURN VALUES
|
|
The return value is the new Pixmap id or zero on error. Errors include
|
|
a NULL display argument or an invalid Pixmap argument.
|
|
|
|
ERRORS
|
|
If one of the XLib functions fail, it will produce a X error. The
|
|
default X error handler prints a diagnostic and calls exit().
|
|
|
|
SEE ALSO
|
|
XCopyArea(3), XCreateBitmapFromData(3), XCreateGC(3), XCreatePixmap(3),
|
|
XFillRectangle(3), exit(2)
|
|
|
|
AUTHOR
|
|
John R Veregge - john@puente.jpl.nasa.gov
|
|
Advanced Engineering and Prototyping Group (AEG)
|
|
Information Systems Technology Section (395)
|
|
Jet Propulsion Lab - Calif Institute of Technology
|
|
|
|
*****************************************************************************/
|
|
|
|
Pixmap
|
|
XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
|
|
|
|
{
|
|
static char stipple_data[] =
|
|
{
|
|
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
|
|
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
|
|
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
|
|
0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA
|
|
};
|
|
GC gc;
|
|
Pixmap ipixmap, stipple;
|
|
unsigned width, height, depth;
|
|
|
|
Window window; /* These return values */
|
|
unsigned border; /* from XGetGeometry() */
|
|
int x, y; /* are not needed. */
|
|
|
|
ipixmap = 0;
|
|
|
|
if ( NULL == display || 0 == pixmap )
|
|
return ipixmap;
|
|
|
|
if ( 0 == XGetGeometry( display, pixmap, &window, &x, &y,
|
|
&width, &height, &border, &depth )
|
|
)
|
|
return ipixmap; /* BadDrawable: probably an invalid pixmap */
|
|
|
|
/* Get the stipple pixmap to be used to 'gray-out' the argument pixmap.
|
|
*/
|
|
stipple = XCreateBitmapFromData( display, pixmap, stipple_data, 16, 16 );
|
|
if ( 0 != stipple )
|
|
{
|
|
gc = XCreateGC( display, pixmap, (XtGCMask)0, (XGCValues*)NULL );
|
|
if ( NULL != gc )
|
|
{
|
|
/* Create an identical copy of the argument pixmap.
|
|
*/
|
|
ipixmap = XCreatePixmap( display, pixmap, width, height, depth );
|
|
if ( 0 != ipixmap )
|
|
{
|
|
/* Copy the argument pixmap into the new pixmap.
|
|
*/
|
|
XCopyArea( display, pixmap, ipixmap,
|
|
gc, 0, 0, width, height, 0, 0 );
|
|
|
|
/* Refill the new pixmap using the stipple algorithm/pixmap.
|
|
*/
|
|
XSetStipple( display, gc, stipple );
|
|
XSetFillStyle( display, gc, FillStippled );
|
|
XFillRectangle( display, ipixmap, gc, 0, 0, width, height );
|
|
}
|
|
XFreeGC( display, gc );
|
|
}
|
|
XFreePixmap( display, stipple );
|
|
}
|
|
return ipixmap;
|
|
}
|