Browse Source

Merge branch 'vmware' of https://github.com/CendioOssman/tigervnc

tags/v1.9.90
Pierre Ossman 5 years ago
parent
commit
650e63ebb0

+ 4
- 1
common/rfb/CConnection.cxx View File



if (supportsLocalCursor) { if (supportsLocalCursor) {
encodings.push_back(pseudoEncodingCursorWithAlpha); encodings.push_back(pseudoEncodingCursorWithAlpha);
encodings.push_back(pseudoEncodingVMwareCursor);
encodings.push_back(pseudoEncodingCursor); encodings.push_back(pseudoEncodingCursor);
encodings.push_back(pseudoEncodingXCursor); encodings.push_back(pseudoEncodingXCursor);
} }
encodings.push_back(pseudoEncodingDesktopSize); encodings.push_back(pseudoEncodingDesktopSize);
encodings.push_back(pseudoEncodingExtendedDesktopSize); encodings.push_back(pseudoEncodingExtendedDesktopSize);
} }
if (supportsLEDState)
if (supportsLEDState) {
encodings.push_back(pseudoEncodingLEDState); encodings.push_back(pseudoEncodingLEDState);
encodings.push_back(pseudoEncodingVMwareLEDState);
}


encodings.push_back(pseudoEncodingDesktopName); encodings.push_back(pseudoEncodingDesktopName);
encodings.push_back(pseudoEncodingLastRect); encodings.push_back(pseudoEncodingLastRect);

+ 107
- 0
common/rfb/CMsgReader.cxx View File

case pseudoEncodingCursorWithAlpha: case pseudoEncodingCursorWithAlpha:
readSetCursorWithAlpha(w, h, Point(x,y)); readSetCursorWithAlpha(w, h, Point(x,y));
break; break;
case pseudoEncodingVMwareCursor:
readSetVMwareCursor(w, h, Point(x,y));
break;
case pseudoEncodingDesktopName: case pseudoEncodingDesktopName:
readSetDesktopName(x, y, w, h); readSetDesktopName(x, y, w, h);
break; break;
break; break;
case pseudoEncodingLEDState: case pseudoEncodingLEDState:
readLEDState(); readLEDState();
break;
case pseudoEncodingVMwareLEDState:
readVMwareLEDState();
break;
case pseudoEncodingQEMUKeyEvent: case pseudoEncodingQEMUKeyEvent:
handler->supportsQEMUKeyEvent(); handler->supportsQEMUKeyEvent();
break; break;
pb.getBuffer(pb.getRect(), &stride)); pb.getBuffer(pb.getRect(), &stride));
} }


void CMsgReader::readSetVMwareCursor(int width, int height, const Point& hotspot)
{
if (width > maxCursorSize || height > maxCursorSize)
throw Exception("Too big cursor");

rdr::U8 type;

type = is->readU8();
is->skip(1);

if (type == 0) {
int len = width * height * (handler->server.pf().bpp/8);
rdr::U8Array andMask(len);
rdr::U8Array xorMask(len);

rdr::U8Array data(width*height*4);

rdr::U8* andIn;
rdr::U8* xorIn;
rdr::U8* out;
int Bpp;

is->readBytes(andMask.buf, len);
is->readBytes(xorMask.buf, len);

andIn = andMask.buf;
xorIn = xorMask.buf;
out = data.buf;
Bpp = handler->server.pf().bpp/8;
for (int y = 0;y < height;y++) {
for (int x = 0;x < width;x++) {
Pixel andPixel, xorPixel;

andPixel = handler->server.pf().pixelFromBuffer(andIn);
xorPixel = handler->server.pf().pixelFromBuffer(xorIn);
andIn += Bpp;
xorIn += Bpp;

if (andPixel == 0) {
rdr::U8 r, g, b;

// Opaque pixel

handler->server.pf().rgbFromPixel(xorPixel, &r, &g, &b);
*out++ = r;
*out++ = g;
*out++ = b;
*out++ = 0xff;
} else if (xorPixel == 0) {
// Fully transparent pixel
*out++ = 0;
*out++ = 0;
*out++ = 0;
*out++ = 0;
} else if (andPixel == xorPixel) {
// Inverted pixel

// We don't really support this, so just turn the pixel black
// FIXME: Do an outline like WinVNC does?
*out++ = 0;
*out++ = 0;
*out++ = 0;
*out++ = 0xff;
} else {
// Partially transparent/inverted pixel

// We _really_ can't handle this, just make it black
*out++ = 0;
*out++ = 0;
*out++ = 0;
*out++ = 0xff;
}
}
}

handler->setCursor(width, height, hotspot, data.buf);
} else if (type == 1) {
rdr::U8Array data(width*height*4);

// FIXME: Is alpha premultiplied?
is->readBytes(data.buf, width*height*4);

handler->setCursor(width, height, hotspot, data.buf);
} else {
throw Exception("Unknown cursor type");
}
}

