Browse Source

Remove full support for colour maps

Gets rid of a loooot of code and complexity.

Colour map clients are still supported through an
automatically generated map, but we lose the ability to
develop a client or server that uses colour maps
internally.
tags/v1.3.90
Pierre Ossman 10 years ago
parent
commit
b6b4dc6487
48 changed files with 309 additions and 1247 deletions
  1. 0
    96
      common/rfb/ColourCube.h
  2. 0
    51
      common/rfb/ColourMap.h
  3. 7
    16
      common/rfb/PixelBuffer.cxx
  4. 2
    9
      common/rfb/PixelBuffer.h
  5. 90
    58
      common/rfb/PixelFormat.cxx
  6. 17
    13
      common/rfb/PixelFormat.h
  7. 59
    109
      common/rfb/PixelFormat.inl
  8. 11
    137
      common/rfb/PixelTransformer.cxx
  9. 2
    31
      common/rfb/PixelTransformer.h
  10. 14
    5
      common/rfb/SConnection.cxx
  11. 1
    5
      common/rfb/SConnection.h
  12. 6
    7
      common/rfb/SMsgWriter.cxx
  13. 4
    4
      common/rfb/SMsgWriter.h
  14. 3
    3
      common/rfb/TightEncoder.cxx
  15. 2
    23
      common/rfb/TransImageGetter.cxx
  16. 2
    25
      common/rfb/TransImageGetter.h
  17. 0
    41
      common/rfb/TrueColourMap.h
  18. 0
    29
      common/rfb/VNCSConnectionST.cxx
  19. 0
    3
      common/rfb/VNCSConnectionST.h
  20. 0
    6
      common/rfb/VNCServer.h
  21. 0
    9
      common/rfb/VNCServerST.cxx
  22. 0
    1
      common/rfb/VNCServerST.h
  23. 9
    9
      common/rfb/tightDecode.h
  24. 1
    1
      common/rfb/tightEncode.h
  25. 10
    129
      common/rfb/transInitTempl.h
  26. 0
    33
      common/rfb/transTempl.h
  27. 1
    1
      tests/pixelconv.cxx
  28. 1
    2
      unix/x0vncserver/XPixelBuffer.cxx
  29. 1
    2
      unix/x0vncserver/XPixelBuffer.h
  30. 2
    16
      unix/x0vncserver/x0vncserver.cxx
  31. 27
    109
      unix/xserver/hw/vnc/XserverDesktop.cc
  32. 1
    9
      unix/xserver/hw/vnc/XserverDesktop.h
  33. 4
    5
      unix/xserver/hw/vnc/vncExtInit.cc
  34. 0
    38
      unix/xserver/hw/vnc/vncHooks.cc
  35. 4
    3
      vncviewer/CConn.cxx
  36. 0
    6
      vncviewer/DesktopWindow.cxx
  37. 0
    2
      vncviewer/DesktopWindow.h
  38. 4
    36
      vncviewer/Viewport.cxx
  39. 0
    9
      vncviewer/Viewport.h
  40. 1
    1
      vncviewer/Win32PixelBuffer.cxx
  41. 1
    1
      vncviewer/X11PixelBuffer.cxx
  42. 18
    72
      win/rfb_win32/DIBSectionBuffer.cxx
  43. 1
    20
      win/rfb_win32/DIBSectionBuffer.h
  44. 2
    48
      win/rfb_win32/DeviceFrameBuffer.cxx
  45. 0
    1
      win/rfb_win32/DeviceFrameBuffer.h
  46. 0
    6
      win/rfb_win32/SDisplay.cxx
  47. 0
    6
      win/rfb_win32/WMNotifier.cxx
  48. 1
    1
      win/rfb_win32/WMNotifier.h

+ 0
- 96
common/rfb/ColourCube.h View File

@@ -1,96 +0,0 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
* 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.
*/
//
// ColourCube - structure to represent a colour cube. The colour cube consists
// of its dimensions (nRed x nGreen x nBlue) and a table mapping an (r,g,b)
// triple to a pixel value.
//
// A colour cube is used in two cases. The first is internally in a viewer
// when it cannot use a trueColour format, nor can it have exclusive access to
// a writable colour map. This is most notably the case for an X viewer
// wishing to use a PseudoColor X server's default colormap.
//
// The second use is on the server side when a client has asked for a colour
// map and the server is trueColour. Instead of setting an uneven trueColour
// format like bgr233, it can set the client's colour map up with a 6x6x6
// colour cube. For this use the colour cube table has a null mapping, which
// makes it easy to perform the reverse lookup operation from pixel value to
// r,g,b values.

#ifndef __RFB_COLOURCUBE_H__
#define __RFB_COLOURCUBE_H__

#include <rfb/Pixel.h>
#include <rfb/ColourMap.h>

namespace rfb {

class ColourCube : public ColourMap {
public:
ColourCube(int nr, int ng, int nb, Pixel* table_=0)
: nRed(nr), nGreen(ng), nBlue(nb), table(table_), deleteTable(false)
{
if (!table) {
table = new Pixel[size()];
deleteTable = true;
// set a null mapping by default
for (int i = 0; i < size(); i++)
table[i] = i;
}
}

ColourCube() : deleteTable(false) {}

virtual ~ColourCube() {
if (deleteTable) delete [] table;
}

void set(int r, int g, int b, Pixel p) {
table[(r * nGreen + g) * nBlue + b] = p;
}

Pixel lookup(int r, int g, int b) const {
return table[(r * nGreen + g) * nBlue + b];
}

int size() const { return nRed*nGreen*nBlue; }
int redMult() const { return nGreen*nBlue; }
int greenMult() const { return nBlue; }
int blueMult() const { return 1; }

// ColourMap lookup() method. Note that this only works when the table has
// the default null mapping.
virtual void lookup(int i, int* r, int* g, int* b) {
if (i >= size()) return;
*b = i % nBlue;
i /= nBlue;
*g = i % nGreen;
*r = i / nGreen;
*r = (*r * 65535 + (nRed-1) / 2) / (nRed-1);
*g = (*g * 65535 + (nGreen-1) / 2) / (nGreen-1);
*b = (*b * 65535 + (nBlue-1) / 2) / (nBlue-1);
}

int nRed;
int nGreen;
int nBlue;
Pixel* table;
bool deleteTable;
};
}
#endif

+ 0
- 51
common/rfb/ColourMap.h View File

@@ -1,51 +0,0 @@
/* 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.
*/
#ifndef __RFB_COLOURMAP_H__
#define __RFB_COLOURMAP_H__
namespace rfb {
struct Colour {
Colour() : r(0), g(0), b(0) {}
Colour(int r_, int g_, int b_) : r(r_), g(g_), b(b_) {}
int r, g, b;
bool operator==(const Colour& c) const {return c.r == r && c.g == g && c.b == b;}
bool operator!=(const Colour& c) const {return !(c == *this);}
};

class ColourMap {
public:
virtual void lookup(int index, int* r, int* g, int* b)=0;
virtual ~ColourMap() {}
};

class SimpleColourMap : public ColourMap {
public:
SimpleColourMap(int size = 256) { table = new Colour[size]; };
virtual ~SimpleColourMap() { delete [] table; };

void lookup(int index, int* r, int* g, int* b)
{ *r = table[index].r; *g = table[index].g; *b = table[index].b; };

void set(int index, int r, int g, int b)
{ table[index].r = r; table[index].g = g; table[index].b = b; };

protected:
Colour *table;
};
}
#endif

+ 7
- 16
common/rfb/PixelBuffer.cxx View File

@@ -33,16 +33,15 @@ static LogWriter vlog("PixelBuffer");

// -=- Generic pixel buffer class

PixelBuffer::PixelBuffer(const PixelFormat& pf, int w, int h, ColourMap* cm)
: format(pf), width_(w), height_(h), colourmap(cm) {}
PixelBuffer::PixelBuffer() : width_(0), height_(0), colourmap(0) {}
PixelBuffer::PixelBuffer(const PixelFormat& pf, int w, int h)
: format(pf), width_(w), height_(h) {}
PixelBuffer::PixelBuffer() : width_(0), height_(0) {}

PixelBuffer::~PixelBuffer() {}


void PixelBuffer::setPF(const PixelFormat &pf) {format = pf;}
const PixelFormat& PixelBuffer::getPF() const {return format;}
ColourMap* PixelBuffer::getColourMap() const {return colourmap;}


void
@@ -117,8 +116,8 @@ static void fillRect32(U8 *buf, int stride, const Rect& r, Pixel pix)


FullFramePixelBuffer::FullFramePixelBuffer(const PixelFormat& pf, int w, int h,
rdr::U8* data_, ColourMap* cm)
: PixelBuffer(pf, w, h, cm), data(data_)
rdr::U8* data_)
: PixelBuffer(pf, w, h), data(data_)
{
// Called again to configure the fill function
setPF(pf);
@@ -314,20 +313,19 @@ void FullFramePixelBuffer::copyRect(const Rect &rect, const Point &move_by_delta
// Automatically allocates enough space for the specified format & area

ManagedPixelBuffer::ManagedPixelBuffer()
: datasize(0), own_colourmap(false)
: datasize(0)
{
checkDataSize();
};

ManagedPixelBuffer::ManagedPixelBuffer(const PixelFormat& pf, int w, int h)
: FullFramePixelBuffer(pf, w, h, 0, 0), datasize(0), own_colourmap(false)
: FullFramePixelBuffer(pf, w, h, 0), datasize(0)
{
checkDataSize();
};

ManagedPixelBuffer::~ManagedPixelBuffer() {
if (data) delete [] data;
if (colourmap && own_colourmap) delete colourmap;
};


@@ -341,13 +339,6 @@ ManagedPixelBuffer::setSize(int w, int h) {
};


void
ManagedPixelBuffer::setColourMap(ColourMap* cm, bool own_cm) {
if (colourmap && own_colourmap) delete colourmap;
colourmap = cm;
own_colourmap = own_cm;
}

inline void
ManagedPixelBuffer::checkDataSize() {
unsigned long new_datasize = width_ * height_ * (format.bpp/8);

+ 2
- 9
common/rfb/PixelBuffer.h View File

@@ -26,7 +26,6 @@

#include <rfb/ImageGetter.h>
#include <rfb/PixelFormat.h>
#include <rfb/ColourMap.h>
#include <rfb/Rect.h>
#include <rfb/Pixel.h>

@@ -36,7 +35,7 @@ namespace rfb {

class PixelBuffer : public ImageGetter {
public:
PixelBuffer(const PixelFormat& pf, int width, int height, ColourMap* cm);
PixelBuffer(const PixelFormat& pf, int width, int height);
virtual ~PixelBuffer();

///////////////////////////////////////////////
@@ -49,7 +48,6 @@ namespace rfb {
virtual void setPF(const PixelFormat &pf);
public:
virtual const PixelFormat &getPF() const;
virtual ColourMap* getColourMap() const;

// Get width, height and number of pixels
int width() const { return width_; }
@@ -91,7 +89,6 @@ namespace rfb {
PixelBuffer();
PixelFormat format;
int width_, height_;
ColourMap* colourmap;
};

// FullFramePixelBuffer
@@ -99,7 +96,7 @@ namespace rfb {
class FullFramePixelBuffer : public PixelBuffer {
public:
FullFramePixelBuffer(const PixelFormat& pf, int width, int height,
rdr::U8* data_, ColourMap* cm);
rdr::U8* data_);
virtual ~FullFramePixelBuffer();

protected:
@@ -160,15 +157,11 @@ namespace rfb {
virtual void setPF(const PixelFormat &pf);
virtual void setSize(int w, int h);

// Assign a colour map to the buffer
virtual void setColourMap(ColourMap* cm, bool own_cm);

// Return the total number of bytes of pixel data in the buffer
int dataLen() const { return width_ * height_ * (format.bpp/8); }

protected:
unsigned long datasize;
bool own_colourmap;
void checkDataSize();
};


+ 90
- 58
common/rfb/PixelFormat.cxx View File

@@ -53,16 +53,51 @@ PixelFormat::PixelFormat()

bool PixelFormat::equal(const PixelFormat& other) const
{
return (bpp == other.bpp &&
depth == other.depth &&
(bigEndian == other.bigEndian || bpp == 8) &&
trueColour == other.trueColour &&
(!trueColour || (redMax == other.redMax &&
greenMax == other.greenMax &&
blueMax == other.blueMax &&
redShift == other.redShift &&
greenShift == other.greenShift &&
blueShift == other.blueShift)));
if (bpp != other.bpp || depth != other.depth)
return false;

if (redMax != other.redMax)
return false;
if (greenMax != other.greenMax)
return false;
if (blueMax != other.blueMax)
return false;

// Endianness requires more care to determine compatibility
if (bigEndian == other.bigEndian || bpp == 8) {
if (redShift != other.redShift)
return false;
if (greenShift != other.greenShift)
return false;
if (blueShift != other.blueShift)
return false;
} else {
// Has to be the same byte for each channel
if (redShift/8 != (3 - other.redShift/8))
return false;
if (greenShift/8 != (3 - other.greenShift/8))
return false;
if (blueShift/8 != (3 - other.blueShift/8))
return false;

// And the same bit offset within the byte
if (redShift%8 != other.redShift%8)
return false;
if (greenShift%8 != other.greenShift%8)
return false;
if (blueShift%8 != other.blueShift%8)
return false;

// And not cross a byte boundary
if (redShift/8 != (redShift + redBits - 1)/8)
return false;
if (greenShift/8 != (greenShift + greenBits - 1)/8)
return false;
if (blueShift/8 != (blueShift + blueBits - 1)/8)
return false;
}

return true;
}

void PixelFormat::read(rdr::InStream* is)
@@ -79,6 +114,18 @@ void PixelFormat::read(rdr::InStream* is)
blueShift = is->readU8();
is->skip(3);

// We have no real support for colour maps. If the client
// wants one, then we force a 8-bit true colour format and
// pretend it's a colour map.
if (!trueColour) {
redMax = 7;
greenMax = 7;
blueMax = 3;
redShift = 0;
greenShift = 3;
blueShift = 6;
}

if (!isSane())
throw Exception("invalid pixel format");

@@ -132,14 +179,13 @@ bool PixelFormat::isLittleEndian(void) const
}


void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
int pixels, ColourMap* cm) const
void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int pixels) const
{
bufferFromRGB(dst, src, pixels, pixels, 1, cm);
bufferFromRGB(dst, src, pixels, pixels, 1);
}

void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
int w, int stride, int h, ColourMap* cm) const
int w, int stride, int h) const
{
if (is888()) {
// Optimised common case
@@ -188,7 +234,7 @@ void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
g = *(src++);
b = *(src++);

p = pixelFromRGB(r, g, b, cm);
p = pixelFromRGB(r, g, b);

bufferFromPixel(dst, p);
dst += bpp/8;
@@ -199,26 +245,14 @@ void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
}


void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, Colour* rgb) const
{
rdr::U16 r, g, b;

rgbFromPixel(p, cm, &r, &g, &b);

rgb->r = r;
rgb->g = g;
rgb->b = b;
}


void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels, ColourMap* cm) const
void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels) const
{
rgbFromBuffer(dst, src, pixels, pixels, 1, cm);
rgbFromBuffer(dst, src, pixels, pixels, 1);
}


