Selaa lähdekoodia

Optimised drawing routines for X11, roughly based on how the old Unix viewer

did things.


git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4493 3789f03b-4d11-0410-bbf8-ca57d06f2519
tags/v1.1.90
Pierre Ossman 13 vuotta sitten
vanhempi
commit
1350069127
4 muutettua tiedostoa jossa 240 lisäystä ja 1 poistoa
  1. 4
    0
      vncviewer/CMakeLists.txt
  2. 1
    1
      vncviewer/Viewport.h
  3. 188
    0
      vncviewer/X11PixelBuffer.cxx
  4. 47
    0
      vncviewer/X11PixelBuffer.h

+ 4
- 0
vncviewer/CMakeLists.txt Näytä tiedosto

@@ -21,6 +21,10 @@ if(APPLE)
set(VNCVIEWER_SOURCES ${VNCVIEWER_SOURCES} cocoa.mm)
endif()

if((NOT APPLE) AND (NOT WIN32))
set(VNCVIEWER_SOURCES ${VNCVIEWER_SOURCES} X11PixelBuffer.cxx)
endif()

add_executable(vncviewer ${VNCVIEWER_SOURCES})

target_link_libraries(vncviewer rfb network rdr os Xregion ${FLTK_LIBRARIES} ${GETTEXT_LIBRARIES})

+ 1
- 1
vncviewer/Viewport.h Näytä tiedosto

@@ -38,7 +38,7 @@
#elif defined(__APPLE__)
#include "PlatformPixelBuffer.h"
#else
#include "PlatformPixelBuffer.h"
#include "X11PixelBuffer.h"
#endif

class CConn;

+ 188
- 0
vncviewer/X11PixelBuffer.cxx Näytä tiedosto

@@ -0,0 +1,188 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
*
* This 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.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/

#include <assert.h>
#include <stdlib.h>

#include <FL/x.H>

#include <rfb/LogWriter.h>
#include <rfb/Exception.h>

#include "X11PixelBuffer.h"

using namespace rfb;

static rfb::LogWriter vlog("PlatformPixelBuffer");

static PixelFormat display_pf()
{
int i;

int bpp;
int trueColour, bigEndian;
int redShift, greenShift, blueShift;
int redMax, greenMax, blueMax;

int nformats;
XPixmapFormatValues* format;

// Might not be open at this point
fl_open_display();

format = XListPixmapFormats(fl_display, &nformats);

for (i = 0; i < nformats; i++)
if (format[i].depth == fl_visual->depth) break;

if (i == nformats)
throw rfb::Exception("Error: display lacks pixmap format for default depth");

switch (format[i].bits_per_pixel) {
case 8:
case 16:
case 32:
bpp = format[i].bits_per_pixel;
break;
default:
throw rfb::Exception("Error: couldn't find suitable pixmap format");
}

XFree(format);

bigEndian = (ImageByteOrder(fl_display) == MSBFirst);
trueColour = (fl_visual->c_class == TrueColor);

if (!trueColour)
throw rfb::Exception("Error: only true colour displays supported");

vlog.info("Using default colormap and visual, %sdepth %d.",
(fl_visual->c_class == TrueColor) ? "TrueColor, " :
((fl_visual->c_class == PseudoColor) ? "PseudoColor, " : ""),
fl_visual->depth);

redShift = ffs(fl_visual->red_mask) - 1;
greenShift = ffs(fl_visual->green_mask) - 1;
blueShift = ffs(fl_visual->blue_mask) - 1;
redMax = fl_visual->red_mask >> redShift;
greenMax = fl_visual->green_mask >> greenShift;
blueMax = fl_visual->blue_mask >> blueShift;

return PixelFormat(bpp, fl_visual->depth, bigEndian, trueColour,
redMax, greenMax, blueMax,
redShift, greenShift, blueShift);
}

PlatformPixelBuffer::PlatformPixelBuffer(int width, int height) :
FullFramePixelBuffer(display_pf(), width, height, NULL, NULL),
shminfo(NULL), xim(NULL)
{
// Might not be open at this point
fl_open_display();

if (!setupShm()) {
xim = XCreateImage(fl_display, fl_visual->visual, fl_visual->depth,
ZPixmap, 0, 0, width, height, BitmapPad(fl_display), 0);
assert(xim);

xim->data = (char*)malloc(xim->bytes_per_line * xim->height);
assert(xim->data);
}

data = (rdr::U8*)xim->data;
}


PlatformPixelBuffer::~PlatformPixelBuffer()
{
if (shminfo) {
vlog.debug("Freeing shared memory XImage");
shmdt(shminfo->shmaddr);
shmctl(shminfo->shmid, IPC_RMID, 0);
delete shminfo;
shminfo = NULL;
}

// XDestroyImage() will free(xim->data) if appropriate
if (xim)
XDestroyImage(xim);
xim = NULL;
}


void PlatformPixelBuffer::draw(int src_x, int src_y, int x, int y, int w, int h)
{
if (shminfo)
XShmPutImage(fl_display, fl_window, fl_gc, xim, src_x, src_y, x, y, w, h, False);
else
XPutImage(fl_display, fl_window, fl_gc, xim, src_x, src_y, x, y, w, h);
}


int PlatformPixelBuffer::getStride() const
{
return xim->bytes_per_line / (getPF().bpp/8);
}


int PlatformPixelBuffer::setupShm()
{
int major, minor;
Bool pixmaps;

if (!XShmQueryVersion(fl_display, &major, &minor, &pixmaps))
return 0;

shminfo = new XShmSegmentInfo;

xim = XShmCreateImage(fl_display, fl_visual->visual, fl_visual->depth,
ZPixmap, 0, shminfo, width(), height());
if (!xim)
goto free_shminfo;

shminfo->shmid = shmget(IPC_PRIVATE,
xim->bytes_per_line * xim->height,
IPC_CREAT|0777);
if (shminfo->shmid == -1)
goto free_xim;

shminfo->shmaddr = xim->data = (char*)shmat(shminfo->shmid, 0, 0);
if (shminfo->shmaddr == (char *)-1)
goto free_shm;

shminfo->readOnly = True;
XShmAttach(fl_display, shminfo);

vlog.debug("Using shared memory XImage");

return 1;

free_shm:
shmctl(shminfo->shmid, IPC_RMID, 0);

free_xim:
XDestroyImage(xim);
xim = NULL;

free_shminfo:
delete shminfo;
shminfo = NULL;

return 0;
}

+ 47
- 0
vncviewer/X11PixelBuffer.h Näytä tiedosto

@@ -0,0 +1,47 @@
/* Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
*
* This 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.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/

#ifndef __X11PIXELBUFFER_H__
#define __X11PIXELBUFFER_H__

#include <X11/Xlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>

#include <rfb/PixelBuffer.h>

class PlatformPixelBuffer: public rfb::FullFramePixelBuffer {
public:
PlatformPixelBuffer(int width, int height);
~PlatformPixelBuffer();

void draw(int src_x, int src_y, int x, int y, int w, int h);

int getStride() const;

protected:
int setupShm();

protected:
XShmSegmentInfo *shminfo;
XImage *xim;
};


#endif

Loading…
Peruuta
Tallenna