void CMsgReader::readSetDesktopName(int x, int y, int w, int h) void CMsgReader::readSetDesktopName(int x, int y, int w, int h)
{ {
char* name = is->readString(); char* name = is->readString();


handler->setLEDState(state); handler->setLEDState(state);
} }

void CMsgReader::readVMwareLEDState()
{
rdr::U32 state;

state = is->readU32();

// As luck has it, this extension uses the same bit definitions,
// so no conversion required

handler->setLEDState(state);
}

+ 2
- 0
common/rfb/CMsgReader.h View File

void readSetXCursor(int width, int height, const Point& hotspot); void readSetXCursor(int width, int height, const Point& hotspot);
void readSetCursor(int width, int height, const Point& hotspot); void readSetCursor(int width, int height, const Point& hotspot);
void readSetCursorWithAlpha(int width, int height, const Point& hotspot); void readSetCursorWithAlpha(int width, int height, const Point& hotspot);
void readSetVMwareCursor(int width, int height, const Point& hotspot);
void readSetDesktopName(int x, int y, int w, int h); void readSetDesktopName(int x, int y, int w, int h);
void readExtendedDesktopSize(int x, int y, int w, int h); void readExtendedDesktopSize(int x, int y, int w, int h);
void readLEDState(); void readLEDState();
void readVMwareLEDState();


CMsgHandler* handler; CMsgHandler* handler;
rdr::InStream* is; rdr::InStream* is;

+ 4
- 0
common/rfb/ClientParams.cxx View File

