--- qt-x11-free-3.3.8/src/kernel/qpixmap_x11.cpp.orig	2007-02-02 19:31:11.000000000 +0530
+++ qt-x11-free-3.3.8/src/kernel/qpixmap_x11.cpp	2008-01-08 20:53:54.083245433 +0530
@@ -37,7 +37,19 @@
 
 // NOT REVISED
 
+#include "qplatformdefs.h"
+
+#if defined(Q_OS_WIN32) && defined(QT_MITSHM)
+#undef QT_MITSHM
+#endif
+
+#ifdef QT_MITSHM
+
+// Use the MIT Shared Memory extension for pixmap<->image conversions
+#define QT_MITSHM_CONVERSIONS
+
 // Uncomment the next line to enable the MIT Shared Memory extension
+// for QPixmap::xForm()
 //
 // WARNING:  This has some problems:
 //
@@ -45,14 +57,13 @@
 //    2. Qt does not handle the ShmCompletion message, so you will
 //        get strange effects if you xForm() repeatedly.
 //
-// #define QT_MITSHM
+// #define QT_MITSHM_XFORM
 
-#if defined(Q_OS_WIN32) && defined(QT_MITSHM)
-#undef QT_MITSHM
+#else
+#undef QT_MITSHM_CONVERSIONS
+#undef QT_MITSHM_XFORM
 #endif
 
-#include "qplatformdefs.h"
-
 #include "qbitmap.h"
 #include "qpaintdevicemetrics.h"
 #include "qimage.h"
@@ -91,7 +102,7 @@
   MIT Shared Memory Extension support: makes xForm noticeably (~20%) faster.
  *****************************************************************************/
 
-#if defined(QT_MITSHM)
+#if defined(QT_MITSHM_XFORM)
 
 static bool	       xshminit = FALSE;
 static XShmSegmentInfo xshminfo;
@@ -173,8 +184,100 @@
 //     return FALSE;
 // }
 
-#endif // QT_MITSHM
+#endif // QT_MITSHM_XFORM
+
+#ifdef QT_MITSHM_CONVERSIONS
 
