11 #include "x11framebuffer.moc"
13 #include <config-krfb.h>
16 #include <QApplication>
17 #include <QDesktopWidget>
19 #include <KApplication>
23 #include <X11/Xutil.h>
26 #include <X11/extensions/Xdamage.h>
32 #include <X11/extensions/XShm.h>
35 class X11FrameBuffer::P
43 XShmSegmentInfo shminfo;
46 XImage *framebufferImage;
59 kDebug() <<
"shm: " << d->useShm;
77 d->framebufferImage->bits_per_pixel,
83 d->shminfo.shmid = shmget(IPC_PRIVATE,
84 d->updateTile->bytes_per_line * d->updateTile->height,
87 d->shminfo.shmaddr = d->updateTile->data = (
char *)
88 shmat(d->shminfo.shmid, 0, 0);
89 d->shminfo.readOnly = False;
97 kDebug() <<
"Got image. bpp: " << d->framebufferImage->bits_per_pixel
98 <<
", depth: " << d->framebufferImage->depth
99 <<
", padded width: " << d->framebufferImage->bytes_per_line
100 <<
" (sent: " << d->framebufferImage->width * 4 <<
")"
103 fb = d->framebufferImage->data;
106 kapp->installX11EventFilter(d->ev);
113 XDestroyImage(d->framebufferImage);
115 kapp->removeX11EventFilter(d->ev);
119 XDestroyImage(d->updateTile);
120 shmdt(d->shminfo.shmaddr);
121 shmctl(d->shminfo.shmid, IPC_RMID, 0);
130 return d->framebufferImage->depth;
135 return d->framebufferImage->height;
140 return d->framebufferImage->width;
145 return d->framebufferImage->bytes_per_line;
150 format.
bitsPerPixel = d->framebufferImage->bits_per_pixel;
151 format.
depth = d->framebufferImage->depth;
153 format.
bigEndian = ((d->framebufferImage->bitmap_bit_order == MSBFirst) ?
true :
false);
165 if (d->framebufferImage->red_mask)
166 while (!(d->framebufferImage->red_mask & (1 << format.
redShift))) {
172 if (d->framebufferImage->green_mask)
173 while (!(d->framebufferImage->green_mask & (1 << format.
greenShift))) {
179 if (d->framebufferImage->blue_mask)
180 while (!(d->framebufferImage->blue_mask & (1 << format.
blueShift))) {
193 XDamageNotifyEvent *dev = (XDamageNotifyEvent *)event;
194 QRect r(dev->area.x, dev->area.y, dev->area.width, dev->area.height);
204 void X11FrameBuffer::cleanupRects()
208 bool inserted =
false;
211 foreach(
const QRect & r, cpy) {
234 tiles[i].adjust(-30, -30, 30, 30);
236 if (
tiles[i].top() < 0) {
240 if (
tiles[i].left() < 0) {
244 if (
tiles[i].bottom() > d->framebufferImage->height) {
245 tiles[i].setBottom(d->framebufferImage->height);
248 if (
tiles[i].right() > d->framebufferImage->width) {
249 tiles[i].setRight(d->framebufferImage->width);
256 void X11FrameBuffer::acquireEvents()
261 while (XCheckTypedEvent(
QX11Info::display(), d->xdamageBaseEvent + XDamageNotify, &ev)) {
276 kapp->processEvents();
291 while (x < r.
right()) {
293 if (y + d->updateTile->height > d->framebufferImage->height) {
294 y = d->framebufferImage->height - d->updateTile->height;
297 if (x + d->updateTile->width > d->framebufferImage->width) {
298 x = d->framebufferImage->width - d->updateTile->width;
303 int pxsize = d->framebufferImage->bits_per_pixel / 8;
304 char *dest =
fb + ((d->framebufferImage->bytes_per_line * y) + (x * pxsize));
305 char *src = d->updateTile->data;
307 for (
int i = 0; i < d->updateTile->height; i++) {
308 memcpy(dest, src, d->updateTile->bytes_per_line);
309 dest += d->framebufferImage->bytes_per_line;
310 src += d->updateTile->bytes_per_line;
313 y += d->updateTile->height;
316 x += d->updateTile->width;
378 if (event->type == xdamageBaseEvent + XDamageNotify) {
bool intersects(const QRect &rectangle) const
void append(const T &value)
virtual void getServerFormat(rfbPixelFormat &format)
virtual void startMonitor()
X11FrameBuffer(WId id, QObject *parent=0)
virtual QList< QRect > modifiedTiles()
virtual void stopMonitor()
void handleXDamage(XEvent *event)
QDesktopWidget * desktop()
virtual int paddedWidth()