]> git.saurik.com Git - wxWidgets.git/blobdiff - src/motif/bmpmotif.cpp
Fixed copying only 1/3 of scanline when saving TIFF image in rare cases.
[wxWidgets.git] / src / motif / bmpmotif.cpp
index 0cb1dbadeb885a12a8f83bb77d72ce0d3ccade0b..51caa8e009566d616e3d42187ca0e40af57f3a59 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        bitmap.cpp
+// Name:        src/motif/bmpmotif.cpp
 // Purpose:     wxBitmap
 // Author:      Julian Smart, originally in bitmap.cpp
 // Modified by:
@@ -9,17 +9,15 @@
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "bmpmotif.h"
-#endif
-
-#ifdef __VMS
-#define XtParent XTPARENT
-#endif
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
 
-#include "wx/defs.h"
 #include "wx/motif/bmpmotif.h"
 
+#ifndef WX_PRECOMP
+    #include "wx/math.h"
+#endif
+
 #ifdef __VMS__
 #pragma message disable nosimpint
 #endif
 #if wxHAVE_LIB_XPM
     #include <X11/xpm.h>
 #endif
-#include <math.h>
 
 Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap );
 
+static inline wxCharBuffer GetCacheImageName(WXImage image)
+{
+    return wxString::Format(wxT("wxBitmap_%p"), image).ToAscii();
+}
+
 wxBitmapCache::~wxBitmapCache()
 {
     if( m_display )
@@ -63,7 +65,7 @@ wxBitmapCache::~wxBitmapCache()
 
 void wxBitmapCache::SetBitmap( const wxBitmap& bitmap )
 {
-    if( m_bitmap != bitmap )
+    if ( !m_bitmap.IsSameAs(bitmap) )
     {
         InvalidateCache();
         m_bitmap = bitmap;
@@ -72,7 +74,7 @@ void wxBitmapCache::SetBitmap( const wxBitmap& bitmap )
         {
             XmUninstallImage( (XImage*)m_image );
             XtFree( (char*)(XImage*)m_image );
-            m_image = (WXImage*)NULL;
+            m_image = NULL;
         }
     }
 }
@@ -99,7 +101,7 @@ void wxBitmapCache::CreateImageIfNeeded( WXWidget w )
                 (WXDisplay*)wxGetDisplay();
 
     XImage *ximage = XGetImage( (Display*)m_display,
-                                (Drawable)m_bitmap.GetPixmap(),
+                                (Drawable)m_bitmap.GetDrawable(),
                                 0, 0,
                                 m_bitmap.GetWidth(), m_bitmap.GetHeight(),
                                 AllPlanes, ZPixmap );
@@ -108,12 +110,26 @@ void wxBitmapCache::CreateImageIfNeeded( WXWidget w )
 
     if( m_image )
     {
-        char tmp[128];
-        sprintf( tmp, "Im%x", (unsigned int)ximage );
-        XmInstallImage( ximage, tmp );
+        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 )
@@ -129,21 +145,7 @@ WXPixmap wxBitmapCache::GetLabelPixmap( WXWidget w )
     if( !m_image )
         return (WXPixmap)NULL;
 
-    char tmp[128];
-    sprintf( tmp, "Im%x", (unsigned int)m_image );
-
-    Pixel fg, bg;
-    Widget widget = (Widget)w;
-
-    while( XmIsGadget( widget ) )
-        widget = XtParent( widget );
-    XtVaGetValues( widget,
-                   XmNbackground, &bg,
-                   XmNforeground, &fg,
-                   NULL );
-
-    m_labelPixmap = (WXPixmap)XmGetPixmap( screen, tmp, fg, bg );
-
+    m_labelPixmap = GetPixmapFromCache(w);
     m_recalcPixmaps.label = !m_labelPixmap;
     return m_labelPixmap;
 }
@@ -163,19 +165,7 @@ WXPixmap wxBitmapCache::GetArmPixmap( WXWidget w )
     if( !m_image )
         return (WXPixmap)NULL;
 
-    char tmp[128];
-    sprintf( tmp, "Im%x", (unsigned int)m_image );
-
-    Pixel fg, bg;
-    Widget widget = (Widget) w;
-
-    XtVaGetValues( widget, XmNarmColor, &bg, NULL );
-    while( XmIsGadget( widget ) )
-        widget = XtParent( widget );
-    XtVaGetValues( widget, XmNforeground, &fg, NULL );
-
-    m_armPixmap = (WXPixmap)XmGetPixmap( screen, tmp, fg, bg );
-
+    m_armPixmap = GetPixmapFromCache(w);
     m_recalcPixmaps.arm = !m_armPixmap;
     return m_armPixmap;
 }
@@ -197,8 +187,104 @@ WXPixmap wxBitmapCache::GetInsensPixmap( WXWidget w )
 
     m_insensPixmap =
         (WXPixmap)XCreateInsensitivePixmap( (Display*)m_display,
-                                            (Pixmap)m_bitmap.GetPixmap() );
+                                            (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, 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;
+}