/*************************************************************************** sq_pixmap.h - description ------------------- begin : Apr 10 2005 copyright : (C) 2005 by Baryshev Dmitry email : ksquirrel@tut.by ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************//* * * Originally written by * Dmitry Smirnov, * Saint-Petersburg, Russia * */#ifndef SQ_PIXMAP_H#define SQ_PIXMAP_H#include <X11/Xlib.h>#include <X11/extensions/XShm.h>#include <sys/timeb.h>class QPaintDevice;class SQ_Pixmap{ public: SQ_Pixmap(int, int); SQ_Pixmap(); ~SQ_Pixmap(); private: XImage* m_pXImage; XShmSegmentInfo* m_pXShmSegmentInfo; public: void draw(QPaintDevice *, int, int); void fillPixmap(unsigned char *data, const int w, const int h); int width() const; int height() const; int region_width() const; int region_height() const; public: int* data; int m_width; int m_height; int m_w, m_h;};inline int SQ_Pixmap::width() const{ return m_width;}inline int SQ_Pixmap::height() const{ return m_height;}inline int SQ_Pixmap::region_width() const{ return m_w;}inline int SQ_Pixmap::region_height() const{ return m_h;}#endif
/*************************************************************************** sq_pixmap.cpp - description ------------------- begin : Apr 10 2005 copyright : (C) 2005 by Baryshev Dmitry email : ksquirrel@tut.by ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/#include <qpaintdevice.h>#include <qapplication.h>#include <X11/Xutil.h>#include <sys/ipc.h>#include <sys/shm.h>#include "sq_pixmap.h"SQ_Pixmap::SQ_Pixmap(){ QDesktopWidget *d = QApplication::desktop(); SQ_Pixmap::SQ_Pixmap(d->width()+2, d->height()+2);}SQ_Pixmap::SQ_Pixmap(int iWidth, int iHeight) : m_w(0), m_h(0){ m_width = iWidth; m_height = iHeight; // create the shared segment m_pXShmSegmentInfo = new XShmSegmentInfo; // create the shared memory image m_pXImage = XShmCreateImage(QPaintDevice::x11AppDisplay(), (Visual *)QPaintDevice::x11AppVisual(), QPaintDevice::x11AppDepth(), ZPixmap, 0, m_pXShmSegmentInfo, m_width, m_height); // create the shared memory segment m_pXShmSegmentInfo->shmid = shmget(IPC_PRIVATE, m_pXImage->bytes_per_line * m_pXImage->height, IPC_CREAT | 0777); // attach the shared memory segment to process data = (int *)shmat(m_pXShmSegmentInfo->shmid, 0, 0); m_pXShmSegmentInfo->shmaddr = m_pXImage->data = (char *)data; // make the shared memory segment writable m_pXShmSegmentInfo->readOnly = false; // attach the shared memory segment to server XShmAttach(QPaintDevice::x11AppDisplay(), m_pXShmSegmentInfo); memset(data, 0x80, m_width * m_height * 4);}SQ_Pixmap::~SQ_Pixmap(){ // detach the shared memory segment from server XShmDetach(QPaintDevice::x11AppDisplay(), m_pXShmSegmentInfo); // destroy the shared memory image XDestroyImage(m_pXImage); // destroy the shared memory segment shmdt(m_pXShmSegmentInfo->shmaddr); shmctl(m_pXShmSegmentInfo->shmid, IPC_RMID, 0);}void SQ_Pixmap::draw(QPaintDevice* pPaintDevice, int x, int y){ // synchronize X server QApplication::syncX(); // create device context GC gc = XCreateGC(pPaintDevice->x11Display(), pPaintDevice->handle(), 0, 0); // draw the shared memory image XShmPutImage(pPaintDevice->x11Display(), pPaintDevice->handle(), gc, m_pXImage, 0, 0, x, y, m_w, m_h, true); // free device context XFreeGC(pPaintDevice->x11Display(), gc);}void SQ_Pixmap::fillPixmap(unsigned char *buf, const int w, const int h){ m_w = w; m_h = h; const int row_stride = w << 2; if(w < m_width) { for(int i = 0;i < h;i++) memcpy(data+m_width*i, buf + i*row_stride, row_stride); } else memcpy(data, buf, (m_width * m_height) << 2);}
unsigned char *data = // ... каким-то образом получаешь данныеint w = 300, h = 200;SQ_Pixmap *p = new SQ_Pixmap(w, h);p->fillPixmap(data, w, h);// отрисовка по координатам x,yp->draw(this, 10, 10);
QPixmap pm(*m_pQImg);bitBlt(viewport(), 0, 0, &pm,contentsX () ,contentsY () ,m_pQImg->width(),m_pQImg->height(),CopyROP, TRUE );