+static bool qt_mitshm_error = false;
+static int qt_mitshm_errorhandler( Display*, XErrorEvent* )
+{
+    qt_mitshm_error = true;
+    return 0;
+}
+
+static XImage* qt_XShmCreateImage( Display* dpy, Visual* visual, unsigned int depth,
+    int format, int /*offset*/, char* /*data*/, unsigned int width, unsigned int height,
+    int /*bitmap_pad*/, int /*bytes_per_line*/, XShmSegmentInfo* shminfo )
+{
+    if( width * height * depth < 100*100*32 )
+        return NULL;
+    static int shm_inited = -1;
+    if( shm_inited == -1 ) {
+        if( XShmQueryExtension( dpy ))
+            shm_inited = 1;
+        else
+            shm_inited = 0;
+    }
+    if( shm_inited == 0 )
+        return NULL;
+    XImage* xi = XShmCreateImage( dpy, visual, depth, format, NULL, shminfo, width,
+        height );
+    if( xi == NULL )
+        return NULL;
+    shminfo->shmid = shmget( IPC_PRIVATE, xi->bytes_per_line * xi->height,
+        IPC_CREAT|0600);
+    if( shminfo->shmid < 0 ) {
+        XDestroyImage( xi );
+        return NULL;
+    }
+    shminfo->readOnly = False;
+    shminfo->shmaddr = (char*)shmat( shminfo->shmid, 0, 0 );
+    if( shminfo->shmaddr == (char*)-1 ) {
+        XDestroyImage( xi );
+        shmctl( shminfo->shmid, IPC_RMID, 0 );
+        return NULL;
+    }
+    xi->data = shminfo->shmaddr;
+#ifndef QT_MITSHM_RMID_IGNORES_REFCOUNT
+    // mark as deleted to automatically free the memory in case
+    // of a crash (but this doesn't work e.g. on Solaris)
+    shmctl( shminfo->shmid, IPC_RMID, 0 );
+#endif
+    if( shm_inited == 1 ) { // first time
+        XErrorHandler old_h = XSetErrorHandler( qt_mitshm_errorhandler );
+        XShmAttach( dpy, shminfo );
+        shm_inited = 2;
+        XSync( dpy, False );
+        XSetErrorHandler( old_h );
+        if( qt_mitshm_error ) { // oops ... perhaps we are remote?
+            shm_inited = 0;
+            XDestroyImage( xi );
+            shmdt( shminfo->shmaddr );
+#ifdef QT_MITSHM_RMID_IGNORES_REFCOUNT
+            shmctl( shminfo->shmid, IPC_RMID, 0 );
+#endif    
+            return NULL;
+        }
+    } else
+        XShmAttach( dpy, shminfo );
+    return xi;
+}
+
+static void qt_XShmDestroyImage( XImage* xi, XShmSegmentInfo* shminfo )
+{
+    XShmDetach( QPaintDevice::x11AppDisplay(), shminfo );
+    XDestroyImage( xi );
+    shmdt( shminfo->shmaddr );
+#ifdef QT_MITSHM_RMID_IGNORES_REFCOUNT
+    shmctl( shminfo->shmid, IPC_RMID, 0 );
+#endif    
+}
+
+static XImage* qt_XShmGetImage( const QPixmap* pix, int format,
+    XShmSegmentInfo* shminfo )
+{
+    XImage* xi = qt_XShmCreateImage( pix->x11Display(), (Visual*)pix->x11Visual(),
+        pix->depth(), format, 0, 0, pix->width(), pix->height(), 32, 0, shminfo );
+    if( xi == NULL )
+        return NULL;
+    if( XShmGetImage( pix->x11Display(), pix->handle(), xi, 0, 0, AllPlanes ) == False ) {
+        qt_XShmDestroyImage( xi, shminfo );
+        return NULL;
+    }
+    return xi;
+}
+
+#endif // QT_MITSHM_CONVERSIONS
 
 /*****************************************************************************
   Internal functions
@@ -627,9 +730,20 @@
 	d = 32;					//   > 8  ==> 32
 
     XImage *xi = (XImage *)data->ximage;	// any cached ximage?
-    if ( !xi )					// fetch data from X server
-	xi = XGetImage( x11Display(), hd, 0, 0, w, h, AllPlanes,
+#ifdef QT_MITSHM_CONVERSIONS
+    bool mitshm_ximage = false;
+    XShmSegmentInfo shminfo;
+#endif
+    if ( !xi ) {				// fetch data from X server
+#ifdef QT_MITSHM_CONVERSIONS
+        xi = qt_XShmGetImage( this, mono ? XYPixmap : ZPixmap, &shminfo );
+        if( xi ) {
+            mitshm_ximage = true;
+        } else
+#endif
+	    xi = XGetImage( x11Display(), hd, 0, 0, w, h, AllPlanes,
 			mono ? XYPixmap : ZPixmap );
+    }
     Q_CHECK_PTR( xi );
     if (!xi)
         return image; // null image
@@ -640,15 +754,31 @@
 		   QImage::LittleEndian : QImage::BigEndian;
     }
     image.create( w, h, d, 0, bitOrder );
-    if ( image.isNull() )			// could not create image
+    if ( image.isNull() ) {			// could not create image
+#ifdef QT_MITSHM_CONVERSIONS
+        if( mitshm_ximage )
+            qt_XShmDestroyImage( xi, &shminfo );
+        else
+#endif
+        qSafeXDestroyImage( xi );
 	return image;
+    }
 
     const QPixmap* msk = mask();
     const QPixmap *alf = data->alphapm;
 
     QImage alpha;
     if (alf) {
-	XImage *axi = XGetImage(x11Display(), alf->hd, 0, 0, w, h, AllPlanes, ZPixmap);
+        XImage* axi;
+#ifdef QT_MITSHM_CONVERSIONS
+        bool mitshm_aximage = false;
+        XShmSegmentInfo ashminfo;
+        axi = qt_XShmGetImage( alf, ZPixmap, &ashminfo );
+        if( axi ) {
+            mitshm_aximage = true;
+        } else
+#endif
+            axi = XGetImage(x11Display(), alf->hd, 0, 0, w, h, AllPlanes, ZPixmap);
 
 	if (axi) {
 	    image.setAlphaBuffer( TRUE );
@@ -662,7 +792,12 @@
 		src += axi->bytes_per_line;
 	    }
 
-	    qSafeXDestroyImage( axi );
+#ifdef QT_MITSHM_CONVERSIONS
+            if( mitshm_aximage )
+                qt_XShmDestroyImage( axi, &ashminfo );
+            else
+#endif
+    	        qSafeXDestroyImage( axi );
 	}
     } else if (msk) {
 	image.setAlphaBuffer( TRUE );
@@ -804,6 +939,12 @@
 		  xi->bits_per_pixel );
 #endif
 	image.reset();
+#ifdef QT_MITSHM_CONVERSIONS
+        if( mitshm_ximage )
+            qt_XShmDestroyImage( xi, &shminfo );
+        else
+#endif
+            qSafeXDestroyImage( xi );
 	return image;
     }
 
@@ -909,10 +1050,22 @@
 	delete [] carr;
     }
     if ( data->optim != BestOptim ) {		// throw away image data
-	qSafeXDestroyImage( xi );
+#ifdef QT_MITSHM_CONVERSIONS
+        if( mitshm_ximage )
+            qt_XShmDestroyImage( xi, &shminfo );
+        else
+#endif
+            qSafeXDestroyImage( xi );
 	((QPixmap*)this)->data->ximage = 0;
-    } else					// keep ximage data
+    } else {					// keep ximage data
+#ifdef QT_MITSHM_CONVERSIONS
+        if( mitshm_ximage ) { // copy the XImage?
+            qt_XShmDestroyImage( xi, &shminfo );
+            xi = 0;
+        }
+#endif
 	((QPixmap*)this)->data->ximage = xi;
+    }
 
     return image;
 }
@@ -1085,6 +1238,11 @@
     bool    trucol = (visual->c_class == TrueColor || visual->c_class == DirectColor);
     int	    nbytes = image.numBytes();
     uchar  *newbits= 0;
+    int newbits_size = 0;
+#ifdef QT_MITSHM_CONVERSIONS
+    bool mitshm_ximage = false;
+    XShmSegmentInfo shminfo;
+#endif
 
     if ( trucol ) {				// truecolor display
 	QRgb  pix[256];				// pixel translation table
@@ -1113,11 +1271,20 @@
 	    }
 	}
 
-	xi = XCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0 );
+#ifdef QT_MITSHM_CONVERSIONS
+        xi = qt_XShmCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0, &shminfo );
+        if( xi != NULL ) {
+            mitshm_ximage = true;
+            newbits = (uchar*)xi->data;
+        }
+        else
+#endif
+	    xi = XCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0 );
 	Q_CHECK_PTR( xi );
         if (!xi)
             return false;
-	newbits = (uchar *)malloc( xi->bytes_per_line*h );
+	if( newbits == NULL )
+	    newbits = (uchar *)malloc( xi->bytes_per_line*h );
 	Q_CHECK_PTR( newbits );
 	if ( !newbits )				// no memory
 	    return FALSE;
@@ -1323,6 +1490,7 @@
 	}
 
 	newbits = (uchar *)malloc( nbytes );	// copy image into newbits
+        newbits_size = nbytes;
 	Q_CHECK_PTR( newbits );
 	if ( !newbits )				// no memory
 	    return FALSE;
@@ -1440,11 +1608,18 @@
     }
 
     if ( !xi ) {				// X image not created
-	xi = XCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0 );
+#ifdef QT_MITSHM_CONVERSIONS
+        xi = qt_XShmCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0, &shminfo );
+        if( xi != NULL )
+            mitshm_ximage = true;
+        else
+#endif
+	    xi = XCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0 );
 	if ( xi->bits_per_pixel == 16 ) {	// convert 8 bpp ==> 16 bpp
 	    ushort *p2;
 	    int	    p2inc = xi->bytes_per_line/sizeof(ushort);
 	    ushort *newerbits = (ushort *)malloc( xi->bytes_per_line * h );
+            newbits_size = xi->bytes_per_line * h;
 	    Q_CHECK_PTR( newerbits );
 	    if ( !newerbits )				// no memory
 		return FALSE;
@@ -1462,7 +1637,15 @@
 		      "(bpp=%d)", xi->bits_per_pixel );
 #endif
 	}
-	xi->data = (char *)newbits;
+#ifdef QT_MITSHM_CONVERSIONS
+        if( newbits_size > 0 && mitshm_ximage ) { // need to copy to shared memory
+            memcpy( xi->data, newbits, newbits_size );
+            free( newbits );
+            newbits = (uchar*)xi->data;
+        }
+        else
+#endif
+            xi->data = (char *)newbits;
     }
 
     if ( hd && (width() != (int)w || height() != (int)h || this->depth() != dd) ) {
@@ -1495,19 +1678,24 @@
 
     }
 
-    XPutImage( dpy, hd, qt_xget_readonly_gc( x11Screen(), FALSE  ),
-	       xi, 0, 0, 0, 0, w, h );
+#ifdef QT_MITSHM_CONVERSIONS
+    if( mitshm_ximage )
+        XShmPutImage( dpy, hd, qt_xget_readonly_gc( x11Screen(), FALSE ),
+                      xi, 0, 0, 0, 0, w, h, False );
+    else
+#endif
+        XPutImage( dpy, hd, qt_xget_readonly_gc( x11Screen(), FALSE  ),
+                   xi, 0, 0, 0, 0, w, h );
 
-    if ( data->optim != BestOptim ) {		// throw away image
-	qSafeXDestroyImage( xi );
-	data->ximage = 0;
-    } else {					// keep ximage that we created
-	data->ximage = xi;
-    }
     data->w = w;
     data->h = h;
     data->d = dd;
 
+    XImage* axi = NULL;
+#ifdef QT_MITSHM_CONVERSIONS
+    bool mitshm_aximage = false;
+    XShmSegmentInfo ashminfo;
+#endif
     if ( image.hasAlphaBuffer() ) {
 	QBitmap m;
 	m = image.createAlphaMask( conversion_flags );
@@ -1543,13 +1731,22 @@
 	    data->alphapm->rendhd =
 		(HANDLE) XftDrawCreateAlpha( x11Display(), data->alphapm->hd, 8 );
 
-	    XImage *axi = XCreateImage(x11Display(), (Visual *) x11Visual(),
+#ifdef QT_MITSHM_CONVERSIONS
+            axi = qt_XShmCreateImage( x11Display(), (Visual*)x11Visual(),
+                                      8, ZPixmap, 0, 0, w, h, 8, 0, &ashminfo );
+            if( axi != NULL )
+                mitshm_aximage = true;
+            else
+#endif
+	        axi = XCreateImage(x11Display(), (Visual *) x11Visual(),
 				       8, ZPixmap, 0, 0, w, h, 8, 0);
 
 	    if (axi) {
-		// the data is deleted by qSafeXDestroyImage
-                axi->data = (char *) malloc(h * axi->bytes_per_line);
-		Q_CHECK_PTR( axi->data );
+		if( axi->data==NULL ) {
+		    // the data is deleted by qSafeXDestroyImage
+                    axi->data = (char *) malloc(h * axi->bytes_per_line);
+		    Q_CHECK_PTR( axi->data );
+		}
                 char *aptr = axi->data;
 
                 if (image.depth() == 32) {
@@ -1567,7 +1764,12 @@
                 }
 
                 GC gc = XCreateGC(x11Display(), data->alphapm->hd, 0, 0);
-                XPutImage(dpy, data->alphapm->hd, gc, axi, 0, 0, 0, 0, w, h);
+#ifdef QT_MITSHM_CONVERSIONS
+                if( mitshm_aximage )
+                    XShmPutImage( dpy, data->alphapm->hd, gc, axi, 0, 0, 0, 0, w, h, False );
+                else
+#endif
+                    XPutImage(dpy, data->alphapm->hd, gc, axi, 0, 0, 0, 0, w, h);
                 XFreeGC(x11Display(), gc);
 		qSafeXDestroyImage(axi);
 	    }
@@ -1737,7 +1939,7 @@
 	return pm;
     }
 
-#if defined(QT_MITSHM)
+#if defined(QT_MITSHM_XFORM)
     static bool try_once = TRUE;
     if (try_once) {
 	try_once = FALSE;
@@ -1770,7 +1972,7 @@
 	dbpl = ((w*bpp+31)/32)*4;
     dbytes = dbpl*h;
 
-#if defined(QT_MITSHM)
+#if defined(QT_MITSHM_XFORM)
     if ( use_mitshm ) {
 	dptr = (uchar *)xshmimg->data;
 	uchar fillbyte = bpp == 8 ? white.pixel() : 0xff;
@@ -1786,7 +1988,7 @@
 	    memset( dptr, Qt::white.pixel( x11Screen() ), dbytes );
 	else
 	    memset( dptr, 0xff, dbytes );
-#if defined(QT_MITSHM)
+#if defined(QT_MITSHM_XFORM)
     }
 #endif
 
@@ -1817,7 +2019,7 @@
     } else {
 	xbpl  = (w*bpp)/8;
 	p_inc = dbpl - xbpl;
-#if defined(QT_MITSHM)
+#if defined(QT_MITSHM_XFORM)
 	if ( use_mitshm )
 	    p_inc = xshmimg->bytes_per_line - xbpl;
 #endif
@@ -1854,7 +2056,7 @@
 	QPixmap pm( w, h );
 	pm.data->uninit = FALSE;
 	pm.x11SetScreen( x11Screen() );
-#if defined(QT_MITSHM)
+#if defined(QT_MITSHM_XFORM)
 	if ( use_mitshm ) {
 	    XCopyArea( dpy, xshmpm, pm.handle(), gc, 0, 0, w, h, 0, 0 );
 	} else {
@@ -1863,7 +2065,7 @@
 			       ZPixmap, 0, (char *)dptr, w, h, 32, 0 );
 	    XPutImage( dpy, pm.handle(), gc, xi, 0, 0, 0, 0, w, h);
 	    qSafeXDestroyImage( xi );
-#if defined(QT_MITSHM)
+#if defined(QT_MITSHM_XFORM)
 	}
 #endif
 
--- qt-x11-free-3.3.8/mkspecs/linux-g++/qplatformdefs.h.orig	2008-01-08 20:53:20.515026849 +0530
+++ qt-x11-free-3.3.8/mkspecs/linux-g++/qplatformdefs.h	2008-01-08 20:53:32.448225016 +0530
@@ -102,5 +102,6 @@
 #define QT_VSNPRINTF		::vsnprintf
 #endif
 
+#define QT_MITSHM
 
 #endif // QPLATFORMDEFS_H