void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src,
int w, int stride, int h, ColourMap* cm) const
int w, int stride, int h) const
{
if (is888()) {
// Optimised common case
@@ -260,7 +294,7 @@ void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src,

p = pixelFromBuffer(src);

rgbFromPixel(p, cm, &r, &g, &b);
rgbFromPixel(p, &r, &g, &b);

*(dst++) = r;
*(dst++) = g;
@@ -449,36 +483,34 @@ bool PixelFormat::isSane(void)
if (!trueColour && (depth != 8))
return false;

if (trueColour) {
if ((redMax & (redMax + 1)) != 0)
return false;
if ((greenMax & (greenMax + 1)) != 0)
return false;
if ((blueMax & (blueMax + 1)) != 0)
return false;
if ((redMax & (redMax + 1)) != 0)
return false;
if ((greenMax & (greenMax + 1)) != 0)
return false;
if ((blueMax & (blueMax + 1)) != 0)
return false;

/*
* We don't allow individual channels > 8 bits in order to keep our
* conversions simple.
*/
if (redMax >= (1 << 8))
return false;
if (greenMax >= (1 << 8))
return false;
if (blueMax >= (1 << 8))
return false;
/*
* We don't allow individual channels > 8 bits in order to keep our
* conversions simple.
*/
if (redMax >= (1 << 8))
return false;
if (greenMax >= (1 << 8))
return false;
if (blueMax >= (1 << 8))
return false;

totalBits = bits(redMax) + bits(greenMax) + bits(blueMax);
if (totalBits > bpp)
return false;
totalBits = bits(redMax) + bits(greenMax) + bits(blueMax);
if (totalBits > bpp)
return false;

if (((redMax << redShift) & (greenMax << greenShift)) != 0)
return false;
if (((redMax << redShift) & (blueMax << blueShift)) != 0)
return false;
if (((greenMax << greenShift) & (blueMax << blueShift)) != 0)
return false;
}
if (((redMax << redShift) & (greenMax << greenShift)) != 0)
return false;
if (((redMax << redShift) & (blueMax << blueShift)) != 0)
return false;
if (((greenMax << greenShift) & (blueMax << blueShift)) != 0)
return false;

return true;
}

+ 17
- 13
common/rfb/PixelFormat.h View File

@@ -35,7 +35,6 @@
#define __RFB_PIXELFORMAT_H__

#include <rfb/Pixel.h>
#include <rfb/ColourMap.h>

namespace rdr { class InStream; class OutStream; }

@@ -44,9 +43,12 @@ namespace rfb {
class PixelFormat {
public:
PixelFormat(int b, int d, bool e, bool t,
int rm=0, int gm=0, int bm=0, int rs=0, int gs=0, int bs=0);
int rm, int gm, int bm, int rs, int gs, int bs);
PixelFormat();

// Checks if the formats have identical buffer representation.
// They might still have different pixel representation, endianness
// or true colour state.
bool equal(const PixelFormat& other) const;

void read(rdr::InStream* is);
@@ -59,20 +61,19 @@ namespace rfb {
inline Pixel pixelFromBuffer(const rdr::U8* buffer) const;
inline void bufferFromPixel(rdr::U8* buffer, Pixel pixel) const;

inline Pixel pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue, ColourMap* cm=0) const;
inline Pixel pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue, ColourMap* cm=0) const;
inline Pixel pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue) const;
inline Pixel pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue) const;

void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int pixels, ColourMap* cm=0) const;
void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int w, int stride,
int h, ColourMap* cm=0) const;
void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int pixels) const;
void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
int w, int stride, int h) const;

void rgbFromPixel(Pixel pix, ColourMap* cm, Colour* rgb) const;
inline void rgbFromPixel(Pixel pix, ColourMap* cm, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const;
inline void rgbFromPixel(Pixel pix, ColourMap* cm, rdr::U8 *r, rdr::U8 *g, rdr::U8 *b) const;
inline void rgbFromPixel(Pixel pix, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const;
inline void rgbFromPixel(Pixel pix, rdr::U8 *r, rdr::U8 *g, rdr::U8 *b) const;

void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels, ColourMap* cm=0) const;
void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int w, int stride,
int h, ColourMap* cm=0) const;
void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels) const;
void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src,
int w, int stride, int h) const;

void print(char* str, int len) const;
bool parse(const char* str);
@@ -84,6 +85,9 @@ namespace rfb {
public:
int bpp;
int depth;

// This only tracks if the client thinks it is in colour map mode.
// In practice we are always in true colour mode.
bool trueColour;

// FIXME: These should be protected, but we need to fix TransImageGetter first.

+ 59
- 109
common/rfb/PixelFormat.inl View File

@@ -75,131 +75,81 @@ inline void PixelFormat::bufferFromPixel(rdr::U8* buffer, Pixel p) const
}


inline Pixel PixelFormat::pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue, ColourMap* cm) const
inline Pixel PixelFormat::pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue) const
{
if (trueColour) {
Pixel p;

/* We don't need to mask since we shift out unwanted bits */
p = ((Pixel)red >> (16 - redBits)) << redShift;
p |= ((Pixel)green >> (16 - greenBits)) << greenShift;
p |= ((Pixel)blue >> (16 - blueBits)) << blueShift;
} else if (cm) {
// Try to find the closest pixel by Cartesian distance
int colours = 1 << depth;
int diff = 256 * 256 * 4;
int col = 0;
for (int i=0; i<colours; i++) {
int r, g, b;
cm->lookup(i, &r, &g, &b);
int rd = (r-red) >> 8;
int gd = (g-green) >> 8;
int bd = (b-blue) >> 8;
int d = rd*rd + gd*gd + bd*bd;
if (d < diff) {
col = i;
diff = d;
}
}
return col;
} else {
// XXX just return 0 for colour map?
return 0;
}
Pixel p;

/* We don't need to mask since we shift out unwanted bits */
p = ((Pixel)red >> (16 - redBits)) << redShift;
p |= ((Pixel)green >> (16 - greenBits)) << greenShift;
p |= ((Pixel)blue >> (16 - blueBits)) << blueShift;

return p;
}


inline Pixel PixelFormat::pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue, ColourMap* cm) const
inline Pixel PixelFormat::pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue) const
{
if (trueColour) {
Pixel p;
Pixel p;

p = ((Pixel)red >> (8 - redBits)) << redShift;
p |= ((Pixel)green >> (8 - greenBits)) << greenShift;
p |= ((Pixel)blue >> (8 - blueBits)) << blueShift;
p = ((Pixel)red >> (8 - redBits)) << redShift;
p |= ((Pixel)green >> (8 - greenBits)) << greenShift;
p |= ((Pixel)blue >> (8 - blueBits)) << blueShift;

return p;
} else {
return pixelFromRGB((rdr::U16)(red << 8 | red),
(rdr::U16)(green << 8 | green),
(rdr::U16)(blue << 8 | blue), cm);
}
return p;
}


