diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-23 17:13:36 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-23 17:13:36 -0500 |
commit | d3f7a9d6f1b8f6e24fb49aaa8caeaa7623ae48b5 (patch) | |
tree | baeeba639393f46abab749f4700a250091c3cc16 /tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp | |
parent | d7be1694839bacae31e500ea9e36b3c13257ce28 (diff) | |
download | experimental-d3f7a9d6f1b8f6e24fb49aaa8caeaa7623ae48b5.tar.gz experimental-d3f7a9d6f1b8f6e24fb49aaa8caeaa7623ae48b5.zip |
Apply all Qt3.3.8d patches
NOTE: This will *likely* break compilation of TQt4
Please wait a few days for fixes to be committed as needed!
Diffstat (limited to 'tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp')
-rw-r--r-- | tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp | 593 |
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 |