summaryrefslogtreecommitdiffstats
path: root/tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp')
-rw-r--r--tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp593
1 files changed, 478 insertions, 115 deletions
diff --git a/tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp b/tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp
index 974f23c..2a497e5 100644
--- a/tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp
+++ b/tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp
@@ -40,7 +40,19 @@
// NOT REVISED
+#include "tqplatformdefs.h"
+
+#if defined(Q_OS_WIN32) && defined(TQT_MITSHM)
+#undef TQT_MITSHM
+#endif
+
+#ifdef TQT_MITSHM
+
+// Use the MIT Shared Memory extension for pixmap<->image conversions
+#define TQT_MITSHM_CONVERSIONS
+
// Uncomment the next line to enable the MIT Shared Memory extension
+// for TQPixmap::xForm()
//
// WARNING: This has some problems:
//
@@ -48,7 +60,7 @@
// 2. TQt does not handle the ShmCompletion message, so you will
// get strange effects if you xForm() repeatedly.
//
-// #define TQT_MITSHM
+// #define TQT_MITSHM_XFORM
#if defined(TQ_OS_WIN32) && defined(TQT_MITSHM)
#undef TQT_MITSHM
@@ -131,7 +143,7 @@ inline static void qSafeXDestroyImage( XImage *x )
MIT Shared Memory Extension support: makes xForm noticeably (~20%) faster.
*****************************************************************************/
-#if defined(TQT_MITSHM)
+#if defined(TQT_MITSHM_XFORM)
static bool xshminit = FALSE;
static XShmSegmentInfo xshminfo;
@@ -213,8 +225,100 @@ static bool qt_create_mitshm_buffer( const TQPaintDevice* dev, int w, int h )
// return FALSE;
// }
-#endif // TQT_MITSHM
+#endif // TQT_MITSHM_XFORM
+
+#ifdef TQT_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 TQT_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 TQT_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( TQPaintDevice::x11AppDisplay(), shminfo );
+ XDestroyImage( xi );
+ shmdt( shminfo->shmaddr );
+#ifdef TQT_MITSHM_RMID_IGNORES_REFCOUNT
+ shmctl( shminfo->shmid, IPC_RMID, 0 );
+#endif
+}
+static XImage* qt_XShmGetImage( const TQPixmap* 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 // TQT_MITSHM_CONVERSIONS
/*****************************************************************************
Internal functions
@@ -667,9 +771,20 @@ TQImage TQPixmap::convertToImage() const
d = 32; // > 8 ==> 32
XImage *xi = (XImage *)data->ximage; // any cached ximage?
- if ( !xi ) // fetch data from X server
+#ifdef TQT_MITSHM_CONVERSIONS
+ bool mitshm_ximage = false;
+ XShmSegmentInfo shminfo;
+#endif
+ if ( !xi ) { // fetch data from X server
+#ifdef TQT_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 );
+ }
TQ_CHECK_PTR( xi );
if (!xi)
return image; // null image
@@ -680,15 +795,31 @@ TQImage TQPixmap::convertToImage() const
TQImage::LittleEndian : TQImage::BigEndian;
}
image.create( w, h, d, 0, bitOrder );
- if ( image.isNull() ) // could not create image
+ if ( image.isNull() ) { // could not create image
+#ifdef TQT_MITSHM_CONVERSIONS
+ if( mitshm_ximage )
+ qt_XShmDestroyImage( xi, &shminfo );
+ else
+#endif
+ qSafeXDestroyImage( xi );
return image;
+ }
const TQPixmap* msk = tqmask();
const TQPixmap *alf = data->alphapm;
TQImage alpha;
if (alf) {
- XImage *axi = XGetImage(x11Display(), alf->hd, 0, 0, w, h, AllPlanes, ZPixmap);
+ XImage* axi;
+#ifdef TQT_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 );
@@ -702,6 +833,11 @@ TQImage TQPixmap::convertToImage() const
src += axi->bytes_per_line;
}
+#ifdef TQT_MITSHM_CONVERSIONS
+ if( mitshm_aximage )
+ qt_XShmDestroyImage( axi, &ashminfo );
+ else
+#endif
qSafeXDestroyImage( axi );
}
} else if (msk) {
@@ -844,6 +980,12 @@ TQImage TQPixmap::convertToImage() const
xi->bits_per_pixel );
#endif
image.reset();
+#ifdef TQT_MITSHM_CONVERSIONS
+ if( mitshm_ximage )
+ qt_XShmDestroyImage( xi, &shminfo );
+ else
+#endif
+ qSafeXDestroyImage( xi );
return image;
}
@@ -949,10 +1091,22 @@ TQImage TQPixmap::convertToImage() const
delete [] carr;
}
if ( data->optim != BestOptim ) { // throw away image data
+#ifdef TQT_MITSHM_CONVERSIONS
+ if( mitshm_ximage )
+ qt_XShmDestroyImage( xi, &shminfo );
+ else
+#endif
qSafeXDestroyImage( xi );
((TQPixmap*)this)->data->ximage = 0;
- } else // keep ximage data
+ } else { // keep ximage data
+#ifdef TQT_MITSHM_CONVERSIONS
+ if( mitshm_ximage ) { // copy the XImage?
+ qt_XShmDestroyImage( xi, &shminfo );
+ xi = 0;
+ }
+#endif
((TQPixmap*)this)->data->ximage = xi;
+ }
return image;
}
@@ -1125,6 +1279,11 @@ bool TQPixmap::convertFromImage( const TQImage &img, int conversion_flags )
bool trucol = (visual->c_class == TrueColor || visual->c_class == DirectColor);
int nbytes = image.numBytes();
uchar *newbits= 0;
+ int newbits_size = 0;
+#ifdef TQT_MITSHM_CONVERSIONS
+ bool mitshm_ximage = false;
+ XShmSegmentInfo shminfo;
+#endif
if ( trucol ) { // truecolor display
TQRgb pix[256]; // pixel translation table
@@ -1153,19 +1312,24 @@ bool TQPixmap::convertFromImage( const TQImage &img, int conversion_flags )
}
}
+#ifdef TQT_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 );
- TQ_CHECK_PTR( xi );
if (!xi)
return false;
+ if( newbits == NULL )
newbits = (uchar *)malloc( xi->bytes_per_line*h );
TQ_CHECK_PTR( newbits );
if ( !newbits ) // no memory
return FALSE;
int bppc = xi->bits_per_pixel;
- if ( bppc > 8 && xi->byte_order == LSBFirst )
- bppc++;
-
bool contig_bits = n_bits(red_mask) == rbits &&
n_bits(green_mask) == gbits &&
n_bits(blue_mask) == bbits;
@@ -1215,31 +1379,70 @@ bool TQPixmap::convertFromImage( const TQImage &img, int conversion_flags )
init=TRUE;
}
- for ( uint y=0; y<h; y++ ) {
- uchar* src = image.scanLine( y );
- uchar* dst = newbits + xi->bytes_per_line*y;
- TQRgb* p = (TQRgb *)src;
+ enum { BPP8,
+ BPP16_8_3_M3, BPP16_7_2_M3, BPP16_MSB, BPP16_LSB,
+ BPP24_MSB, BPP24_LSB,
+ BPP32_16_8_0, BPP32_MSB, BPP32_LSB
+ } mode = BPP8;
-#define GET_RGB \
- int r = tqRed ( *p ); \
- int g = tqGreen( *p ); \
- int b = tqBlue ( *p++ ); \
- r = red_shift > 0 \
- ? r << red_shift : r >> -red_shift; \
- g = green_shift > 0 \
- ? g << green_shift : g >> -green_shift; \
- b = blue_shift > 0 \
- ? b << blue_shift : b >> -blue_shift;
+ if ( bppc > 8 && xi->byte_order == LSBFirst )
+ bppc++;
+
+ int wordsize;
+ bool bigendian;
+ qSysInfo( &wordsize, &bigendian );
+ bool same_msb_lsb = ( xi->byte_order == MSBFirst ) == ( bigendian );
+
+ if( bppc == 8 ) // 8 bit
+ mode = BPP8;
+ else if( bppc == 16 || bppc == 17 ) { // 16 bit MSB/LSB
+ if( red_shift == 8 && green_shift == 3 && blue_shift == -3
+ && !d8 && same_msb_lsb )
+ mode = BPP16_8_3_M3;
+ else if( red_shift == 7 && green_shift == 2 && blue_shift == -3
+ && !d8 && same_msb_lsb )
+ mode = BPP16_7_2_M3;
+ else
+ mode = bppc == 17 ? BPP16_LSB : BPP16_MSB;
+ } else if( bppc == 24 || bppc == 25 ) { // 24 bit MSB/LSB
+ mode = bppc == 25 ? BPP24_LSB : BPP24_MSB;
+ } else if( bppc == 32 || bppc == 33 ) { // 32 bit MSB/LSB
+ if( red_shift == 16 && green_shift == 8 && blue_shift == 0
+ && !d8 && same_msb_lsb )
+ mode = BPP32_16_8_0;
+ else
+ mode = bppc == 33 ? BPP32_LSB : BPP32_MSB;
+ } else
+ qFatal("Logic error 3");
#define GET_PIXEL \
int pixel; \
if ( d8 ) pixel = pix[*src++]; \
else { \
- GET_RGB \
- pixel = (b & blue_mask)|(g & green_mask) | (r & red_mask) \
+ int r = tqRed ( *p ); \
+ int g = tqGreen( *p ); \
+ int b = tqBlue ( *p++ ); \
+ r = red_shift > 0 \
+ ? r << red_shift : r >> -red_shift; \
+ g = green_shift > 0 \
+ ? g << green_shift : g >> -green_shift; \
+ b = blue_shift > 0 \
+ ? b << blue_shift : b >> -blue_shift; \
+ pixel = (r & red_tqmask)|(g & green_tqmask) | (b & blue_tqmask) \
| ~(blue_mask | green_mask | red_mask); \
}
+// optimized case - no d8 case, shift only once instead of twice, tqmask only once instead of twice,
+// use direct values instead of variables, and use only one statement
+// (*p >> 16), (*p >> 8 ) and (*p) are tqRed(),tqGreen() and tqBlue() without masking
+// shifts have to be passed including the shift operator (e.g. '>>3'), because of the direction
+#define GET_PIXEL_OPT(red_shift,green_shift,blue_shift,red_tqmask,green_tqmask,blue_tqmask) \
+ int pixel = ((( *p >> 16 ) red_shift ) & red_tqmask ) \
+ | ((( *p >> 8 ) green_shift ) & green_tqmask ) \
+ | ((( *p ) blue_shift ) & blue_tqmask ); \
+ ++p;
+
+
#define GET_PIXEL_DITHER_TC \
int r = tqRed ( *p ); \
int g = tqGreen( *p ); \
@@ -1262,89 +1465,176 @@ bool TQPixmap::convertFromImage( const TQImage &img, int conversion_flags )
? b << blue_shift : b >> -blue_shift; \
int pixel = (b & blue_mask)|(g & green_mask) | (r & red_mask);
- if ( dither_tc ) {
- uint x;
- switch ( bppc ) {
- case 16: // 16 bit MSB
- for ( x=0; x<w; x++ ) {
- GET_PIXEL_DITHER_TC
- *dst++ = (pixel >> 8);
- *dst++ = pixel;
- }
+// again, optimized case
+// can't be optimized that much :(
+#define GET_PIXEL_DITHER_TC_OPT(red_shift,green_shift,blue_shift,red_tqmask,green_tqmask,blue_tqmask, \
+ rbits,gbits,bbits) \
+ const int thres = D[x%16][y%16]; \
+ int r = tqRed ( *p ); \
+ if ( r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
+ > thres) \
+ r += (1<<(8-rbits)); \
+ int g = tqGreen( *p ); \
+ if ( g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
+ > thres) \
+ g += (1<<(8-gbits)); \
+ int b = tqBlue ( *p++ ); \
+ if ( b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
+ > thres) \
+ b += (1<<(8-bbits)); \
+ int pixel = (( r red_shift ) & red_tqmask ) \
+ | (( g green_shift ) & green_tqmask ) \
+ | (( b blue_shift ) & blue_tqmask );
+
+#define CYCLE(body) \
+ for ( uint y=0; y<h; y++ ) { \
+ uchar* src = image.scanLine( y ); \
+ uchar* dst = newbits + xi->bytes_per_line*y; \
+ TQRgb* p = (TQRgb *)src; \
+ body \
+ }
+
+ if ( dither_tc ) {
+ switch ( mode ) {
+ case BPP16_8_3_M3:
+ CYCLE(
+ TQ_INT16* dst16 = (TQ_INT16*)dst;
+ for ( uint x=0; x<w; x++ ) {
+ GET_PIXEL_DITHER_TC_OPT(<<8,<<3,>>3,0xf800,0x7e0,0x1f,5,6,5)
+ *dst16++ = pixel;
+ }
+ )
break;
- case 17: // 16 bit LSB
- for ( x=0; x<w; x++ ) {
- GET_PIXEL_DITHER_TC
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- }
+ case BPP16_7_2_M3:
+ CYCLE(
+ TQ_INT16* dst16 = (TQ_INT16*)dst;
+ for ( uint x=0; x<w; x++ ) {
+ GET_PIXEL_OPT(<<7,<<2,>>3,0x7c00,0x3e0,0x1f)
+ *dst16++ = pixel;
+ }
+ )
break;
default:
qFatal("Logic error");
}
- } else {
- uint x;
- switch ( bppc ) {
- case 8: // 8 bit
- for ( x=0; x<w; x++ ) {
- int pixel = pix[*src++];
- *dst++ = pixel;
- }
+ } else {
+ switch ( mode ) {
+ case BPP8: // 8 bit
+ CYCLE(
+ Q_UNUSED(p);
+ for ( uint x=0; x<w; x++ ) {
+ int pixel = pix[*src++];
+ *dst++ = pixel;
+ }
+ )
break;
- case 16: // 16 bit MSB
- for ( x=0; x<w; x++ ) {
- GET_PIXEL
- *dst++ = (pixel >> 8);
- *dst++ = pixel;
- }
+ case BPP16_8_3_M3:
+ CYCLE(
+ TQ_INT16* dst16 = (TQ_INT16*)dst;
+ for ( uint x=0; x<w; x++ ) {
+ GET_PIXEL_OPT(<<8,<<3,>>3,0xf800,0x7e0,0x1f)
+ *dst16++ = pixel;
+ }
+ )
break;
- case 17: // 16 bit LSB
- for ( x=0; x<w; x++ ) {
- GET_PIXEL
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- }
+ case BPP16_7_2_M3:
+ CYCLE(
+ TQ_INT16* dst16 = (TQ_INT16*)dst;
+ for ( uint x=0; x<w; x++ ) {
+ GET_PIXEL_DITHER_TC_OPT(<<7,<<2,>>3,0x7c00,0x3e0,0x1f,5,5,5)
+ *dst16++ = pixel;
+ }
+ )
break;
- case 24: // 24 bit MSB
- for ( x=0; x<w; x++ ) {
- GET_PIXEL
- *dst++ = pixel >> 16;
- *dst++ = pixel >> 8;
- *dst++ = pixel;
- }
+ case BPP16_MSB: // 16 bit MSB
+ CYCLE(
+ for ( uint x=0; x<w; x++ ) {
+ GET_PIXEL_DITHER_TC
+ *dst++ = (pixel >> 8);
+ *dst++ = pixel;
+ }
+ )
break;
- case 25: // 24 bit LSB
- for ( x=0; x<w; x++ ) {
- GET_PIXEL
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- *dst++ = pixel >> 16;
- }
+ case BPP16_LSB: // 16 bit LSB
+ CYCLE(
+ for ( uint x=0; x<w; x++ ) {
+ GET_PIXEL_DITHER_TC
+ *dst++ = pixel;
+ *dst++ = pixel >> 8;
+ }
+ )
break;
- case 32: // 32 bit MSB
- for ( x=0; x<w; x++ ) {
- GET_PIXEL
- *dst++ = pixel >> 24;
- *dst++ = pixel >> 16;
- *dst++ = pixel >> 8;
- *dst++ = pixel;
- }
+ case BPP16_MSB: // 16 bit MSB
+ CYCLE(
+ for ( uint x=0; x<w; x++ ) {
+ GET_PIXEL
+ *dst++ = (pixel >> 8);
+ *dst++ = pixel;
+ }
+ )
+ break;
+ case BPP16_LSB: // 16 bit LSB
+ CYCLE(
+ for ( uint x=0; x<w; x++ ) {
+ GET_PIXEL
+ *dst++ = pixel;
+ *dst++ = pixel >> 8;
+ }
+ )
+ break;
+ case BPP24_MSB: // 24 bit MSB
+ CYCLE(
+ for ( uint x=0; x<w; x++ ) {
+ GET_PIXEL
+ *dst++ = pixel >> 16;
+ *dst++ = pixel >> 8;
+ *dst++ = pixel;
+ }
+ )
break;
case 33: // 32 bit LSB
- for ( x=0; x<w; x++ ) {
- GET_PIXEL
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- *dst++ = pixel >> 16;
- *dst++ = pixel >> 24;
- }
+ case BPP24_LSB: // 24 bit LSB
+ CYCLE(
+ for ( uint x=0; x<w; x++ ) {
+ GET_PIXEL
+ *dst++ = pixel;
+ *dst++ = pixel >> 8;
+ *dst++ = pixel >> 16;
+ }
+ )
break;
- default:
- qFatal("Logic error 2");
- }
- }
- }
- xi->data = (char *)newbits;
+ case BPP32_16_8_0:
+ CYCLE(
+ memcpy( dst, p, w * 4 );
+ )
+ break;
+ case BPP32_MSB: // 32 bit MSB
+ CYCLE(
+ for ( uint x=0; x<w; x++ ) {
+ GET_PIXEL
+ *dst++ = pixel >> 24;
+ *dst++ = pixel >> 16;
+ *dst++ = pixel >> 8;
+ *dst++ = pixel;
+ }
+ )
+ break;
+ case BPP32_LSB: // 32 bit LSB
+ CYCLE(
+ for ( uint x=0; x<w; x++ ) {
+ GET_PIXEL
+ *dst++ = pixel;
+ *dst++ = pixel >> 8;
+ *dst++ = pixel >> 16;
+ *dst++ = pixel >> 24;
+ }
+ )
+ break;
+ default:
+ qFatal("Logic error 2");
+ }
+ }
+ xi->data = (char *)newbits;
}
if ( d == 8 && !trucol ) { // 8 bit pixmap
@@ -1363,6 +1653,7 @@ bool TQPixmap::convertFromImage( const TQImage &img, int conversion_flags )
}
newbits = (uchar *)malloc( nbytes ); // copy image into newbits
+ newbits_size = nbytes;
TQ_CHECK_PTR( newbits );
if ( !newbits ) // no memory
return FALSE;
@@ -1479,12 +1770,19 @@ bool TQPixmap::convertFromImage( const TQImage &img, int conversion_flags )
}
}
- if ( !xi ) { // X image not created
+ if ( !xi ) {
+#ifdef TQT_MITSHM_CONVERSIONS
+ xi = qt_XShmCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0, &shminfo );
+ if( xi != NULL )
+ mitshm_ximage = true;
+ else
+#endif // X image not created
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;
TQ_CHECK_PTR( newerbits );
if ( !newerbits ) // no memory
return FALSE;
@@ -1502,6 +1800,14 @@ bool TQPixmap::convertFromImage( const TQImage &img, int conversion_flags )
"(bpp=%d)", xi->bits_per_pixel );
#endif
}
+#ifdef TQT_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;
}
@@ -1535,19 +1841,24 @@ bool TQPixmap::convertFromImage( const TQImage &img, int conversion_flags )
}
+#ifdef TQT_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 TQT_MITSHM_CONVERSIONS
+ bool mitshm_aximage = false;
+ XShmSegmentInfo ashminfo;
+#endif
if ( image.hasAlphaBuffer() ) {
TQBitmap m;
m = image.createAlphaMask( conversion_flags );
@@ -1583,38 +1894,90 @@ bool TQPixmap::convertFromImage( const TQImage &img, int conversion_flags )
data->alphapm->rendhd =
(HANDLE) XftDrawCreateAlpha( x11Display(), data->alphapm->hd, 8 );
- XImage *axi = XCreateImage(x11Display(), (Visual *) x11Visual(),
+#ifdef TQT_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) {
+ if( axi->data==NULL ) {
// the data is deleted by qSafeXDestroyImage
axi->data = (char *) malloc(h * axi->bytes_per_line);
TQ_CHECK_PTR( axi->data );
+ }
char *aptr = axi->data;
if (image.depth() == 32) {
const int *iptr = (const int *) image.bits();
- int max = w * h;
- while (max--)
- *aptr++ = *iptr++ >> 24; // squirt
+ if( axi->bytes_per_line == (int)w ) {
+ int max = w * h;
+ while (max--)
+ *aptr++ = *iptr++ >> 24; // squirt
+ } else {
+ for (uint i = 0; i < h; ++i ) {
+ for (uint j = 0; j < w; ++j )
+ *aptr++ = *iptr++ >> 24; // squirt
+ aptr += ( axi->bytes_per_line - w );
+ }
+ }
} else if (image.depth() == 8) {
const TQRgb * const rgb = image.colorTable();
for (uint y = 0; y < h; ++y) {
const uchar *iptr = image.scanLine(y);
for (uint x = 0; x < w; ++x)
*aptr++ = tqAlpha(rgb[*iptr++]);
+ aptr += ( axi->bytes_per_line - w );
}
}
GC gc = XCreateGC(x11Display(), data->alphapm->hd, 0, 0);
+ #ifdef TQT_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);
}
}
#endif // TQT_NO_XFTFREETYPE
}
+#ifdef TQT_MITSHM_CONVERSIONS
+ if( mitshm_ximage || mitshm_aximage )
+ XSync( x11Display(), False ); // wait until processed
+#endif
+
+ if ( data->optim != BestOptim ) { // throw away image
+#ifdef TQT_MITSHM_CONVERSIONS
+ if( mitshm_ximage )
+ qt_XShmDestroyImage( xi, &shminfo );
+ else
+#endif
+ qSafeXDestroyImage( xi );
+ data->ximage = 0;
+ } else { // keep ximage that we created
+#ifdef TQT_MITSHM_CONVERSIONS
+ if( mitshm_ximage ) { // copy the XImage?
+ qt_XShmDestroyImage( xi, &shminfo );
+ xi = 0;
+ }
+#endif
+ data->ximage = xi;
+ }
+ if( axi ) {
+#ifdef TQT_MITSHM_CONVERSIONS
+ if( mitshm_aximage )
+ qt_XShmDestroyImage( axi, &ashminfo );
+ else
+#endif
+ qSafeXDestroyImage(axi);
+ }
return TRUE;
}
@@ -1777,7 +2140,7 @@ TQPixmap TQPixmap::xForm( const TQWMatrix &matrix ) const
return pm;
}
-#if defined(TQT_MITSHM)
+#if defined(TQT_MITSHM_XFORM)
static bool try_once = TRUE;
if (try_once) {
try_once = FALSE;
@@ -1810,7 +2173,7 @@ TQPixmap TQPixmap::xForm( const TQWMatrix &matrix ) const
dbpl = ((w*bpp+31)/32)*4;
dbytes = dbpl*h;
-#if defined(TQT_MITSHM)
+#if defined(TQT_MITSHM_XFORM)
if ( use_mitshm ) {
dptr = (uchar *)xshmimg->data;
uchar fillbyte = bpp == 8 ? white.pixel() : 0xff;
@@ -1826,7 +2189,7 @@ TQPixmap TQPixmap::xForm( const TQWMatrix &matrix ) const
memset( dptr, TQt::white.pixel( x11Screen() ), dbytes );
else
memset( dptr, 0xff, dbytes );
-#if defined(TQT_MITSHM)
+#if defined(TQT_MITSHM_XFORM)
}
#endif
@@ -1857,7 +2220,7 @@ TQPixmap TQPixmap::xForm( const TQWMatrix &matrix ) const
} else {
xbpl = (w*bpp)/8;
p_inc = dbpl - xbpl;
-#if defined(TQT_MITSHM)
+#if defined(TQT_MITSHM_XFORM)
if ( use_mitshm )
p_inc = xshmimg->bytes_per_line - xbpl;
#endif
@@ -1894,7 +2257,7 @@ TQPixmap TQPixmap::xForm( const TQWMatrix &matrix ) const
TQPixmap pm( w, h );
pm.data->uninit = FALSE;
pm.x11SetScreen( x11Screen() );
-#if defined(TQT_MITSHM)
+#if defined(TQT_MITSHM_XFORM)
if ( use_mitshm ) {
XCopyArea( dpy, xshmpm, pm.handle(), gc, 0, 0, w, h, 0, 0 );
} else {
@@ -1903,7 +2266,7 @@ TQPixmap TQPixmap::xForm( const TQWMatrix &matrix ) const
ZPixmap, 0, (char *)dptr, w, h, 32, 0 );
XPutImage( dpy, pm.handle(), gc, xi, 0, 0, 0, 0, w, h);
qSafeXDestroyImage( xi );
-#if defined(TQT_MITSHM)
+#if defined(TQT_MITSHM_XFORM)
}
#endif