inline void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const
inline void PixelFormat::rgbFromPixel(Pixel p, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const
{
if (trueColour) {
int mb, rb, gb, bb;

/* Bit replication is much cheaper than multiplication and division */

mb = minBits;
rb = redBits;
gb = greenBits;
bb = blueBits;

*r = (p >> redShift) << (16 - rb);
*g = (p >> greenShift) << (16 - gb);
*b = (p >> blueShift) << (16 - bb);

while (mb < 16) {
*r = *r | (*r >> rb);
*g = *g | (*g >> gb);
*b = *b | (*b >> bb);
mb <<= 1;
rb <<= 1;
gb <<= 1;
bb <<= 1;
}
} else if (cm) {
int ir, ig, ib;
cm->lookup(p, &ir, &ig, &ib);
*r = ir;
*g = ig;
*b = ib;
} else {
// XXX just return 0 for colour map?
*r = 0;
*g = 0;
*b = 0;
int mb, rb, gb, bb;

/* Bit replication is much cheaper than multiplication and division */

mb = minBits;
rb = redBits;
gb = greenBits;
bb = blueBits;

*r = (p >> redShift) << (16 - rb);
*g = (p >> greenShift) << (16 - gb);
*b = (p >> blueShift) << (16 - bb);

while (mb < 16) {
*r = *r | (*r >> rb);
*g = *g | (*g >> gb);
*b = *b | (*b >> bb);
mb <<= 1;
rb <<= 1;
gb <<= 1;
bb <<= 1;
}
}


inline void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, rdr::U8 *r, rdr::U8 *g, rdr::U8 *b) const
inline void PixelFormat::rgbFromPixel(Pixel p, rdr::U8 *r, rdr::U8 *g, rdr::U8 *b) const
{
if (trueColour) {
int mb, rb, gb, bb;

/* Bit replication is much cheaper than multiplication and division */

mb = minBits;
rb = redBits;
gb = greenBits;
bb = blueBits;

*r = (p >> redShift) << (8 - rb);
*g = (p >> greenShift) << (8 - gb);
*b = (p >> blueShift) << (8 - bb);

while (mb < 8) {
*r = *r | (*r >> rb);
*g = *g | (*g >> gb);
*b = *b | (*b >> bb);
mb <<= 1;
rb <<= 1;
gb <<= 1;
bb <<= 1;
}
} else {
rdr::U16 r2, g2, b2;

rgbFromPixel(p, cm, &r2, &g2, &b2);

*r = r2 >> 8;
*g = g2 >> 8;
*b = b2 >> 8;
int mb, rb, gb, bb;

/* Bit replication is much cheaper than multiplication and division */

mb = minBits;
rb = redBits;
gb = greenBits;
bb = blueBits;

*r = (p >> redShift) << (8 - rb);
*g = (p >> greenShift) << (8 - gb);
*b = (p >> blueShift) << (8 - bb);

while (mb < 8) {
*r = *r | (*r >> rb);
*g = *g | (*g >> gb);
*b = *b | (*b >> bb);
mb <<= 1;
rb <<= 1;
gb <<= 1;
bb <<= 1;
}
}


+ 11
- 137
common/rfb/PixelTransformer.cxx View File

@@ -22,10 +22,7 @@
#include <string.h>
#include <rfb/PixelFormat.h>
#include <rfb/Exception.h>
#include <rfb/ColourMap.h>
#include <rfb/TrueColourMap.h>
#include <rfb/PixelBuffer.h>
#include <rfb/ColourCube.h>
#include <rfb/PixelTransformer.h>

using namespace rfb;
@@ -100,50 +97,23 @@ static transFnType transRGBFns[][3] = {
{ transRGB16to8, transRGB16to16, transRGB16to32 },
{ transRGB32to8, transRGB32to16, transRGB32to32 }
};
static transFnType transRGBCubeFns[][3] = {
{ transRGBCube16to8, transRGBCube16to16, transRGBCube16to32 },
{ transRGBCube32to8, transRGBCube32to16, transRGBCube32to32 }
};

// Table initialisation functions.

typedef void (*initCMtoTCFnType)(rdr::U8** tablep, const PixelFormat& inPF,
ColourMap* cm, const PixelFormat& outPF);
typedef void (*initTCtoTCFnType)(rdr::U8** tablep, const PixelFormat& inPF,
const PixelFormat& outPF);
typedef void (*initCMtoCubeFnType)(rdr::U8** tablep, const PixelFormat& inPF,
ColourMap* cm, ColourCube* cube);
typedef void (*initTCtoCubeFnType)(rdr::U8** tablep, const PixelFormat& inPF,
ColourCube* cube);

typedef void (*initFnType)(rdr::U8** tablep, const PixelFormat& inPF,
const PixelFormat& outPF);

static initCMtoTCFnType initSimpleCMtoTCFns[] = {
initSimpleCMtoTC8, initSimpleCMtoTC16, initSimpleCMtoTC32
static initFnType initSimpleFns[] = {
initSimple8, initSimple16, initSimple32
};

static initTCtoTCFnType initSimpleTCtoTCFns[] = {
initSimpleTCtoTC8, initSimpleTCtoTC16, initSimpleTCtoTC32
};

static initCMtoCubeFnType initSimpleCMtoCubeFns[] = {
initSimpleCMtoCube8, initSimpleCMtoCube16, initSimpleCMtoCube32
};

static initTCtoCubeFnType initSimpleTCtoCubeFns[] = {
initSimpleTCtoCube8, initSimpleTCtoCube16, initSimpleTCtoCube32
};

static initTCtoTCFnType initRGBTCtoTCFns[] = {
initRGBTCtoTC8, initRGBTCtoTC16, initRGBTCtoTC32
};

static initTCtoCubeFnType initRGBTCtoCubeFns[] = {
initRGBTCtoCube8, initRGBTCtoCube16, initRGBTCtoCube32
static initFnType initRGBFns[] = {
initRGB8, initRGB16, initRGB32
};


PixelTransformer::PixelTransformer(bool econ)
: economic(econ), cmCallback(0), cube(0), table(0), transFn(0)
: economic(econ), table(0), transFn(0)
{
}

@@ -152,17 +122,11 @@ PixelTransformer::~PixelTransformer()
delete [] table;
}

void PixelTransformer::init(const PixelFormat& inPF_, ColourMap* inCM_,
const PixelFormat& outPF_, ColourCube* cube_,
setCMFnType cmCallback_, void *cbData_)
void PixelTransformer::init(const PixelFormat& inPF_,
const PixelFormat& outPF_)
{
inPF = inPF_;
inCM = inCM_;

outPF = outPF_;
cube = cube_;
cmCallback = cmCallback_;
cbData = cbData_;

if (table)
delete [] table;
@@ -175,79 +139,17 @@ void PixelTransformer::init(const PixelFormat& inPF_, ColourMap* inCM_,
if ((outPF.bpp != 8) && (outPF.bpp != 16) && (outPF.bpp != 32))
throw Exception("PixelTransformer: bpp out not 8, 16 or 32");

if (!outPF.trueColour) {
if (outPF.bpp != 8)
throw Exception("PixelTransformer: outPF has color map but not 8bpp");

if (!inPF.trueColour) {
if (inPF.bpp != 8)
throw Exception("PixelTransformer: inPF has colorMap but not 8bpp");
if (!inCM)
throw Exception("PixelTransformer: inPF has colorMap but no colour map specified");

// CM to CM/Cube

if (cube) {
transFn = transSimpleFns[0][0];
(*initSimpleCMtoCubeFns[0]) (&table, inPF, inCM, cube);
} else {
transFn = noTransFn;
setColourMapEntries(0, 256);
}
return;
}

// TC to CM/Cube

ColourCube defaultCube(6,6,6);
if (!cube) cube = &defaultCube;

if ((inPF.bpp > 16) || (economic && (inPF.bpp == 16))) {
transFn = transRGBCubeFns[inPF.bpp/32][0];
(*initRGBTCtoCubeFns[0]) (&table, inPF, cube);
} else {
transFn = transSimpleFns[inPF.bpp/16][0];
(*initSimpleTCtoCubeFns[0]) (&table, inPF, cube);
}

if (cube != &defaultCube)
return;

if (!cmCallback)
throw Exception("PixelTransformer: Neither colour map callback nor colour cube provided");

cmCallback(0, 216, cube, cbData);
cube = 0;
return;
}

if (inPF.equal(outPF)) {
transFn = noTransFn;
return;
}

if (!inPF.trueColour) {

// CM to TC

if (inPF.bpp != 8)
throw Exception("PixelTransformer: inPF has colorMap but not 8bpp");
if (!inCM)
throw Exception("PixelTransformer: inPF has colorMap but no colour map specified");

transFn = transSimpleFns[0][outPF.bpp/16];
(*initSimpleCMtoTCFns[outPF.bpp/16]) (&table, inPF, inCM, outPF);
return;
}

// TC to TC

if ((inPF.bpp > 16) || (economic && (inPF.bpp == 16))) {
transFn = transRGBFns[inPF.bpp/32][outPF.bpp/16];
(*initRGBTCtoTCFns[outPF.bpp/16]) (&table, inPF, outPF);
(*initRGBFns[outPF.bpp/16]) (&table, inPF, outPF);
} else {
transFn = transSimpleFns[inPF.bpp/16][outPF.bpp/16];
(*initSimpleTCtoTCFns[outPF.bpp/16]) (&table, inPF, outPF);
(*initSimpleFns[outPF.bpp/16]) (&table, inPF, outPF);
}
}

@@ -256,39 +158,11 @@ const PixelFormat &PixelTransformer::getInPF() const
return inPF;
}

const ColourMap *PixelTransformer::getInColourMap() const
{
return inCM;
}

const PixelFormat &PixelTransformer::getOutPF() const
{
return outPF;
}

const ColourCube *PixelTransformer::getOutColourCube() const
{
return cube;
}

void PixelTransformer::setColourMapEntries(int firstCol, int nCols)
{
if (nCols == 0)
nCols = (1 << inPF.depth) - firstCol;

if (inPF.trueColour) return; // shouldn't be called in this case

if (outPF.trueColour) {
(*initSimpleCMtoTCFns[outPF.bpp/16]) (&table, inPF, inCM, outPF);
} else if (cube) {
(*initSimpleCMtoCubeFns[outPF.bpp/16]) (&table, inPF, inCM, cube);
} else {
if (!cmCallback)
throw Exception("PixelTransformer: Neither colour map callback nor colour cube provided");
cmCallback(firstCol, nCols, inCM, cbData);
}
}

void PixelTransformer::translatePixels(const void* inPtr, void* outPtr,
int nPixels) const
{

+ 2
- 31
common/rfb/PixelTransformer.h View File

@@ -33,11 +33,7 @@ namespace rfb {
int outStride, int width, int height);

class SMsgWriter;
class ColourMap;
class PixelBuffer;
class ColourCube;

typedef void (*setCMFnType)(int firstColour, int nColours, ColourMap* cm, void* data);

class PixelTransformer {
public:
@@ -47,32 +43,12 @@ namespace rfb {

// init() is called to initialise the translation tables. The inPF and
// inCM arguments give the source format details, outPF gives the
// target pixel format. If the target has a colour map, then the you
// must specify either a colour map callback or a colour cube to indicate
// how the target colour map should be handled. If both are specified
// then the cube will be used.
// target pixel format.

void init(const PixelFormat& inPF, ColourMap* inCM,
const PixelFormat& outPF, ColourCube* cube = NULL,
setCMFnType cmCallback = NULL, void *cbData = NULL);
void init(const PixelFormat& inPF, const PixelFormat& outPF);

const PixelFormat &getInPF() const;
const ColourMap *getInColourMap() const;

const PixelFormat &getOutPF() const;
const ColourCube *getOutColourCube() const;

// setColourMapEntries() is called when the colour map specified to init()
// has changed. firstColour and nColours specify which part of the
// colour map has changed. If nColours is 0, this means the rest of the
// colour map. If the target also has a colour map, then the callback or
// cube specified to init() will be used. If the target is true colour
// then instead we update the internal translation table - in this case
// the caller should also make sure that the target surface receives an
// update of the relevant parts (the simplest thing to do is just update
// the whole framebuffer, though it is possible to be smarter than this).

void setColourMapEntries(int firstColour, int nColours);

// translatePixels() translates the given number of pixels from inPtr,
// putting it into the buffer pointed to by outPtr. The pixels at inPtr
@@ -91,12 +67,7 @@ namespace rfb {
bool economic;

PixelFormat inPF;
ColourMap* inCM;

PixelFormat outPF;
setCMFnType cmCallback;
void *cbData;
ColourCube* cube;

rdr::U8* table;
transFnType transFn;

+ 14
- 5
common/rfb/SConnection.cxx View File

@@ -306,10 +306,6 @@ void SConnection::approveConnection(bool accept, const char* reason)
}
}

void SConnection::setInitialColourMap()
{
}

void SConnection::clientInit(bool shared)
{
writer_->writeServerInit();
@@ -320,6 +316,8 @@ void SConnection::setPixelFormat(const PixelFormat& pf)
{
SMsgHandler::setPixelFormat(pf);
readyForSetColourMapEntries = true;
if (!pf.trueColour)
writeFakeColourMap();
}

void SConnection::framebufferUpdateRequest(const Rect& r, bool incremental)
@@ -327,7 +325,7 @@ void SConnection::framebufferUpdateRequest(const Rect& r, bool incremental)
if (!readyForSetColourMapEntries) {
readyForSetColourMapEntries = true;
if (!cp.pf().trueColour) {
setInitialColourMap();
writeFakeColourMap();
}
}
}
@@ -347,3 +345,14 @@ void SConnection::enableContinuousUpdates(bool enable,
int x, int y, int w, int h)
{
}

void SConnection::writeFakeColourMap(void)
{
int i;
rdr::U16 red[256], green[256], blue[256];

for (i = 0;i < 256;i++)
cp.pf().rgbFromPixel(i, &red[i], &green[i], &blue[i]);

writer()->writeSetColourMapEntries(0, 256, red, green, blue);
}

+ 1
- 5
common/rfb/SConnection.h View File

@@ -102,11 +102,6 @@ namespace rfb {
// SConnection::framebufferUpdateRequest().
virtual void framebufferUpdateRequest(const Rect& r, bool incremental);

// setInitialColourMap() is called when the client needs an initial
// SetColourMapEntries message. In fact this only happens when the client
// accepts the server's default pixel format and it uses a colour map.
virtual void setInitialColourMap();

// fence() is called when we get a fence request or response. By default
// it responds directly to requests (stating it doesn't support any
// synchronisation) and drops responses. Override to implement more proper
@@ -180,6 +175,7 @@ namespace rfb {

protected:
void setState(stateEnum s) { state_ = s; }
void writeFakeColourMap(void);

bool readyForSetColourMapEntries;


+ 6
- 7
common/rfb/SMsgWriter.cxx View File

@@ -23,7 +23,6 @@
#include <rfb/msgTypes.h>
#include <rfb/fenceTypes.h>
#include <rfb/Exception.h>
#include <rfb/ColourMap.h>
#include <rfb/ConnParams.h>
#include <rfb/UpdateTracker.h>
#include <rfb/Encoder.h>
@@ -76,18 +75,18 @@ void SMsgWriter::writeServerInit()
}

void SMsgWriter::writeSetColourMapEntries(int firstColour, int nColours,
ColourMap* cm)
const rdr::U16 red[],
const rdr::U16 green[],
const rdr::U16 blue[])
{
startMsg(msgTypeSetColourMapEntries);
os->pad(1);
os->writeU16(firstColour);
os->writeU16(nColours);
for (int i = firstColour; i < firstColour+nColours; i++) {
int r, g, b;
cm->lookup(i, &r, &g, &b);
os->writeU16(r);
os->writeU16(g);
os->writeU16(b);
os->writeU16(red[i]);
os->writeU16(green[i]);
os->writeU16(blue[i]);
}
endMsg();
}

+ 4
- 4
common/rfb/SMsgWriter.h View File

@@ -33,7 +33,6 @@ namespace rfb {

class ConnParams;
class TransImageGetter;
class ColourMap;
class Region;
class UpdateInfo;
class Encoder;
@@ -56,10 +55,11 @@ namespace rfb {
// Methods to write normal protocol messages

// writeSetColourMapEntries() writes a setColourMapEntries message, using
// the given ColourMap object to lookup the RGB values of the given range
// of colours.
// the given colour entries.
void writeSetColourMapEntries(int firstColour, int nColours,
ColourMap* cm);
const rdr::U16 red[],
const rdr::U16 green[],
const rdr::U16 blue[]);

// writeBell() and writeServerCutText() do the obvious thing.
void writeBell();

+ 3
- 3
common/rfb/TightEncoder.cxx View File

@@ -338,9 +338,9 @@ void TightEncoder::writeRect(const Rect& _r, TransImageGetter* _ig)
if (checkSolidTile(sr, &colorValue, false)) {

if (jpegSubsampling == subsampleGray && jpegQuality != -1) {
Colour rgb;
serverpf.rgbFromPixel(colorValue, NULL, &rgb);
rdr::U32 lum = ((257 * rgb.r) + (504 * rgb.g) + (98 * rgb.b)
rdr::U16 r, g, b;
serverpf.rgbFromPixel(colorValue, &r, &g, &b);
rdr::U32 lum = ((257 * r) + (504 * g) + (98 * b)
+ 16500) / 1000;
colorValue = lum + (lum << 8) + (lum << 16);
}

+ 2
- 23
common/rfb/TransImageGetter.cxx View File

@@ -24,10 +24,7 @@
#include <rfb/Exception.h>
#include <rfb/ConnParams.h>
#include <rfb/SMsgWriter.h>
#include <rfb/ColourMap.h>
#include <rfb/TrueColourMap.h>
#include <rfb/PixelBuffer.h>
#include <rfb/ColourCube.h>
#include <rfb/TransImageGetter.h>

using namespace rfb;
@@ -42,18 +39,12 @@ TransImageGetter::~TransImageGetter()
}

void TransImageGetter::init(PixelBuffer* pb_, const PixelFormat& out,
SMsgWriter* writer_, ColourCube* cube_)
SMsgWriter* writer_)
{
pb = pb_;
writer = writer_;

PixelTransformer::init(pb->getPF(), pb->getColourMap(), out, cube_,
cmCallback, this);
}

void TransImageGetter::setColourMapEntries(int firstCol, int nCols)
{
PixelTransformer::setColourMapEntries(firstCol, nCols);
PixelTransformer::init(pb->getPF(), out);
}

const rdr::U8 *TransImageGetter::getRawBufferR(const Rect &r, int *stride)
@@ -74,15 +65,3 @@ void TransImageGetter::getImage(void* outPtr, const Rect& r, int outStride)
translateRect((void*)inPtr, inStride, Rect(0, 0, r.width(), r.height()),
outPtr, outStride, Point(0, 0));
}

void TransImageGetter::cmCallback(int firstColour, int nColours,
ColourMap* cm, void* data)
{
TransImageGetter *self;

assert(data);
self = (TransImageGetter*)data;

if (self->writer)
self->writer->writeSetColourMapEntries(firstColour, nColours, cm);
}

+ 2
- 25
common/rfb/TransImageGetter.h View File

@@ -32,9 +32,7 @@
namespace rfb {

class SMsgWriter;
class ColourMap;
class PixelBuffer;
class ColourCube;

class TransImageGetter : public ImageGetter,
public PixelTransformer {
@@ -45,25 +43,9 @@ namespace rfb {

// init() is called to initialise the translation tables. The PixelBuffer
// argument gives the source data and format details, outPF gives the
// client's pixel format. If the client has a colour map, then the writer
// argument is used to send a SetColourMapEntries message to the client.
// client's pixel format.

void init(PixelBuffer* pb, const PixelFormat& outPF, SMsgWriter* writer=0,
ColourCube* cube=0);

// setColourMapEntries() is called when the PixelBuffer has a colour map
// which has changed. firstColour and nColours specify which part of the
// colour map has changed. If nColours is 0, this means the rest of the
// colour map. The PixelBuffer previously passed to init() must have a
// valid ColourMap object. If the client also has a colour map, then the
// writer argument is used to send a SetColourMapEntries message to the
// client. If the client is true colour then instead we update the
// internal translation table - in this case the caller should also make
// sure that the client receives an update of the relevant parts of the
// framebuffer (the simplest thing to do is just update the whole
// framebuffer, though it is possible to be smarter than this).

void setColourMapEntries(int firstColour, int nColours);
void init(PixelBuffer* pb, const PixelFormat& outPF, SMsgWriter* writer=0);

// getImage() gets the given rectangle of data from the PixelBuffer,
// translates it into the client's pixel format and puts it in the buffer
@@ -89,10 +71,6 @@ namespace rfb {
// the rectangle given to getImage().
void setOffset(const Point& offset_) { offset = offset_; }

private:
static void cmCallback(int firstColour, int nColours,
ColourMap* cm, void* data);

private:
bool economic;
PixelBuffer* pb;
@@ -100,7 +78,6 @@ namespace rfb {
SMsgWriter* writer;
rdr::U8* table;
transFnType transFn;
ColourCube* cube;
Point offset;
};
}

+ 0
- 41
common/rfb/TrueColourMap.h View File

@@ -1,41 +0,0 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
* 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 __RFB_TRUECOLOURMAP_H__
#define __RFB_TRUECOLOURMAP_H__

#include <rfb/ColourMap.h>

namespace rfb {

class TrueColourMap : public ColourMap {
public:
TrueColourMap(const PixelFormat& pf_) : pf(pf_) {}

virtual void lookup(int i, int* r, int* g, int* b)
{
rdr::U16 _r, _g, _b;
pf.rgbFromPixel(i, NULL, &_r, &_g, &_b);
*r = _r;
*g = _g;
*b = _b;
}
private:
PixelFormat pf;
};
}
#endif

+ 0
- 29
common/rfb/VNCSConnectionST.cxx View File

@@ -253,15 +253,6 @@ void VNCSConnectionST::screenLayoutChangeOrClose(rdr::U16 reason)
}
}

void VNCSConnectionST::setColourMapEntriesOrClose(int firstColour,int nColours)
{
try {
setColourMapEntries(firstColour, nColours);
} catch(rdr::Exception& e) {
close(e.str());
}
}

void VNCSConnectionST::bellOrClose()
{
try {
@@ -625,11 +616,6 @@ void VNCSConnectionST::setDesktopSize(int fb_width, int fb_height,
writeFramebufferUpdate();
}

void VNCSConnectionST::setInitialColourMap()
{
setColourMapEntries(0, 0);
}

void VNCSConnectionST::fence(rdr::U32 flags, unsigned len, const char data[])
{
if (flags & fenceFlagRequest) {
@@ -1151,21 +1137,6 @@ void VNCSConnectionST::screenLayoutChange(rdr::U16 reason)
writeFramebufferUpdate();
}

void VNCSConnectionST::setColourMapEntries(int firstColour, int nColours)
{
if (!readyForSetColourMapEntries)
return;
if (server->pb->getPF().trueColour)
return;

image_getter.setColourMapEntries(firstColour, nColours);

if (cp.pf().trueColour) {
updates.add_changed(server->pb->getRect());
writeFramebufferUpdate();
}
}


// setCursor() is called whenever the cursor has changed shape or pixel format.
// If the client supports local cursor then it will arrange for the cursor to

+ 0
- 3
common/rfb/VNCSConnectionST.h View File

@@ -71,7 +71,6 @@ namespace rfb {
// Wrappers to make these methods "safe" for VNCServerST.
void writeFramebufferUpdateOrClose();
void screenLayoutChangeOrClose(rdr::U16 reason);
void setColourMapEntriesOrClose(int firstColour, int nColours);
void setCursorOrClose();
void bellOrClose();
void serverCutTextOrClose(const char *str, int len);
@@ -138,7 +137,6 @@ namespace rfb {
virtual void framebufferUpdateRequest(const Rect& r, bool incremental);
virtual void setDesktopSize(int fb_width, int fb_height,
const ScreenSet& layout);
virtual void setInitialColourMap();
virtual void fence(rdr::U32 flags, unsigned len, const char data[]);
virtual void enableContinuousUpdates(bool enable,
int x, int y, int w, int h);
@@ -173,7 +171,6 @@ namespace rfb {

void writeRenderedCursorRect();
void screenLayoutChange(rdr::U16 reason);
void setColourMapEntries(int firstColour, int nColours);
void setCursor();
void setDesktopName(const char *name);
void setSocketTimeouts();

+ 0
- 6
common/rfb/VNCServer.h View File

@@ -52,12 +52,6 @@ namespace rfb {
// getPixelBuffer() returns a pointer to the PixelBuffer object.
virtual PixelBuffer* getPixelBuffer() const = 0;

// setColourMapEntries() tells the server that some entries in the colour
// map have changed. The server will retrieve them via the PixelBuffer's
// ColourMap object. This may result in protocol messages being sent.
// If nColours is 0, this means the rest of the colour map.
virtual void setColourMapEntries(int firstColour=0, int nColours=0) = 0;

// serverCutText() tells the server that the cut text has changed. This
// will normally be sent to all clients.
virtual void serverCutText(const char* str, int len) = 0;

+ 0
- 9
common/rfb/VNCServerST.cxx View File

@@ -359,15 +359,6 @@ void VNCServerST::setScreenLayout(const ScreenSet& layout)
}
}

void VNCServerST::setColourMapEntries(int firstColour, int nColours)
{
std::list<VNCSConnectionST*>::iterator ci, ci_next;
for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {
ci_next = ci; ci_next++;
(*ci)->setColourMapEntriesOrClose(firstColour, nColours);
}
}

void VNCServerST::bell()
{
std::list<VNCSConnectionST*>::iterator ci, ci_next;

+ 0
- 1
common/rfb/VNCServerST.h View File

@@ -88,7 +88,6 @@ namespace rfb {
virtual void setPixelBuffer(PixelBuffer* pb);
virtual void setScreenLayout(const ScreenSet& layout);
virtual PixelBuffer* getPixelBuffer() const { return pb; }
virtual void setColourMapEntries(int firstColour=0, int nColours=0);
virtual void serverCutText(const char* str, int len);
virtual void add_changed(const Region &region);
virtual void add_copied(const Region &dest, const Point &delta);

+ 9
- 9
common/rfb/tightDecode.h View File

@@ -73,7 +73,7 @@ void TIGHT_DECODE (const Rect& r)
if (cutZeros) {
rdr::U8 bytebuf[3];
is->readBytes(bytebuf, 3);
serverpf.bufferFromRGB((rdr::U8*)&pix, bytebuf, 1, NULL);
serverpf.bufferFromRGB((rdr::U8*)&pix, bytebuf, 1);
} else {
pix = is->READ_PIXEL();
}
@@ -107,7 +107,7 @@ void TIGHT_DECODE (const Rect& r)
if (cutZeros) {
rdr::U8 tightPalette[256 * 3];
is->readBytes(tightPalette, palSize * 3);
serverpf.bufferFromRGB((rdr::U8*)palette, tightPalette, palSize, NULL);
serverpf.bufferFromRGB((rdr::U8*)palette, tightPalette, palSize);
} else {
is->readBytes(palette, palSize * sizeof(PIXEL_T));
}
@@ -175,7 +175,7 @@ void TIGHT_DECODE (const Rect& r)
int w = r.width();
if (cutZeros) {
while (h > 0) {
serverpf.bufferFromRGB((rdr::U8*)ptr, srcPtr, w, NULL);
serverpf.bufferFromRGB((rdr::U8*)ptr, srcPtr, w);
ptr += stride;
srcPtr += w * 3;
h--;
@@ -284,7 +284,7 @@ TightDecoder::FilterGradient24(rdr::U8 *netbuf, PIXEL_T* buf, int stride,
pix[c] = netbuf[y*rectWidth*3+c] + prevRow[c];
thisRow[c] = pix[c];
}
serverpf.bufferFromRGB((rdr::U8*)&buf[y*stride], pix, 1, NULL);
serverpf.bufferFromRGB((rdr::U8*)&buf[y*stride], pix, 1);

/* Remaining pixels of a row */
for (x = 1; x < rectWidth; x++) {
@@ -298,7 +298,7 @@ TightDecoder::FilterGradient24(rdr::U8 *netbuf, PIXEL_T* buf, int stride,
pix[c] = netbuf[(y*rectWidth+x)*3+c] + est[c];
thisRow[x*3+c] = pix[c];
}
serverpf.bufferFromRGB((rdr::U8*)&buf[y*stride+x], pix, 1, NULL);
serverpf.bufferFromRGB((rdr::U8*)&buf[y*stride+x], pix, 1);
}

memcpy(prevRow, thisRow, sizeof(prevRow));
@@ -324,13 +324,13 @@ FILTER_GRADIENT(rdr::U8 *netbuf, PIXEL_T* buf, int stride, const Rect& r)

for (y = 0; y < rectHeight; y++) {
/* First pixel in a row */
serverpf.rgbFromBuffer(pix, (rdr::U8*)&netbuf[y*rectWidth], 1, NULL);
serverpf.rgbFromBuffer(pix, (rdr::U8*)&netbuf[y*rectWidth], 1);
for (c = 0; c < 3; c++)
pix[c] += prevRow[c];

memcpy(thisRow, pix, sizeof(pix));

serverpf.bufferFromRGB((rdr::U8*)&buf[y*stride], pix, 1, NULL);
serverpf.bufferFromRGB((rdr::U8*)&buf[y*stride], pix, 1);

/* Remaining pixels of a row */
for (x = 1; x < rectWidth; x++) {
@@ -343,13 +343,13 @@ FILTER_GRADIENT(rdr::U8 *netbuf, PIXEL_T* buf, int stride, const Rect& r)
}
}

serverpf.rgbFromBuffer(pix, (rdr::U8*)&netbuf[y*rectWidth+x], 1, NULL);
serverpf.rgbFromBuffer(pix, (rdr::U8*)&netbuf[y*rectWidth+x], 1);
for (c = 0; c < 3; c++)
pix[c] += est[c];

memcpy(&thisRow[x*3], pix, sizeof(pix));

serverpf.bufferFromRGB((rdr::U8*)&buf[y*stride+x], pix, 1, NULL);
serverpf.bufferFromRGB((rdr::U8*)&buf[y*stride+x], pix, 1);
}

memcpy(prevRow, thisRow, sizeof(prevRow));

+ 1
- 1
common/rfb/tightEncode.h View File

@@ -99,7 +99,7 @@ unsigned int PACK_PIXELS (PIXEL_T *buf, unsigned int count)
rdr::U8 *dst = (rdr::U8 *)buf;
for (unsigned int i = 0; i < count; i++) {
pix = *buf++;
clientpf.rgbFromBuffer(dst, (rdr::U8*)&pix, 1, NULL);
clientpf.rgbFromBuffer(dst, (rdr::U8*)&pix, 1);
dst += 3;
}
return count * 3;

+ 10
- 129
common/rfb/transInitTempl.h View File

@@ -46,12 +46,8 @@ namespace rfb {

#define OUTPIXEL rdr::CONCAT2E(U,BPPOUT)
#define SWAPOUT CONCAT2E(SWAP,BPPOUT)
#define initSimpleCMtoTCOUT CONCAT2E(initSimpleCMtoTC,BPPOUT)
#define initSimpleTCtoTCOUT CONCAT2E(initSimpleTCtoTC,BPPOUT)
#define initSimpleCMtoCubeOUT CONCAT2E(initSimpleCMtoCube,BPPOUT)
#define initSimpleTCtoCubeOUT CONCAT2E(initSimpleTCtoCube,BPPOUT)
#define initRGBTCtoTCOUT CONCAT2E(initRGBTCtoTC,BPPOUT)
#define initRGBTCtoCubeOUT CONCAT2E(initRGBTCtoCube,BPPOUT)
#define initSimpleOUT CONCAT2E(initSimple,BPPOUT)
#define initRGBOUT CONCAT2E(initRGB,BPPOUT)
#define initOneRGBTableOUT CONCAT2E(initOneRGBTable,BPPOUT)
#define initOneRGBCubeTableOUT CONCAT2E(initOneRGBCubeTable,BPPOUT)

@@ -61,34 +57,8 @@ namespace rfb {
static bool nativeBigEndian = *(rdr::U8*)(&endianTest) != 1;
#endif

void initSimpleCMtoTCOUT (rdr::U8** tablep, const PixelFormat& inPF,
ColourMap* cm, const PixelFormat& outPF)
{
if (inPF.bpp != 8 && inPF.bigEndian != nativeBigEndian)
throw Exception("Internal error: inPF is not native endian");

int size = 1 << inPF.bpp;

delete [] *tablep;
*tablep = new rdr::U8[size * sizeof(OUTPIXEL)];
OUTPIXEL* table = (OUTPIXEL*)*tablep;

for (int i = 0; i < size; i++) {
int r,g,b;
cm->lookup(i,&r,&g,&b);

table[i] = ((((r * outPF.redMax + 32767) / 65535) << outPF.redShift) |
(((g * outPF.greenMax + 32767) / 65535) << outPF.greenShift) |
(((b * outPF.blueMax + 32767) / 65535) << outPF.blueShift));
#if (BPPOUT != 8)
if (outPF.bigEndian != nativeBigEndian)
table[i] = SWAPOUT (table[i]);
#endif
}
}

void initSimpleTCtoTCOUT (rdr::U8** tablep, const PixelFormat& inPF,
const PixelFormat& outPF)
void initSimpleOUT (rdr::U8** tablep, const PixelFormat& inPF,
const PixelFormat& outPF)
{
if (inPF.bpp != 8 && inPF.bigEndian != nativeBigEndian)
throw Exception("Internal error: inPF is not native endian");
@@ -118,55 +88,8 @@ void initSimpleTCtoTCOUT (rdr::U8** tablep, const PixelFormat& inPF,
}
}

void initSimpleCMtoCubeOUT (rdr::U8** tablep, const PixelFormat& inPF,
ColourMap* cm, ColourCube* cube)
{
if (inPF.bpp != 8 && inPF.bigEndian != nativeBigEndian)
throw Exception("Internal error: inPF is not native endian");

int size = 1 << inPF.bpp;

delete [] *tablep;
*tablep = new rdr::U8[size * sizeof(OUTPIXEL)];
OUTPIXEL* table = (OUTPIXEL*)*tablep;

for (int i = 0; i < size; i++) {
int r,g,b;
cm->lookup(i,&r,&g,&b);
r = (r * (cube->nRed-1) + 32767) / 65535;
g = (g * (cube->nGreen-1) + 32767) / 65535;
b = (b * (cube->nBlue-1) + 32767) / 65535;
table[i] = cube->lookup(r, g, b);
}
}

void initSimpleTCtoCubeOUT (rdr::U8** tablep, const PixelFormat& inPF,
ColourCube* cube)
{
if (inPF.bpp != 8 && inPF.bigEndian != nativeBigEndian)
throw Exception("Internal error: inPF is not native endian");

int size = 1 << inPF.bpp;

delete [] *tablep;
*tablep = new rdr::U8[size * sizeof(OUTPIXEL)];
OUTPIXEL* table = (OUTPIXEL*)*tablep;

for (int i = 0; i < size; i++) {
int r = (i >> inPF.redShift) & inPF.redMax;
int g = (i >> inPF.greenShift) & inPF.greenMax;
int b = (i >> inPF.blueShift) & inPF.blueMax;

r = (r * (cube->nRed-1) + inPF.redMax/2) / inPF.redMax;
g = (g * (cube->nGreen-1) + inPF.greenMax/2) / inPF.greenMax;
b = (b * (cube->nBlue-1) + inPF.blueMax/2) / inPF.blueMax;

table[i] = cube->lookup(r, g, b);
}
}

void initOneRGBTableOUT (OUTPIXEL* table, int inMax, int outMax,
int outShift, bool swap)
static void initOneRGBTableOUT (OUTPIXEL* table, int inMax, int outMax,
int outShift, bool swap)
{
int size = inMax + 1;

@@ -179,8 +102,8 @@ void initOneRGBTableOUT (OUTPIXEL* table, int inMax, int outMax,
}
}

void initRGBTCtoTCOUT (rdr::U8** tablep, const PixelFormat& inPF,
const PixelFormat& outPF)
void initRGBOUT (rdr::U8** tablep, const PixelFormat& inPF,
const PixelFormat& outPF)
{
if (inPF.bpp != 8 && inPF.bigEndian != nativeBigEndian)
throw Exception("Internal error: inPF is not native endian");
@@ -205,50 +128,8 @@ void initRGBTCtoTCOUT (rdr::U8** tablep, const PixelFormat& inPF,
}


void initOneRGBCubeTableOUT (OUTPIXEL* table, int inMax, int outMax,
int outMult)
{
int size = inMax + 1;

for (int i = 0; i < size; i++) {
table[i] = ((i * outMax + inMax / 2) / inMax) * outMult;
}
}

void initRGBTCtoCubeOUT (rdr::U8** tablep, const PixelFormat& inPF,
ColourCube* cube)
{
if (inPF.bpp != 8 && inPF.bigEndian != nativeBigEndian)
throw Exception("Internal error: inPF is not native endian");

int size = inPF.redMax + inPF.greenMax + inPF.blueMax + 3 + cube->size();

delete [] *tablep;
*tablep = new rdr::U8[size * sizeof(OUTPIXEL)];

OUTPIXEL* redTable = (OUTPIXEL*)*tablep;
OUTPIXEL* greenTable = redTable + inPF.redMax + 1;
OUTPIXEL* blueTable = greenTable + inPF.greenMax + 1;
OUTPIXEL* cubeTable = blueTable + inPF.blueMax + 1;

initOneRGBCubeTableOUT (redTable, inPF.redMax, cube->nRed-1,
cube->redMult());
initOneRGBCubeTableOUT (greenTable, inPF.greenMax, cube->nGreen-1,
cube->greenMult());
initOneRGBCubeTableOUT (blueTable, inPF.blueMax, cube->nBlue-1,
cube->blueMult());
for (int i = 0; i < cube->size(); i++) {
cubeTable[i] = cube->table[i];
}
}

#undef OUTPIXEL
#undef initSimpleCMtoTCOUT
#undef initSimpleTCtoTCOUT
#undef initSimpleCMtoCubeOUT
#undef initSimpleTCtoCubeOUT
#undef initRGBTCtoTCOUT
#undef initRGBTCtoCubeOUT
#undef initSimpleOUT
#undef initRGBOUT
#undef initOneRGBTableOUT
#undef initOneRGBCubeTableOUT
}

+ 0
- 33
common/rfb/transTempl.h View File

@@ -42,7 +42,6 @@
#define OUTPIXEL rdr::CONCAT2E(U,BPPOUT)
#define transSimpleINtoOUT CONCAT4E(transSimple,BPPIN,to,BPPOUT)
#define transRGBINtoOUT CONCAT4E(transRGB,BPPIN,to,BPPOUT)
#define transRGBCubeINtoOUT CONCAT4E(transRGBCube,BPPIN,to,BPPOUT)

#if (BPPIN <= 16)

@@ -111,41 +110,9 @@ void transRGBINtoOUT (void* table,
}
}

// transRGBCubeINtoOUT is similar to transRGBINtoOUT but also looks up the
// colour cube index in a fourth table to yield a pixel value.

void transRGBCubeINtoOUT (void* table,
const PixelFormat& inPF, const void* inPtr, int inStride,
const PixelFormat& outPF, void* outPtr,
int outStride, int width, int height)
{
OUTPIXEL* redTable = (OUTPIXEL*)table;
OUTPIXEL* greenTable = redTable + inPF.redMax + 1;
OUTPIXEL* blueTable = greenTable + inPF.greenMax + 1;
OUTPIXEL* cubeTable = blueTable + inPF.blueMax + 1;
INPIXEL* ip = (INPIXEL*)inPtr;
OUTPIXEL* op = (OUTPIXEL*)outPtr;
int inExtra = inStride - width;
int outExtra = outStride - width;

while (height > 0) {
OUTPIXEL* opEndOfRow = op + width;
while (op < opEndOfRow) {
*op++ = cubeTable[(redTable [(*ip >> inPF.redShift) & inPF.redMax] +
greenTable[(*ip >> inPF.greenShift) & inPF.greenMax] +
blueTable [(*ip >> inPF.blueShift) & inPF.blueMax])];
ip++;
}
ip += inExtra;
op += outExtra;
height--;
}
}

#endif

#undef INPIXEL
#undef OUTPIXEL
#undef transSimpleINtoOUT
#undef transRGBINtoOUT
#undef transRGBCubeINtoOUT

+ 1
- 1
tests/pixelconv.cxx View File

@@ -101,7 +101,7 @@ static void doTests(rfb::PixelFormat &dstpf, rfb::PixelFormat &srcpf)
if (srcpf.isLittleEndian()) {
delete pt;
pt = new rfb::PixelTransformer;
pt->init(srcpf, NULL, dstpf);
pt->init(srcpf, dstpf);
}

printf("%s,%s", srcb, dstb);

+ 1
- 2
unix/x0vncserver/XPixelBuffer.cxx View File

@@ -29,7 +29,7 @@
using namespace rfb;

XPixelBuffer::XPixelBuffer(Display *dpy, ImageFactory &factory,
const Rect &rect, ColourMap* cm)
const Rect &rect)
: FullFramePixelBuffer(),
m_poller(0),
m_dpy(dpy),
@@ -54,7 +54,6 @@ XPixelBuffer::XPixelBuffer(Display *dpy, ImageFactory &factory,
width_ = rect.width();
height_ = rect.height();
data = (rdr::U8 *)m_image->xim->data;
colourmap = cm;

// Calculate the distance in pixels between two subsequent scan
// lines of the framebuffer. This may differ from image width.

+ 1
- 2
unix/x0vncserver/XPixelBuffer.h View File

@@ -37,8 +37,7 @@ using namespace rfb;
class XPixelBuffer : public FullFramePixelBuffer
{
public:
XPixelBuffer(Display *dpy, ImageFactory &factory,
const Rect &rect, ColourMap* cm);
XPixelBuffer(Display *dpy, ImageFactory &factory, const Rect &rect);
virtual ~XPixelBuffer();

// Provide access to the underlying Image object.

+ 2
- 16
unix/x0vncserver/x0vncserver.cxx View File

@@ -135,7 +135,7 @@ private:
};


class XDesktop : public SDesktop, public ColourMap, public TXGlobalEventHandler
class XDesktop : public SDesktop, public TXGlobalEventHandler
{
public:
XDesktop(Display* dpy_, Geometry *geometry_)
@@ -199,7 +199,7 @@ public:
ImageFactory factory((bool)useShm, (bool)useOverlay);

// Create pixel buffer and provide it to the server object.
pb = new XPixelBuffer(dpy, factory, geometry->getRect(), this);
pb = new XPixelBuffer(dpy, factory, geometry->getRect());
vlog.info("Allocated %s", pb->getImage()->classDesc());

server = (VNCServerST *)vs;
@@ -269,20 +269,6 @@ public:
return Point(pb->width(), pb->height());
}

// -=- ColourMap callbacks
virtual void lookup(int index, int* r, int* g, int* b) {
XColor xc;
xc.pixel = index;
if (index < DisplayCells(dpy,DefaultScreen(dpy))) {
XQueryColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), &xc);
} else {
xc.red = xc.green = xc.blue = 0;
}
*r = xc.red;
*g = xc.green;
*b = xc.blue;
}

// -=- TXGlobalEventHandler interface

virtual bool handleGlobalEvent(XEvent* ev) {

+ 27
- 109
unix/xserver/hw/vnc/XserverDesktop.cc View File

@@ -51,7 +51,6 @@ extern "C" {

extern char *display;

#include "colormapst.h"
#ifdef RANDR
#include "randrstr.h"
#endif
@@ -143,14 +142,11 @@ XserverDesktop::XserverDesktop(ScreenPtr pScreen_,
: pScreen(pScreen_),
server(0), httpServer(0),
listener(listener_), httpListener(httpListener_),
cmap(0), deferredUpdateTimerSet(false),
deferredUpdateTimerSet(false),
grabbing(false), ignoreHooks_(false), directFbptr(true),
queryConnectId(0)
{
format = pf;
colourmap = this;

serverReset(pScreen);

server = new VNCServerST(name, this);
setFramebuffer(pScreen->width, pScreen->height, fbptr, stride);
@@ -171,24 +167,6 @@ XserverDesktop::~XserverDesktop()
delete server;
}

void XserverDesktop::serverReset(ScreenPtr pScreen_)
{
pScreen = pScreen_;
int i;
pointer retval;

#if XORG >= 17
#define dixLookupResource dixLookupResourceByType
#endif
i = dixLookupResource(&retval, pScreen->defColormap, RT_COLORMAP, NullClient,
DixReadAccess);

/* Handle suspicious conditions */
assert(i == Success);

cmap = (ColormapPtr) retval;
}

void XserverDesktop::blockUpdates()
{
server->blockUpdates();
@@ -379,44 +357,6 @@ XserverDesktop::queryConnection(network::Socket* sock,
return rfb::VNCServerST::PENDING;
}


void XserverDesktop::setColormap(ColormapPtr cmap_)
{
if (cmap != cmap_) {
cmap = cmap_;
setColourMapEntries(0, 0);
}
}

void XserverDesktop::setColourMapEntries(ColormapPtr pColormap, int ndef,
xColorItem* pdef)
{
if (cmap != pColormap || ndef <= 0) return;

unsigned int first = pdef[0].pixel;
unsigned int n = 1;

for (int i = 1; i < ndef; i++) {
if (first + n == pdef[i].pixel) {
n++;
} else {
setColourMapEntries(first, n);
first = pdef[i].pixel;
n = 1;
}
}
setColourMapEntries(first, n);
}

void XserverDesktop::setColourMapEntries(int firstColour, int nColours)
{
try {
server->setColourMapEntries(firstColour, nColours);
} catch (rdr::Exception& e) {
vlog.error("XserverDesktop::setColourMapEntries: %s",e.str());
}
}

void XserverDesktop::bell()
{
server->bell();
@@ -469,7 +409,7 @@ void XserverDesktop::setCursor(CursorPtr cursor)
rgb[1] = (*in >> 8) & 0xff;
rgb[2] = (*in >> 0) & 0xff;

getPF().bufferFromRGB(out, rgb, 1, this);
getPF().bufferFromRGB(out, rgb, 1);

if (((*in >> 24) & 0xff) > 127)
cursorMask[y * rfbMaskBytesPerRow + x/8] |= 0x80>>(x%8);
@@ -480,42 +420,42 @@ void XserverDesktop::setCursor(CursorPtr cursor)
}
} else {
#endif
xColorItem fg, bg;
fg.red = cursor->foreRed;
fg.green = cursor->foreGreen;
fg.blue = cursor->foreBlue;
FakeAllocColor(cmap, &fg);
bg.red = cursor->backRed;
bg.green = cursor->backGreen;
bg.blue = cursor->backBlue;
FakeAllocColor(cmap, &bg);
FakeFreeColor(cmap, fg.pixel);
FakeFreeColor(cmap, bg.pixel);
rdr::U8 rgb[3];
rdr::U8 fg[4], bg[4];

rdr::U8* buffer;

rgb[0] = cursor->foreRed;
rgb[1] = cursor->foreGreen;
rgb[2] = cursor->foreBlue;
getPF().bufferFromRGB(fg, rgb, 1);

rgb[0] = cursor->backRed;
rgb[1] = cursor->backGreen;
rgb[2] = cursor->backBlue;
getPF().bufferFromRGB(bg, rgb, 1);

int xMaskBytesPerRow = BitmapBytePad(w);

buffer = cursorData;

for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
rdr::U8 *pixel;
int byte = y * xMaskBytesPerRow + x / 8;
#if (BITMAP_BIT_ORDER == MSBFirst)
int bit = 7 - x % 8;
#else
int bit = x % 8;
#endif
switch (getPF().bpp) {
case 8:
((rdr::U8*)cursorData)[y * w + x]
= (cursor->bits->source[byte] & (1 << bit)) ? fg.pixel : bg.pixel;
break;
case 16:
((rdr::U16*)cursorData)[y * w + x]
= (cursor->bits->source[byte] & (1 << bit)) ? fg.pixel : bg.pixel;
break;
case 32:
((rdr::U32*)cursorData)[y * w + x]
= (cursor->bits->source[byte] & (1 << bit)) ? fg.pixel : bg.pixel;
break;
}

if (cursor->bits->source[byte] & (1 << bit))
pixel = fg;
else
pixel = bg;

memcpy(buffer, pixel, getPF().bpp/8);
buffer += getPF().bpp/8;
}
}

@@ -1109,28 +1049,6 @@ int XserverDesktop::getStride() const
return stride_;
}

void XserverDesktop::lookup(int index, int* r, int* g, int* b)
{
if ((cmap->c_class | DynamicClass) == DirectColor) {
VisualPtr v = cmap->pVisual;
*r = cmap->red [(index & v->redMask ) >> v->offsetRed ].co.local.red;
*g = cmap->green[(index & v->greenMask) >> v->offsetGreen].co.local.green;
*b = cmap->blue [(index & v->blueMask ) >> v->offsetBlue ].co.local.blue;
} else {
EntryPtr pent;
pent = (EntryPtr)&cmap->red[index];
if (pent->fShared) {
*r = pent->co.shco.red->color;
*g = pent->co.shco.green->color;
*b = pent->co.shco.blue->color;
} else {
*r = pent->co.local.red;
*g = pent->co.local.green;
*b = pent->co.local.blue;
}
}
}

void XserverDesktop::keyEvent(rdr::U32 keysym, bool down)
{
if (down)

+ 1
- 9
unix/xserver/hw/vnc/XserverDesktop.h View File

@@ -54,7 +54,7 @@ namespace rfb {
namespace network { class TcpListener; class Socket; }

class XserverDesktop : public rfb::SDesktop, public rfb::FullFramePixelBuffer,
public rfb::ColourMap, public rdr::Substitutor,
public rdr::Substitutor,
public rfb::VNCServerST::QueryConnectionHandler {
public:

@@ -65,13 +65,10 @@ public:
virtual ~XserverDesktop();

// methods called from X server code
void serverReset(ScreenPtr pScreen);
void blockUpdates();
void unblockUpdates();
void setFramebuffer(int w, int h, void* fbptr, int stride);
void refreshScreenLayout();
void setColormap(ColormapPtr cmap);
void setColourMapEntries(ColormapPtr pColormap, int ndef, xColorItem* pdef);
void bell();
void serverCutText(const char* str, int len);
void setDesktopName(const char* name);
@@ -114,9 +111,6 @@ public:
virtual void grabRegion(const rfb::Region& r);
virtual int getStride() const;

// rfb::ColourMap callbacks
virtual void lookup(int index, int* r, int* g, int* b);

// rdr::Substitutor callback
virtual char* substitute(const char* varName);

@@ -126,7 +120,6 @@ public:
char** reason);

private:
void setColourMapEntries(int firstColour, int nColours);
rfb::ScreenSet computeScreenLayout();
#ifdef RANDR
RRModePtr findRandRMode(RROutputPtr output, int width, int height);
@@ -138,7 +131,6 @@ private:
rfb::HTTPServer* httpServer;
network::TcpListener* listener;
network::TcpListener* httpListener;
ColormapPtr cmap;
int stride_;
bool deferredUpdateTimerSet;
bool grabbing;

+ 4
- 5
unix/xserver/hw/vnc/vncExtInit.cc View File

@@ -168,8 +168,10 @@ static PixelFormat vncGetPixelFormat(ScreenPtr pScreen)

trueColour = (vis->c_class == TrueColor);

if (!trueColour && bpp != 8)
throw rfb::Exception("X server uses unsupported visual");
if (!trueColour) {
fprintf(stderr,"pseudocolour not supported");
abort();
}

redShift = ffs(vis->redMask) - 1;
greenShift = ffs(vis->greenMask) - 1;
@@ -266,9 +268,6 @@ void vncExtensionInit()
desktop[scr]->addClient(sock, false);
vlog.info("added inetd sock");
}

} else {
desktop[scr]->serverReset(screenInfo.screens[scr]);
}

vncHooksInit(screenInfo.screens[scr], desktop[scr]);

+ 0
- 38
unix/xserver/hw/vnc/vncHooks.cc View File

@@ -75,8 +75,6 @@ typedef struct {
#if XORG < 110
RestoreAreasProcPtr RestoreAreas;
#endif
InstallColormapProcPtr InstallColormap;
StoreColorsProcPtr StoreColors;
DisplayCursorProcPtr DisplayCursor;
ScreenBlockHandlerProcPtr BlockHandler;
#ifdef RENDER
@@ -132,9 +130,6 @@ static void vncHooksClearToBackground(WindowPtr pWin, int x, int y, int w,
#if XORG < 110
static RegionPtr vncHooksRestoreAreas(WindowPtr pWin, RegionPtr prgnExposed);
#endif
static void vncHooksInstallColormap(ColormapPtr pColormap);
static void vncHooksStoreColors(ColormapPtr pColormap, int ndef,
xColorItem* pdef);
static Bool vncHooksDisplayCursor(
#if XORG >= 16
DeviceIntPtr pDev,
@@ -289,8 +284,6 @@ Bool vncHooksInit(ScreenPtr pScreen, XserverDesktop* desktop)
#if XORG < 110
vncHooksScreen->RestoreAreas = pScreen->RestoreAreas;
#endif
vncHooksScreen->InstallColormap = pScreen->InstallColormap;
vncHooksScreen->StoreColors = pScreen->StoreColors;
vncHooksScreen->DisplayCursor = pScreen->DisplayCursor;
vncHooksScreen->BlockHandler = pScreen->BlockHandler;
#ifdef RENDER
@@ -318,8 +311,6 @@ Bool vncHooksInit(ScreenPtr pScreen, XserverDesktop* desktop)
#if XORG < 110
pScreen->RestoreAreas = vncHooksRestoreAreas;
#endif
pScreen->InstallColormap = vncHooksInstallColormap;
pScreen->StoreColors = vncHooksStoreColors;
pScreen->DisplayCursor = vncHooksDisplayCursor;
pScreen->BlockHandler = vncHooksBlockHandler;
#ifdef RENDER
@@ -381,8 +372,6 @@ static Bool vncHooksCloseScreen(ScreenPtr pScreen_)
#if XORG < 110
pScreen->RestoreAreas = vncHooksScreen->RestoreAreas;
#endif
pScreen->InstallColormap = vncHooksScreen->InstallColormap;
pScreen->StoreColors = vncHooksScreen->StoreColors;
pScreen->DisplayCursor = vncHooksScreen->DisplayCursor;
pScreen->BlockHandler = vncHooksScreen->BlockHandler;
#ifdef RENDER
@@ -512,33 +501,6 @@ static RegionPtr vncHooksRestoreAreas(WindowPtr pWin, RegionPtr pRegion)
}
#endif

// InstallColormap - get the new colormap

static void vncHooksInstallColormap(ColormapPtr pColormap)
{
SCREEN_UNWRAP(pColormap->pScreen, InstallColormap);

(*pScreen->InstallColormap) (pColormap);

vncHooksScreen->desktop->setColormap(pColormap);

SCREEN_REWRAP(InstallColormap);
}

// StoreColors - get the colormap changes

static void vncHooksStoreColors(ColormapPtr pColormap, int ndef,
xColorItem* pdef)
{
SCREEN_UNWRAP(pColormap->pScreen, StoreColors);

(*pScreen->StoreColors) (pColormap, ndef, pdef);

vncHooksScreen->desktop->setColourMapEntries(pColormap, ndef, pdef);

SCREEN_REWRAP(StoreColors);
}

// DisplayCursor - get the cursor shape

static Bool vncHooksDisplayCursor(

+ 4
- 3
vncviewer/CConn.cxx View File

@@ -65,8 +65,9 @@ static const PixelFormat verylowColourPF(8, 3,false, true,
// 64 colours (2 bits per component)
static const PixelFormat lowColourPF(8, 6, false, true,
3, 3, 3, 4, 2, 0);
// 256 colours (palette)
static const PixelFormat mediumColourPF(8, 8, false, false);
// 256 colours (2-3 bits per component)
static const PixelFormat mediumColourPF(8, 8, false, true,
7, 7, 3, 5, 2, 0);

CConn::CConn(const char* vncServerName, network::Socket* socket=NULL)
: serverHost(0), serverPort(0), desktop(NULL),
@@ -342,7 +343,7 @@ void CConn::framebufferUpdateEnd()

void CConn::setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs)
{
desktop->setColourMapEntries(firstColour, nColours, rgbs);
vlog.error("Invalid SetColourMapEntries from server!");
}

void CConn::bell()

+ 0
- 6
vncviewer/DesktopWindow.cxx View File

@@ -216,12 +216,6 @@ void DesktopWindow::setName(const char *name)
}


void DesktopWindow::setColourMapEntries(int firstColour, int nColours,
rdr::U16* rgbs)
{
viewport->setColourMapEntries(firstColour, nColours, rgbs);
}

void DesktopWindow::fillRect(const rfb::Rect& r, rfb::Pixel pix) {
viewport->fillRect(r, pix);
}

+ 0
- 2
vncviewer/DesktopWindow.h View File

@@ -50,8 +50,6 @@ public:
// Methods forwarded from CConn
void setName(const char *name);

void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs);

void fillRect(const rfb::Rect& r, rfb::Pixel pix);
void imageRect(const rfb::Rect& r, void* pixels);
void copyRect(const rfb::Rect& r, int srcX, int srcY);

+ 4
- 36
vncviewer/Viewport.cxx View File

@@ -87,7 +87,7 @@ enum { ID_EXIT, ID_FULLSCREEN, ID_RESIZE,

Viewport::Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_)
: Fl_Widget(0, 0, w, h), cc(cc_), frameBuffer(NULL), pixelTrans(NULL),
colourMapChange(false), lastPointerPos(0, 0), lastButtonMask(0),
lastPointerPos(0, 0), lastButtonMask(0),
cursor(NULL), menuCtrlKey(false), menuAltKey(false)
{
// FLTK STR #2599 must be fixed for proper dead keys support
@@ -183,11 +183,11 @@ void Viewport::setServerPF(const rfb::PixelFormat& pf)
PixelFormat fake_pf(pf.bpp, pf.depth, nativeBigEndian, pf.trueColour,
pf.redMax, pf.greenMax, pf.blueMax,
pf.redShift, pf.greenShift, pf.blueShift);
pixelTrans->init(fake_pf, &colourMap, getPreferredPF());
pixelTrans->init(fake_pf, getPreferredPF());
return;
}

pixelTrans->init(pf, &colourMap, getPreferredPF());
pixelTrans->init(pf, getPreferredPF());
}


@@ -197,21 +197,6 @@ const rfb::PixelFormat &Viewport::getPreferredPF()
}


// setColourMapEntries() changes some of the entries in the colourmap.
// We don't actually act on these changes until we need to. This is
// because recalculating the internal translation table can be expensive.
// This also solves the issue of silly servers sending colour maps in
// multiple pieces.
void Viewport::setColourMapEntries(int firstColour, int nColours,
rdr::U16* rgbs)
{
for (int i = 0; i < nColours; i++)
colourMap.set(firstColour+i, rgbs[i*3], rgbs[i*3+1], rgbs[i*3+2]);

colourMapChange = true;
}


// Copy the areas of the framebuffer that have been changed (damaged)
// to the displayed window.

@@ -230,8 +215,6 @@ void Viewport::updateWindow()
void Viewport::fillRect(const rfb::Rect& r, rfb::Pixel pix) {
if (pixelTrans) {
rfb::Pixel pix2;
if (colourMapChange)
commitColourMap();
pixelTrans->translatePixels(&pix, &pix2, 1);
pix = pix2;
}
@@ -242,8 +225,6 @@ void Viewport::fillRect(const rfb::Rect& r, rfb::Pixel pix) {

void Viewport::imageRect(const rfb::Rect& r, void* pixels) {
if (pixelTrans) {
if (colourMapChange)
commitColourMap();
pixelTrans->translateRect(pixels, r.width(),
rfb::Rect(0, 0, r.width(), r.height()),
frameBuffer->data, frameBuffer->getStride(),
@@ -327,7 +308,7 @@ void Viewport::setCursor(int width, int height, const Point& hotspot,
m_width = (width+7)/8;
for (int y = 0;y < height;y++) {
for (int x = 0;x < width;x++) {
pf->rgbFromBuffer(o, i, 1, &colourMap);
pf->rgbFromBuffer(o, i, 1);

if (m[(m_width*y)+(x/8)] & 0x80>>(x%8))
o[3] = 255;
@@ -529,19 +510,6 @@ void Viewport::handleUpdateTimeout(void *data)
}


void Viewport::commitColourMap()
{
if (pixelTrans == NULL)
return;
if (!colourMapChange)
return;

colourMapChange = false;

pixelTrans->setColourMapEntries(0, 0);
}


void Viewport::handleClipboardChange(int source, void *data)
{
Viewport *self = (Viewport *)data;

+ 0
- 9
vncviewer/Viewport.h View File

@@ -26,7 +26,6 @@

#include <rfb/Region.h>
#include <rfb/Pixel.h>
#include <rfb/ColourMap.h>

class Fl_Menu_Button;
class Fl_RGB_Image;
@@ -52,8 +51,6 @@ public:

// Methods forwarded from CConn

void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs);

void fillRect(const rfb::Rect& r, rfb::Pixel pix);
void imageRect(const rfb::Rect& r, void* pixels);
void copyRect(const rfb::Rect& r, int srcX, int srcY);
@@ -77,8 +74,6 @@ private:

static void handleUpdateTimeout(void *data);

void commitColourMap();

static void handleClipboardChange(int source, void *data);

void handlePointerEvent(const rfb::Point& pos, int buttonMask);
@@ -98,11 +93,7 @@ private:
CConn* cc;

PlatformPixelBuffer* frameBuffer;

rfb::PixelTransformer *pixelTrans;
rfb::SimpleColourMap colourMap;
bool colourMapChange;

rfb::Region damage;

rfb::Point lastPointerPos;

+ 1
- 1
vncviewer/Win32PixelBuffer.cxx View File

@@ -40,7 +40,7 @@ static rfb::LogWriter vlog("PlatformPixelBuffer");
PlatformPixelBuffer::PlatformPixelBuffer(int width, int height) :
FullFramePixelBuffer(rfb::PixelFormat(32, 24, false, true,
255, 255, 255, 16, 8, 0),
width, height, NULL, NULL),
width, height, NULL),
bitmap(NULL)
{
BITMAPINFOHEADER bih;

+ 1
- 1
vncviewer/X11PixelBuffer.cxx View File

@@ -94,7 +94,7 @@ static PixelFormat display_pf()
}

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

+ 18
- 72
win/rfb_win32/DIBSectionBuffer.cxx View File

@@ -31,13 +31,11 @@ static LogWriter vlog("DIBSectionBuffer");
DIBSectionBuffer::DIBSectionBuffer(HWND window_)
: bitmap(0), window(window_), device(0) {
memset(&format, 0, sizeof(format));
memset(palette, 0, sizeof(palette));
}

DIBSectionBuffer::DIBSectionBuffer(HDC device_)
: bitmap(0), window(0), device(device_) {
memset(&format, 0, sizeof(format));
memset(palette, 0, sizeof(palette));
}

DIBSectionBuffer::~DIBSectionBuffer() {
@@ -51,19 +49,10 @@ void DIBSectionBuffer::setPF(const PixelFormat& pf) {
vlog.debug("pixel format unchanged by setPF()");
return;
}
if (!pf.trueColour)
throw rfb::Exception("palette format not supported");
format = pf;
recreateBuffer();
if ((pf.bpp <= 8) && pf.trueColour) {
vlog.info("creating %d-bit TrueColour palette", pf.depth);
for (int i=0; i < (1<<(pf.depth)); i++) {
rdr::U16 r, g, b;
pf.rgbFromPixel(i, NULL, &r, &g, &b);
palette[i].r = r;
palette[i].g = g;
palette[i].b = b;
}
refreshPalette();
}
}

void DIBSectionBuffer::setSize(int w, int h) {
@@ -77,20 +66,6 @@ void DIBSectionBuffer::setSize(int w, int h) {
}


// * copyPaletteToDIB MUST NEVER be called on a truecolour DIB! *

void copyPaletteToDIB(Colour palette[256], HDC wndDC, HBITMAP dib) {
BitmapDC dibDC(wndDC, dib);
RGBQUAD rgb[256];
for (unsigned int i=0;i<256;i++) {
rgb[i].rgbRed = palette[i].r >> 8;
rgb[i].rgbGreen = palette[i].g >> 8;
rgb[i].rgbBlue = palette[i].b >> 8;
}
if (!SetDIBColorTable(dibDC, 0, 256, (RGBQUAD*) rgb))
throw rdr::SystemException("unable to SetDIBColorTable", GetLastError());
}

inline void initMaxAndShift(DWORD mask, int* max, int* shift) {
for ((*shift) = 0; (mask & 1) == 0; (*shift)++) mask >>= 1;
(*max) = (rdr::U16)mask;
@@ -103,9 +78,7 @@ void DIBSectionBuffer::recreateBuffer() {
if (width_ && height_ && (format.depth != 0)) {
BitmapInfo bi;
memset(&bi, 0, sizeof(bi));
// *** wrong?
UINT iUsage = format.trueColour ? DIB_RGB_COLORS : DIB_PAL_COLORS;
// ***
UINT iUsage = DIB_RGB_COLORS;
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biBitCount = format.bpp;
bi.bmiHeader.biSizeImage = (format.bpp / 8) * width_ * height_;
@@ -140,15 +113,11 @@ void DIBSectionBuffer::recreateBuffer() {

// Copy the contents across
if (device) {
if (format.bpp <= 8)
copyPaletteToDIB(palette, device, new_bitmap);
BitmapDC src_dev(device, bitmap);
BitmapDC dest_dev(device, new_bitmap);
BitBlt(dest_dev, 0, 0, width_, height_, src_dev, 0, 0, SRCCOPY);
} else {
WindowDC wndDC(window);
if (format.bpp <= 8)
copyPaletteToDIB(palette, wndDC, new_bitmap);
BitmapDC src_dev(wndDC, bitmap);
BitmapDC dest_dev(wndDC, new_bitmap);
BitBlt(dest_dev, 0, 0, width_, height_, src_dev, 0, 0, SRCCOPY);
@@ -164,7 +133,6 @@ void DIBSectionBuffer::recreateBuffer() {

if (new_bitmap) {
int bpp, depth;
bool trueColour;
int redMax, greenMax, blueMax;
int redShift, greenShift, blueShift;

@@ -189,46 +157,24 @@ void DIBSectionBuffer::recreateBuffer() {

// Calculate the PixelFormat for the DIB
bpp = depth = ds.dsBm.bmBitsPixel;
trueColour = format.trueColour || format.bpp > 8;

if (trueColour) {
// Get the truecolour format used by the DIBSection
initMaxAndShift(ds.dsBitfields[0], &redMax, &redShift);
initMaxAndShift(ds.dsBitfields[1], &greenMax, &greenShift);
initMaxAndShift(ds.dsBitfields[2], &blueMax, &blueShift);

// Calculate the effective depth
depth = 0;
Pixel bits = ds.dsBitfields[0] | ds.dsBitfields[1] | ds.dsBitfields[2];
while (bits) {
depth++;
bits = bits >> 1;
}
if (depth > bpp)
throw Exception("Bad DIBSection format (depth exceeds bpp)");

// Get the truecolour format used by the DIBSection
initMaxAndShift(ds.dsBitfields[0], &redMax, &redShift);
initMaxAndShift(ds.dsBitfields[1], &greenMax, &greenShift);
initMaxAndShift(ds.dsBitfields[2], &blueMax, &blueShift);

// Calculate the effective depth
depth = 0;
Pixel bits = ds.dsBitfields[0] | ds.dsBitfields[1] | ds.dsBitfields[2];
while (bits) {
depth++;
bits = bits >> 1;
}
if (depth > bpp)
throw Exception("Bad DIBSection format (depth exceeds bpp)");

format = PixelFormat(bpp, depth, false, trueColour,
format = PixelFormat(bpp, depth, false, true,
redMax, greenMax, blueMax,
redShift, greenShift, blueShift);

if (!trueColour) {
// Set the DIBSection's palette
refreshPalette();
}
}
}

void DIBSectionBuffer::refreshPalette() {
if (format.bpp > 8) {
vlog.error("refresh palette called for truecolor DIB");
return;
}
vlog.debug("refreshing palette");
if (device)
copyPaletteToDIB(palette, device, bitmap);
else
copyPaletteToDIB(palette, WindowDC(window), bitmap);
}



+ 1
- 20
win/rfb_win32/DIBSectionBuffer.h View File

@@ -28,7 +28,6 @@
#include <windows.h>
#include <rfb/PixelBuffer.h>
#include <rfb/Region.h>
#include <rfb/ColourMap.h>
#include <rfb/Exception.h>

namespace rfb {
@@ -39,7 +38,7 @@ namespace rfb {
// -=- DIBSectionBuffer
//

class DIBSectionBuffer : public FullFramePixelBuffer, ColourMap {
class DIBSectionBuffer : public FullFramePixelBuffer {
public:
DIBSectionBuffer(HWND window);
DIBSectionBuffer(HDC device);
@@ -50,29 +49,11 @@ namespace rfb {

virtual int getStride() const {return stride;}

virtual ColourMap* getColourMap() const {return (ColourMap*)this;}

// - ColourMap interface
virtual void lookup(int index, int* r, int *g, int* b) {
*r = palette[index].r;
*g = palette[index].g;
*b = palette[index].b;
}
// Custom colourmap interface
void setColour(int index, int r, int g, int b) {
palette[index].r = r;
palette[index].g = g;
palette[index].b = b;
}
void refreshPalette();

// *** virtual void copyRect(const Rect &dest, const Point &move_by_delta);
public:
HBITMAP bitmap;
protected:
void recreateBuffer();
Colour palette[256];
int stride;
HWND window;
HDC device;

+ 2
- 48
win/rfb_win32/DeviceFrameBuffer.cxx View File

@@ -79,10 +79,6 @@ DeviceFrameBuffer::DeviceFrameBuffer(HDC deviceContext, const Rect& wRect)

// Configure the cursor buffer
cursorBm.setPF(format);

// Set up a palette if required
if (!format.trueColour)
updateColourMap();
}

DeviceFrameBuffer::~DeviceFrameBuffer() {
@@ -134,37 +130,6 @@ DeviceFrameBuffer::grabRegion(const Region &rgn) {
}


void copyDevicePaletteToDIB(HDC dc, DIBSectionBuffer* dib) {
// - Fetch the system palette for the framebuffer
PALETTEENTRY syspalette[256];
UINT entries = ::GetSystemPaletteEntries(dc, 0, 256, syspalette);

if (entries == 0) {
vlog.info("resorting to standard 16 color palette");
for (unsigned int i=0;i<256;i++) {
int v = (i%16) >= 8 ? 127 : 255;
syspalette[i].peRed = i & 1 ? v : 0;
syspalette[i].peGreen = i & 2 ? v : 0;
syspalette[i].peBlue = i & 4 ? v : 0;
}
} else {
vlog.info("framebuffer has %u palette entries", entries);
}

// - Update the bitmap's stored copy of the palette
for (unsigned int i=0;i<256;i++) {
int r, g, b;
r = (syspalette[i].peRed << 8) + 0x80;
g = (syspalette[i].peGreen << 8) + 0x80;
b = (syspalette[i].peBlue << 8) + 0x80;
dib->setColour(i, r, g, b);
}

// - Update the DIB section to use the palette
dib->refreshPalette();
}


void DeviceFrameBuffer::setCursor(HCURSOR hCursor, VNCServer* server)
{
// - If hCursor is null then there is no cursor - clear the old one
@@ -211,10 +176,6 @@ void DeviceFrameBuffer::setCursor(HCURSOR hCursor, VNCServer* server)
// Configure the cursor bitmap
cursorBm.setSize(cursor.width(), cursor.height());

// Copy the palette into it if required
if (format.bpp <= 8)
copyDevicePaletteToDIB(device, &cursorBm);

// Draw the cursor into the bitmap
BitmapDC dc(device, cursorBm.bitmap);
if (!DrawIconEx(dc, 0, 0, hCursor, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT))
@@ -231,7 +192,7 @@ void DeviceFrameBuffer::setCursor(HCURSOR hCursor, VNCServer* server)

bool doOutline = false;
if (!iconInfo.hbmColor) {
Pixel xorColour = format.pixelFromRGB((rdr::U16)0, (rdr::U16)0, (rdr::U16)0, cursorBm.getColourMap());
Pixel xorColour = format.pixelFromRGB((rdr::U16)0, (rdr::U16)0, (rdr::U16)0);
for (int y = 0; y < cursor.height(); y++) {
for (int x = 0; x < cursor.width(); x++) {
int byte = y * maskInfo.bmWidthBytes + x / 8;
@@ -269,7 +230,7 @@ void DeviceFrameBuffer::setCursor(HCURSOR hCursor, VNCServer* server)
if (doOutline) {
vlog.debug("drawing cursor outline!");
memcpy(cursor.data, cursorBm.data, cursor.dataLen());
cursor.drawOutline(format.pixelFromRGB((rdr::U16)0xffff, (rdr::U16)0xffff, (rdr::U16)0xffff, cursorBm.getColourMap()));
cursor.drawOutline(format.pixelFromRGB((rdr::U16)0xffff, (rdr::U16)0xffff, (rdr::U16)0xffff));
memcpy(cursorBm.data, cursor.data, cursor.dataLen());
}

@@ -279,10 +240,3 @@ void DeviceFrameBuffer::setCursor(HCURSOR hCursor, VNCServer* server)
vlog.error("%s", e.str());
}
}


void
DeviceFrameBuffer::updateColourMap() {
if (!format.trueColour)
copyDevicePaletteToDIB(device, this);
}

+ 0
- 1
win/rfb_win32/DeviceFrameBuffer.h View File

@@ -79,7 +79,6 @@ namespace rfb {
// - DeviceFrameBuffer specific methods

void setCursor(HCURSOR c, VNCServer* server);
void updateColourMap();

// Set whether grabRect should ignore errors or throw exceptions
// Only set this if you are sure you'll capture the errors some other way!

+ 0
- 6
win/rfb_win32/SDisplay.cxx View File

@@ -350,12 +350,6 @@ SDisplay::notifyDisplayEvent(WMMonitor::Notifier::DisplayEventType evt) {
vlog.debug("desktop format changed");
recreatePixelBuffer();
break;
case WMMonitor::Notifier::DisplayColourMapChanged:
vlog.debug("desktop colormap changed");
pb->updateColourMap();
if (server)
server->setColourMapEntries();
break;
default:
vlog.error("unknown display event received");
}

+ 0
- 6
win/rfb_win32/WMNotifier.cxx View File

@@ -45,12 +45,6 @@ WMMonitor::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {
notifier->notifyDisplayEvent(Notifier::DisplaySizeChanged);
notifier->notifyDisplayEvent(Notifier::DisplayPixelFormatChanged);
}
break;
case WM_SYSCOLORCHANGE:
case WM_PALETTECHANGED:
if (notifier) {
notifier->notifyDisplayEvent(Notifier::DisplayColourMapChanged);
}
break;
};
return MsgWindow::processMessage(msg, wParam, lParam);

+ 1
- 1
win/rfb_win32/WMNotifier.h View File

@@ -44,7 +44,7 @@ namespace rfb {

class Notifier {
public:
typedef enum {DisplaySizeChanged, DisplayColourMapChanged,
typedef enum {DisplaySizeChanged,
DisplayPixelFormatChanged} DisplayEventType;
virtual void notifyDisplayEvent(DisplayEventType evt) = 0;
};

Loading…
Cancel
Save