36#include <X11/extensions/XShm.h>
44struct KPixmapIOPrivate
54 XShmSegmentInfo *shminfo;
65typedef unsigned char uchar;
66typedef unsigned int uint;
69static int lowest_bit(uint val)
73 for (i=0; (!(val & test)) && i<32; i++, test<<=1);
74 return (i == 32) ? -1 : i;
83 d =
new KPixmapIOPrivate;
92 if (XQueryExtension(tqt_xdisplay(),
"MIT-SHM", &ignore, &ignore, &ignore))
94 if (XShmQueryExtension(tqt_xdisplay()))
99 kdDebug(290) << k_lineinfo <<
"MIT-SHM not available!\n";
107 d->shminfo =
new XShmSegmentInfo;
108 d->ximage = XShmCreateImage(tqt_xdisplay(), (Visual *) TQPaintDevice::x11AppVisual(),
109 TQPaintDevice::x11AppDepth(), ZPixmap, 0L, d->shminfo, 10, 10);
110 d->bpp = d->ximage->bits_per_pixel;
113 if (d->ximage->byte_order == LSBFirst)
115 int red_shift = lowest_bit(d->ximage->red_mask);
116 int green_shift = lowest_bit(d->ximage->green_mask);
117 int blue_shift = lowest_bit(d->ximage->blue_mask);
118 XDestroyImage(d->ximage); d->ximage = 0L;
125 if ((bpp == 32) && (red_shift == 16) && (green_shift == 8) &&
127 d->byteorder = bo32_ARGB;
128 else if ((bpp == 32) && (red_shift == 0) && (green_shift == 8) &&
130 d->byteorder = bo32_BGRA;
131 else if ((bpp == 33) && (red_shift == 16) && (green_shift == 8) &&
133 d->byteorder = bo32_BGRA;
134 else if ((bpp == 24) && (red_shift == 16) && (green_shift == 8) &&
136 d->byteorder = bo24_RGB;
137 else if ((bpp == 24) && (red_shift == 0) && (green_shift == 8) &&
139 d->byteorder = bo24_BGR;
140 else if ((bpp == 25) && (red_shift == 16) && (green_shift == 8) &&
142 d->byteorder = bo24_BGR;
143 else if ((bpp == 16) && (red_shift == 11) && (green_shift == 5) &&
145 d->byteorder = bo16_RGB_565;
146 else if ((bpp == 16) && (red_shift == 10) && (green_shift == 5) &&
148 d->byteorder = bo16_RGB_555;
149 else if ((bpp == 17) && (red_shift == 11) && (green_shift == 5) &&
151 d->byteorder = bo16_BGR_565;
152 else if ((bpp == 17) && (red_shift == 10) && (green_shift == 5) &&
154 d->byteorder = bo16_BGR_555;
155 else if ((bpp == 8) || (bpp == 9))
162 <<
", green = " << green_shift
163 <<
", blue = " << blue_shift <<
endl;
164 kdWarning(290) <<
"Please report to <jansen@kde.org>\n";
173KPixmapIO::~KPixmapIO()
186 int size = img.width() * img.height();
187 if (m_bShm && (img.depth() > 1) && (d->bpp > 8) && (size > d->threshold))
189 TQPixmap dst(img.width(), img.height());
195 dst.convertFromImage(img);
205 int size = pm.width() * pm.height();
206 if (m_bShm && (d->bpp >= 8) && (size > d->threshold))
207 image =
getImage(&pm, 0, 0, pm.width(), pm.height());
209 image = pm.convertToImage();
217 putImage(dst, offset.x(), offset.y(), src);
223 int size = src->width() * src->height();
224 bool fallback =
true;
225 if (m_bShm && (src->depth() > 1) && (d->bpp > 8) && (size > d->threshold))
228 if( initXImage(src->width(), src->height()))
230 convertToXImage(*src);
231 XShmPutImage(tqt_xdisplay(), dst->handle(), tqt_xget_temp_gc(tqt_xscreen(),
false), d->ximage,
232 dx, dy, 0, 0, src->width(), src->height(),
false);
234 XSync(tqt_xdisplay(),
false);
243 pix.convertFromImage(*src);
244 bitBlt(dst, dx, dy, &pix, 0, 0, pix.width(), pix.height());
251 return getImage(src, rect.x(), rect.y(), rect.width(), rect.height());
258 int size = src->width() * src->height();
259 bool fallback =
true;
260 if ((m_bShm) && (d->bpp >= 8) && (size > d->threshold))
263 if( initXImage(sw, sh))
265 XShmGetImage(tqt_xdisplay(), src->handle(), d->ximage, sx, sy, AllPlanes);
266 image = convertFromXImage();
274 TQPixmap pix(sw, sh);
275 bitBlt(&pix, 0, 0, src, sx, sy, sw, sh);
276 image = pix.convertToImage();
287 createShmSegment(size);
296 d->shmpolicy = ShmDontKeep;
300 d->shmpolicy = ShmKeepAndGrow;
309bool KPixmapIO::initXImage(
int w,
int h)
311 if (d->ximage && (w == d->ximage->width) && (h == d->ximage->height))
314 if( !createXImage(w, h))
316 int size = d->ximage->bytes_per_line * d->ximage->height;
317 if (size > d->shmsize)
319 if( !createShmSegment(size))
325 d->ximage->data = d->shminfo->shmaddr;
330void KPixmapIO::doneXImage()
332 if (d->shmpolicy == ShmDontKeep)
340void KPixmapIO::destroyXImage()
344 XDestroyImage(d->ximage);
350bool KPixmapIO::createXImage(
int w,
int h)
353 d->ximage = XShmCreateImage(tqt_xdisplay(), (Visual *) TQPaintDevice::x11AppVisual(),
354 TQPaintDevice::x11AppDepth(), ZPixmap, 0L, d->shminfo, w, h);
355 return d->ximage != None;
359void KPixmapIO::destroyShmSegment()
363 XShmDetach(tqt_xdisplay(), d->shminfo);
364 shmdt(d->shminfo->shmaddr);
365 shmctl(d->shminfo->shmid, IPC_RMID, 0);
370static bool use_xshm =
true;
371static unsigned long kpixmapio_serial;
372static int (*old_errhandler)(Display *dpy, XErrorEvent *ev) = 0;
374static int kpixmapio_errorhandler(Display *dpy, XErrorEvent *ev)
376 if(ev->serial == kpixmapio_serial) {
384 return old_errhandler(dpy, ev);
388bool KPixmapIO::createShmSegment(
int size)
391 d->shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0600);
392 if ( d->shminfo->shmid < 0)
394 kdWarning(290) <<
"Could not get shared memory segment.\n";
399 d->shminfo->shmaddr = (
char *) shmat(d->shminfo->shmid, 0, 0);
400 if (d->shminfo->shmaddr == (
char *)-1)
402 kdWarning(290) <<
"Could not attach shared memory segment.\n";
404 shmctl(d->shminfo->shmid, IPC_RMID, 0);
408 d->shminfo->readOnly =
false;
412 XSync(tqt_xdisplay(), False);
413 old_errhandler = XSetErrorHandler(kpixmapio_errorhandler);
414 kpixmapio_serial = NextRequest(tqt_xdisplay());
417 if ( !XShmAttach(tqt_xdisplay(), d->shminfo))
419 kdWarning() <<
"X-Server could not attach shared memory segment.\n";
421 shmdt(d->shminfo->shmaddr);
422 shmctl(d->shminfo->shmid, IPC_RMID, 0);
426 XSync(tqt_xdisplay(),
false);
431 XSetErrorHandler(old_errhandler);
432 d->first_try =
false;
446TQImage KPixmapIO::convertFromXImage()
449 int width = d->ximage->width, height = d->ximage->height;
450 int bpl = d->ximage->bytes_per_line;
451 char *data = d->ximage->data;
456 image.create(width, height, 8);
461 XColor *cmap =
new XColor[ncells];
462 for (i=0; i<ncells; i++)
464 XQueryColors(tqt_xdisplay(), TQPaintDevice::x11AppColormap(),
466 image.setNumColors(ncells);
467 for (i=0; i<ncells; i++)
468 image.setColor(i, tqRgb(cmap[i].red, cmap[i].green, cmap[i].blue >> 8));
470 image.create(width, height, 32);
472 switch (d->byteorder)
477 for (y=0; y<height; y++)
478 memcpy(image.scanLine(y), data + y*bpl, width);
485 TQ_INT32 pixel, *src;
487 for (y=0; y<height; y++)
489 src = (TQ_INT32 *) (data + y*bpl);
490 dst = (TQRgb *) image.scanLine(y);
491 for (x=0; x<width/2; x++)
494 val = ((pixel & 0xf800) << 8) | ((pixel & 0x7e0) << 5) |
495 ((pixel & 0x1f) << 3);
498 val = ((pixel & 0xf800) << 8) | ((pixel & 0x7e0) << 5) |
499 ((pixel & 0x1f) << 3);
505 val = ((pixel & 0xf800) << 8) | ((pixel & 0x7e0) << 5) |
506 ((pixel & 0x1f) << 3);
516 TQ_INT32 pixel, *src;
518 for (y=0; y<height; y++)
520 src = (TQ_INT32 *) (data + y*bpl);
521 dst = (TQRgb *) image.scanLine(y);
522 for (x=0; x<width/2; x++)
525 val = ((pixel & 0x7c00) << 9) | ((pixel & 0x3e0) << 6) |
526 ((pixel & 0x1f) << 3);
529 val = ((pixel & 0x7c00) << 9) | ((pixel & 0x3e0) << 6) |
530 ((pixel & 0x1f) << 3);
536 val = ((pixel & 0x7c00) << 9) | ((pixel & 0x3e0) << 6) |
537 ((pixel & 0x1f) << 3);
550 for (y=0; y<height; y++)
553 dst = (TQRgb *) image.scanLine(y);
556 d1 = *((TQ_INT32 *)src);
557 d2 = *((TQ_INT32 *)src + 1);
558 d3 = *((TQ_INT32 *)src + 2);
561 *dst++ = (d1 >> 24) | (d2 << 8);
562 *dst++ = (d3 << 16) | (d2 >> 16);
565 for (x=w1*4; x<width; x++)
582 for (y=0; y<height; y++)
585 dst = (TQRgb *) image.scanLine(y);
588 d1 = *((TQ_INT32 *)src);
589 d2 = *((TQ_INT32 *)src + 1);
590 d3 = *((TQ_INT32 *)src + 2);
593 *dst++ = (d1 >> 24) | (d2 << 8);
594 *dst++ = (d3 << 16) | (d2 >> 16);
597 for (x=w1*4; x<width; x++)
611 for (y=0; y<height; y++)
612 memcpy(image.scanLine(y), data + y*bpl, width*4);
622void KPixmapIO::convertToXImage(
const TQImage &img)
625 int width = d->ximage->width, height = d->ximage->height;
626 int bpl = d->ximage->bytes_per_line;
627 char *data = d->ximage->data;
629 switch (d->byteorder)
635 if (img.depth() == 32)
639 for (y=0; y<height; y++)
641 src = (TQRgb *) img.scanLine(y);
642 dst = (TQ_INT32 *) (data + y*bpl);
643 for (x=0; x<width/2; x++)
646 val = ((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) |
647 ((pixel & 0xff) >> 3);
649 val |= (((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) |
650 ((pixel & 0xff) >> 3)) << 16;
656 *((TQ_INT16 *)dst) = ((pixel & 0xf80000) >> 9) |
657 ((pixel & 0xf800) >> 6) | ((pixel & 0xff) >> 3);
664 TQRgb pixel, *clut = img.colorTable();
665 for (y=0; y<height; y++)
667 src =
const_cast<TQImage&
>(img).scanLine(y);
668 dst = (TQ_INT32 *) (data + y*bpl);
669 for (x=0; x<width/2; x++)
671 pixel = clut[*src++];
672 val = ((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) |
673 ((pixel & 0xff) >> 3);
674 pixel = clut[*src++];
675 val |= (((pixel & 0xf80000) >> 9) | ((pixel & 0xf800) >> 6) |
676 ((pixel & 0xff) >> 3)) << 16;
681 pixel = clut[*src++];
682 *((TQ_INT16 *)dst) = ((pixel & 0xf80000) >> 9) |
683 ((pixel & 0xf800) >> 6) | ((pixel & 0xff) >> 3);
692 if (img.depth() == 32)
696 for (y=0; y<height; y++)
698 src = (TQRgb *) img.scanLine(y);
699 dst = (TQ_INT32 *) (data + y*bpl);
700 for (x=0; x<width/2; x++)
703 val = ((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) |
704 ((pixel & 0xff) >> 3);
706 val |= (((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) |
707 ((pixel & 0xff) >> 3)) << 16;
713 *((TQ_INT16 *)dst) = ((pixel & 0xf80000) >> 8) |
714 ((pixel & 0xfc00) >> 5) | ((pixel & 0xff) >> 3);
721 TQRgb pixel, *clut = img.colorTable();
722 for (y=0; y<height; y++)
724 src =
const_cast<TQImage&
>(img).scanLine(y);
725 dst = (TQ_INT32 *) (data + y*bpl);
726 for (x=0; x<width/2; x++)
728 pixel = clut[*src++];
729 val = ((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) |
730 ((pixel & 0xff) >> 3);
731 pixel = clut[*src++];
732 val |= (((pixel & 0xf80000) >> 8) | ((pixel & 0xfc00) >> 5) |
733 ((pixel & 0xff) >> 3)) << 16;
738 pixel = clut[*src++];
739 *((TQ_INT16 *)dst) = ((pixel & 0xf80000) >> 8) |
740 ((pixel & 0xfc00) >> 5) | ((pixel & 0xff) >> 3);
748 if (img.depth() == 32)
752 TQRgb *src, d1, d2, d3, d4;
753 for (y=0; y<height; y++)
755 src = (TQRgb *) img.scanLine(y);
759 d1 = (*src++ & 0xffffff);
760 d2 = (*src++ & 0xffffff);
761 d3 = (*src++ & 0xffffff);
762 d4 = (*src++ & 0xffffff);
763 *((TQ_INT32 *)dst) = d1 | (d2 << 24);
764 *((TQ_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16);
765 *((TQ_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16);
768 for (x=w1*4; x<width; x++)
772 *dst++ = tqGreen(d1);
780 TQRgb *clut = img.colorTable(), d1, d2, d3, d4;
781 for (y=0; y<height; y++)
783 src =
const_cast<TQImage&
>(img).scanLine(y);
784 dst = (uchar *) data + y*bpl;
787 d1 = (clut[*src++] & 0xffffff);
788 d2 = (clut[*src++] & 0xffffff);
789 d3 = (clut[*src++] & 0xffffff);
790 d4 = (clut[*src++] & 0xffffff);
791 *((TQ_INT32 *)dst) = d1 | (d2 << 24);
792 *((TQ_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16);
793 *((TQ_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16);
796 for (x=w1*4; x<width; x++)
800 *dst++ = tqGreen(d1);
809 if (img.depth() == 32)
812 TQRgb *src, d1, d2, d3, d4;
814 for (y=0; y<height; y++)
816 src = (TQRgb *) img.scanLine(y);
820 d1 = (*src++ & 0xffffff);
821 d2 = (*src++ & 0xffffff);
822 d3 = (*src++ & 0xffffff);
823 d4 = (*src++ & 0xffffff);
824 *((TQ_INT32 *)dst) = d1 | (d2 << 24);
825 *((TQ_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16);
826 *((TQ_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16);
829 for (x=w1*4; x<width; x++)
833 *dst++ = tqGreen(d1);
841 TQRgb *clut = img.colorTable(), d1, d2, d3, d4;
842 for (y=0; y<height; y++)
844 src =
const_cast<TQImage&
>(img).scanLine(y);
845 dst = (uchar *) data + y*bpl;
848 d1 = (clut[*src++] & 0xffffff);
849 d2 = (clut[*src++] & 0xffffff);
850 d3 = (clut[*src++] & 0xffffff);
851 d4 = (clut[*src++] & 0xffffff);
852 *((TQ_INT32 *)dst) = d1 | (d2 << 24);
853 *((TQ_INT32 *)dst+1) = (d2 >> 8) | (d3 << 16);
854 *((TQ_INT32 *)dst+2) = (d4 << 8) | (d3 >> 16);
857 for (x=w1*4; x<width; x++)
861 *dst++ = tqGreen(d1);
871 if (img.depth() == 32)
873 for (y=0; y<height; y++)
874 memcpy(data + y*bpl, img.scanLine(y), width*4);
878 TQRgb *dst, *clut = img.colorTable();
879 for (y=0; y<height; y++)
881 src =
const_cast<TQImage&
>(img).scanLine(y);
882 dst = (TQRgb *) (data + y*bpl);
883 for (x=0; x<width; x++)
884 *dst++ = clut[*src++];
896bool KPixmapIO::initXImage(
int,
int) {
return false; }
897void KPixmapIO::doneXImage() {}
898bool KPixmapIO::createXImage(
int,
int) {
return false; }
899void KPixmapIO::destroyXImage() {}
900bool KPixmapIO::createShmSegment(
int) {
return false; }
901void KPixmapIO::destroyShmSegment() {}
902TQImage KPixmapIO::convertFromXImage() {
return TQImage(); }
903void KPixmapIO::convertToXImage(
const TQImage &) {}
void setShmPolicy(int policy)
Set the shared memory allocation policy.
void preAllocShm(int size)
Pre-allocate shared memory.
TQPixmap convertToPixmap(const TQImage &image)
Convert an image to a pixmap.
void putImage(TQPixmap *dst, int dx, int dy, const TQImage *src)
Bitblt an image onto a pixmap.
TQImage getImage(const TQPixmap *src, int sx, int sy, int sw, int sh)
Transfer (a part of) a pixmap to an image.
TQImage convertToImage(const TQPixmap &pixmap)
Convert a pixmap to an image.
bool readBoolEntry(const TQString &pKey, bool bDefault=false) const
static TDEConfig * config()
kdbgstream kdWarning(int area=0)
kndbgstream & endl(kndbgstream &s)
kdbgstream kdDebug(int area=0)