{ {
if (supportsEncoding(pseudoEncodingCursorWithAlpha)) if (supportsEncoding(pseudoEncodingCursorWithAlpha))
return true; return true;
if (supportsEncoding(pseudoEncodingVMwareCursor))
return true;
if (supportsEncoding(pseudoEncodingCursor)) if (supportsEncoding(pseudoEncodingCursor))
return true; return true;
if (supportsEncoding(pseudoEncodingXCursor)) if (supportsEncoding(pseudoEncodingXCursor))
{ {
if (supportsEncoding(pseudoEncodingLEDState)) if (supportsEncoding(pseudoEncodingLEDState))
return true; return true;
if (supportsEncoding(pseudoEncodingVMwareLEDState))
return true;
return false; return false;
} }



+ 39
- 5
common/rfb/SMsgWriter.cxx View File

{ {
if (!client->supportsEncoding(pseudoEncodingCursor) && if (!client->supportsEncoding(pseudoEncodingCursor) &&
!client->supportsEncoding(pseudoEncodingXCursor) && !client->supportsEncoding(pseudoEncodingXCursor) &&
!client->supportsEncoding(pseudoEncodingCursorWithAlpha))
!client->supportsEncoding(pseudoEncodingCursorWithAlpha) &&
!client->supportsEncoding(pseudoEncodingVMwareCursor))
throw Exception("Client does not support local cursor"); throw Exception("Client does not support local cursor");


needCursor = true; needCursor = true;


void SMsgWriter::writeLEDState() void SMsgWriter::writeLEDState()
{ {
if (!client->supportsEncoding(pseudoEncodingLEDState))
if (!client->supportsEncoding(pseudoEncodingLEDState) &&
!client->supportsEncoding(pseudoEncodingVMwareLEDState))
throw Exception("Client does not support LED state"); throw Exception("Client does not support LED state");
if (client->ledState() == ledUnknown) if (client->ledState() == ledUnknown)
throw Exception("Server has not specified LED state"); throw Exception("Server has not specified LED state");
writeSetCursorWithAlphaRect(cursor.width(), cursor.height(), writeSetCursorWithAlphaRect(cursor.width(), cursor.height(),
cursor.hotspot().x, cursor.hotspot().y, cursor.hotspot().x, cursor.hotspot().y,
cursor.getBuffer()); cursor.getBuffer());
} else if (client->supportsEncoding(pseudoEncodingVMwareCursor)) {
writeSetVMwareCursorRect(cursor.width(), cursor.height(),
cursor.hotspot().x, cursor.hotspot().y,
cursor.getBuffer());
} else if (client->supportsEncoding(pseudoEncodingCursor)) { } else if (client->supportsEncoding(pseudoEncodingCursor)) {
rdr::U8Array data(cursor.width()*cursor.height() * (client->pf().bpp/8)); rdr::U8Array data(cursor.width()*cursor.height() * (client->pf().bpp/8));
rdr::U8Array mask(cursor.getMask()); rdr::U8Array mask(cursor.getMask());
} }
} }


void SMsgWriter::writeSetVMwareCursorRect(int width, int height,
int hotspotX, int hotspotY,
const rdr::U8* data)
{
if (!client->supportsEncoding(pseudoEncodingVMwareCursor))
throw Exception("Client does not support local cursors");
if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
throw Exception("SMsgWriter::writeSetVMwareCursorRect: nRects out of sync");

os->writeS16(hotspotX);
os->writeS16(hotspotY);
os->writeU16(width);
os->writeU16(height);
os->writeU32(pseudoEncodingVMwareCursor);

os->writeU8(1); // Alpha cursor
os->pad(1);

// FIXME: Should alpha be premultiplied?
os->writeBytes(data, width*height*4);
}

void SMsgWriter::writeLEDStateRect(rdr::U8 state) void SMsgWriter::writeLEDStateRect(rdr::U8 state)
{ {
if (!client->supportsEncoding(pseudoEncodingLEDState))
if (!client->supportsEncoding(pseudoEncodingLEDState) &&
!client->supportsEncoding(pseudoEncodingVMwareLEDState))
throw Exception("Client does not support LED state updates"); throw Exception("Client does not support LED state updates");
if (client->ledState() == ledUnknown) if (client->ledState() == ledUnknown)
throw Exception("Server does not support LED state updates"); throw Exception("Server does not support LED state updates");
os->writeS16(0); os->writeS16(0);
os->writeU16(0); os->writeU16(0);
os->writeU16(0); os->writeU16(0);
os->writeU32(pseudoEncodingLEDState);
os->writeU8(state);
if (client->supportsEncoding(pseudoEncodingLEDState)) {
os->writeU32(pseudoEncodingLEDState);
os->writeU8(state);
} else {
os->writeU32(pseudoEncodingVMwareLEDState);
os->writeU32(state);
}
} }


void SMsgWriter::writeQEMUKeyEventRect() void SMsgWriter::writeQEMUKeyEventRect()

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

void writeSetCursorWithAlphaRect(int width, int height, void writeSetCursorWithAlphaRect(int width, int height,
int hotspotX, int hotspotY, int hotspotX, int hotspotY,
const rdr::U8* data); const rdr::U8* data);
void writeSetVMwareCursorRect(int width, int height,
int hotspotX, int hotspotY,
const rdr::U8* data);
void writeLEDStateRect(rdr::U8 state); void writeLEDStateRect(rdr::U8 state);
void writeQEMUKeyEventRect(); void writeQEMUKeyEventRect();



+ 4
- 0
common/rfb/encodings.h View File

const int pseudoEncodingSubsamp8X = -764; const int pseudoEncodingSubsamp8X = -764;
const int pseudoEncodingSubsamp16X = -763; const int pseudoEncodingSubsamp16X = -763;


// VMware-specific
const int pseudoEncodingVMwareCursor = 0x574d5664;
const int pseudoEncodingVMwareLEDState = 0x574d5668;

int encodingNum(const char* name); int encodingNum(const char* name);
const char* encodingName(int num); const char* encodingName(int num);
} }

Loading…
Cancel
Save