Browse Source

Merge branches 'vmware-cursor-position' and 'vmware-cursor-position-vncviewer' of https://github.com/lhchavez/tigervnc

tags/v1.11.90
Pierre Ossman 3 years ago
parent
commit
41bf43b0b9

+ 5
- 2
common/rfb/CConnection.cxx View File

@@ -43,8 +43,8 @@ static LogWriter vlog("CConnection");

CConnection::CConnection()
: csecurity(0),
supportsLocalCursor(false), supportsDesktopResize(false),
supportsLEDState(false),
supportsLocalCursor(false), supportsCursorPosition(false),
supportsDesktopResize(false), supportsLEDState(false),
is(0), os(0), reader_(0), writer_(0),
shared(false),
state_(RFBSTATE_UNINITIALISED),
@@ -805,6 +805,9 @@ void CConnection::updateEncodings()
encodings.push_back(pseudoEncodingCursor);
encodings.push_back(pseudoEncodingXCursor);
}
if (supportsCursorPosition) {
encodings.push_back(pseudoEncodingVMwareCursorPosition);
}
if (supportsDesktopResize) {
encodings.push_back(pseudoEncodingDesktopSize);
encodings.push_back(pseudoEncodingExtendedDesktopSize);

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

@@ -239,6 +239,7 @@ namespace rfb {
// Optional capabilities that a subclass is expected to set to true
// if supported
bool supportsLocalCursor;
bool supportsCursorPosition;
bool supportsDesktopResize;
bool supportsLEDState;


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

@@ -52,6 +52,7 @@ namespace rfb {
const ScreenSet& layout);
virtual void setCursor(int width, int height, const Point& hotspot,
const rdr::U8* data) = 0;
virtual void setCursorPos(const Point& pos) = 0;
virtual void setPixelFormat(const PixelFormat& pf);
virtual void setName(const char* name);
virtual void fence(rdr::U32 flags, unsigned len, const char data[]);

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

@@ -165,6 +165,10 @@ bool CMsgReader::readMsg()
case pseudoEncodingVMwareCursor:
ret = readSetVMwareCursor(dataRect.width(), dataRect.height(), dataRect.tl);
break;
case pseudoEncodingVMwareCursorPosition:
handler->setCursorPos(dataRect.tl);
ret = true;
break;
case pseudoEncodingDesktopName:
ret = readSetDesktopName(dataRect.tl.x, dataRect.tl.y,
dataRect.width(), dataRect.height());

+ 13
- 1
common/rfb/ClientParams.cxx View File

@@ -30,7 +30,7 @@ ClientParams::ClientParams()
compressLevel(2), qualityLevel(-1), fineQualityLevel(-1),
subsampling(subsampleUndefined),
width_(0), height_(0), name_(0),
ledState_(ledUnknown)
cursorPos_(0, 0), ledState_(ledUnknown)
{
setName("");

@@ -85,6 +85,11 @@ void ClientParams::setCursor(const Cursor& other)
cursor_ = new Cursor(other);
}

void ClientParams::setCursorPos(const Point& pos)
{
cursorPos_ = pos;
}

bool ClientParams::supportsEncoding(rdr::S32 encoding) const
{
return encodings_.count(encoding) != 0;
@@ -182,6 +187,13 @@ bool ClientParams::supportsLocalCursor() const
return false;
}

bool ClientParams::supportsCursorPosition() const
{
if (supportsEncoding(pseudoEncodingVMwareCursorPosition))
return true;
return false;
}

bool ClientParams::supportsDesktopSize() const
{
if (supportsEncoding(pseudoEncodingExtendedDesktopSize))

+ 5
- 0
common/rfb/ClientParams.h View File

@@ -77,6 +77,9 @@ namespace rfb {
const Cursor& cursor() const { return *cursor_; }
void setCursor(const Cursor& cursor);

const Point& cursorPos() const { return cursorPos_; }
void setCursorPos(const Point& pos);

bool supportsEncoding(rdr::S32 encoding) const;

void setEncodings(int nEncodings, const rdr::S32* encodings);
@@ -91,6 +94,7 @@ namespace rfb {
// Wrappers to check for functionality rather than specific
// encodings
bool supportsLocalCursor() const;
bool supportsCursorPosition() const;
bool supportsDesktopSize() const;
bool supportsLEDState() const;
bool supportsFence() const;
@@ -110,6 +114,7 @@ namespace rfb {
PixelFormat pf_;
char* name_;
Cursor* cursor_;
Point cursorPos_;
std::set<rdr::S32> encodings_;
unsigned int ledState_;
rdr::U32 clipFlags;

+ 40
- 1
common/rfb/SMsgWriter.cxx View File

@@ -42,7 +42,8 @@ SMsgWriter::SMsgWriter(ClientParams* client_, rdr::OutStream* os_)
: client(client_), os(os_),
nRectsInUpdate(0), nRectsInHeader(0),
needSetDesktopName(false), needCursor(false),
needLEDState(false), needQEMUKeyEvent(false)
needCursorPos(false), needLEDState(false),
needQEMUKeyEvent(false)
{
}

@@ -269,6 +270,14 @@ void SMsgWriter::writeCursor()
needCursor = true;
}

void SMsgWriter::writeCursorPos()
{
if (!client->supportsEncoding(pseudoEncodingVMwareCursorPosition))
throw Exception("Client does not support cursor position");

needCursorPos = true;
}

void SMsgWriter::writeLEDState()
{
if (!client->supportsEncoding(pseudoEncodingLEDState) &&
@@ -294,6 +303,8 @@ bool SMsgWriter::needFakeUpdate()
return true;
if (needCursor)
return true;
if (needCursorPos)
return true;
if (needLEDState)
return true;
if (needQEMUKeyEvent)
@@ -340,6 +351,8 @@ void SMsgWriter::writeFramebufferUpdateStart(int nRects)
nRects++;
if (needCursor)
nRects++;
if (needCursorPos)
nRects++;
if (needLEDState)
nRects++;
if (needQEMUKeyEvent)
@@ -455,6 +468,18 @@ void SMsgWriter::writePseudoRects()
needCursor = false;
}

if (needCursorPos) {
const Point& cursorPos = client->cursorPos();

if (client->supportsEncoding(pseudoEncodingVMwareCursorPosition)) {
writeSetVMwareCursorPositionRect(cursorPos.x, cursorPos.y);
} else {
throw Exception("Client does not support cursor position");
}

needCursorPos = false;
}

if (needSetDesktopName) {
writeSetDesktopNameRect(client->name());
needSetDesktopName = false;
@@ -650,6 +675,20 @@ void SMsgWriter::writeSetVMwareCursorRect(int width, int height,
os->writeBytes(data, width*height*4);
}

void SMsgWriter::writeSetVMwareCursorPositionRect(int hotspotX, int hotspotY)
{
if (!client->supportsEncoding(pseudoEncodingVMwareCursorPosition))
throw Exception("Client does not support cursor position");
if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
throw Exception("SMsgWriter::writeSetVMwareCursorRect: nRects out of sync");

os->writeS16(hotspotX);
os->writeS16(hotspotY);
os->writeU16(0);
os->writeU16(0);
os->writeU32(pseudoEncodingVMwareCursorPosition);
}

void SMsgWriter::writeLEDStateRect(rdr::U8 state)
{
if (!client->supportsEncoding(pseudoEncodingLEDState) &&

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

@@ -83,6 +83,9 @@ namespace rfb {
// immediately.
void writeCursor();

// Notifies the client that the cursor pointer was moved by the server.
void writeCursorPos();

// Same for LED state message
void writeLEDState();

@@ -141,6 +144,7 @@ namespace rfb {
void writeSetVMwareCursorRect(int width, int height,
int hotspotX, int hotspotY,
const rdr::U8* data);
void writeSetVMwareCursorPositionRect(int hotspotX, int hotspotY);
void writeLEDStateRect(rdr::U8 state);
void writeQEMUKeyEventRect();

@@ -152,6 +156,7 @@ namespace rfb {

bool needSetDesktopName;
bool needCursor;
bool needCursorPos;
bool needLEDState;
bool needQEMUKeyEvent;


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

@@ -370,6 +370,15 @@ void VNCSConnectionST::renderedCursorChange()
}
}

// cursorPositionChange() is called whenever the cursor has changed position by
// the server. If the client supports being informed about these changes then
// it will arrange for the new cursor position to be sent to the client.

void VNCSConnectionST::cursorPositionChange()
{
setCursorPos();
}

// needRenderedCursor() returns true if this client needs the server-side
// rendered cursor. This may be because it does not support local cursor or
// because the current cursor position has not been set by this client.
@@ -1123,6 +1132,21 @@ void VNCSConnectionST::setCursor()
writer()->writeCursor();
}

// setCursorPos() is called whenever the cursor has changed position by the
// server. If the client supports being informed about these changes then it
// will arrange for the new cursor position to be sent to the client.

void VNCSConnectionST::setCursorPos()
{
if (state() != RFBSTATE_NORMAL)
return;

if (client.supportsCursorPosition()) {
client.setCursorPos(server->getCursorPos());
writer()->writeCursorPos();
}
}

void VNCSConnectionST::setDesktopName(const char *name)
{
client.setName(name);

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

@@ -93,6 +93,11 @@ namespace rfb {
// cursor.
void renderedCursorChange();

// cursorPositionChange() is called whenever the cursor has changed position by
// the server. If the client supports being informed about these changes then
// it will arrange for the new cursor position to be sent to the client.
void cursorPositionChange();

// needRenderedCursor() returns true if this client needs the server-side
// rendered cursor. This may be because it does not support local cursor
// or because the current cursor position has not been set by this client.
@@ -155,6 +160,7 @@ namespace rfb {

void screenLayoutChange(rdr::U16 reason);
void setCursor();
void setCursorPos();
void setDesktopName(const char *name);
void setLEDState(unsigned int state);


+ 4
- 2
common/rfb/VNCServer.h View File

@@ -97,8 +97,10 @@ namespace rfb {
virtual void setCursor(int width, int height, const Point& hotspot,
const rdr::U8* cursorData) = 0;

// setCursorPos() tells the server the current position of the cursor.
virtual void setCursorPos(const Point& p) = 0;
// setCursorPos() tells the server the current position of the cursor, and
// whether the server initiated that change (e.g. through another X11
// client calling XWarpPointer()).
virtual void setCursorPos(const Point& p, bool warped) = 0;

// setName() tells the server what desktop title to supply to clients
virtual void setName(const char* name) = 0;

+ 5
- 2
common/rfb/VNCServerST.cxx View File

@@ -429,14 +429,17 @@ void VNCServerST::setCursor(int width, int height, const Point& newHotspot,
}
}

void VNCServerST::setCursorPos(const Point& pos)
void VNCServerST::setCursorPos(const Point& pos, bool warped)
{
if (!cursorPos.equals(pos)) {
cursorPos = pos;
renderedCursorInvalid = true;
std::list<VNCSConnectionST*>::iterator ci;
for (ci = clients.begin(); ci != clients.end(); ci++)
for (ci = clients.begin(); ci != clients.end(); ci++) {
(*ci)->renderedCursorChange();
if (warped)
(*ci)->cursorPositionChange();
}
}
}


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

@@ -99,7 +99,7 @@ namespace rfb {
virtual void add_copied(const Region &dest, const Point &delta);
virtual void setCursor(int width, int height, const Point& hotspot,
const rdr::U8* data);
virtual void setCursorPos(const Point& p);
virtual void setCursorPos(const Point& p, bool warped);
virtual void setName(const char* name_);
virtual void setLEDState(unsigned state);


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

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

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

// UltraVNC-specific

+ 5
- 0
tests/perf/decperf.cxx View File

@@ -66,6 +66,7 @@ public:
virtual void initDone();
virtual void setPixelFormat(const rfb::PixelFormat& pf);
virtual void setCursor(int, int, const rfb::Point&, const rdr::U8*);
virtual void setCursorPos(const rfb::Point&);
virtual void framebufferUpdateStart();
virtual void framebufferUpdateEnd();
virtual void setColourMapEntries(int, int, rdr::U16*);
@@ -144,6 +145,10 @@ void CConn::setCursor(int, int, const rfb::Point&, const rdr::U8*)
{
}

void CConn::setCursorPos(const rfb::Point&)
{
}

void CConn::framebufferUpdateStart()
{
CConnection::framebufferUpdateStart();

+ 5
- 0
tests/perf/encperf.cxx View File

@@ -95,6 +95,7 @@ public:
virtual void initDone() {};
virtual void resizeFramebuffer();
virtual void setCursor(int, int, const rfb::Point&, const rdr::U8*);
virtual void setCursorPos(const rfb::Point&);
virtual void framebufferUpdateStart();
virtual void framebufferUpdateEnd();
virtual bool dataRect(const rfb::Rect&, int);
@@ -216,6 +217,10 @@ void CConn::setCursor(int, int, const rfb::Point&, const rdr::U8*)
{
}

void CConn::setCursorPos(const rfb::Point&)
{
}

void CConn::framebufferUpdateStart()
{
CConnection::framebufferUpdateStart();

+ 1
- 1
unix/x0vncserver/XDesktop.cxx View File

@@ -217,7 +217,7 @@ void XDesktop::poll() {
&x, &y, &wx, &wy, &mask);
x -= geometry->offsetLeft();
y -= geometry->offsetTop();
server->setCursorPos(rfb::Point(x, y));
server->setCursorPos(rfb::Point(x, y), false);
}
}


+ 10
- 1
unix/xserver/hw/vnc/XserverDesktop.cc View File

@@ -261,6 +261,15 @@ void XserverDesktop::setCursor(int width, int height, int hotX, int hotY,
delete [] cursorData;
}

void XserverDesktop::setCursorPos(int x, int y, bool warped)
{
try {
server->setCursorPos(Point(x, y), warped);
} catch (rdr::Exception& e) {
vlog.error("XserverDesktop::setCursorPos: %s",e.str());
}
}

void XserverDesktop::add_changed(const rfb::Region &region)
{
try {
@@ -377,7 +386,7 @@ void XserverDesktop::blockHandler(int* timeout)
if (oldCursorPos.x != cursorX || oldCursorPos.y != cursorY) {
oldCursorPos.x = cursorX;
oldCursorPos.y = cursorY;
server->setCursorPos(oldCursorPos);
server->setCursorPos(oldCursorPos, false);
}

// Trigger timers and check when the next will expire

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

@@ -67,6 +67,7 @@ public:
void setDesktopName(const char* name);
void setCursor(int width, int height, int hotX, int hotY,
const unsigned char *rgbaData);
void setCursorPos(int x, int y, bool warped);
void add_changed(const rfb::Region &region);
void add_copied(const rfb::Region &dest, const rfb::Point &delta);
void handleSocketEvent(int fd, bool read, bool write);

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

@@ -400,6 +400,11 @@ void vncSetCursor(int width, int height, int hotX, int hotY,
desktop[scr]->setCursor(width, height, hotX, hotY, rgbaData);
}

void vncSetCursorPos(int scrIdx, int x, int y)
{
desktop[scrIdx]->setCursorPos(x, y, true);
}

void vncPreScreenResize(int scrIdx)
{
// We need to prevent the RFB core from accessing the framebuffer

+ 1
- 0
unix/xserver/hw/vnc/vncExtInit.h View File

@@ -81,6 +81,7 @@ void vncAddCopied(int scrIdx, int nRects,

void vncSetCursor(int width, int height, int hotX, int hotY,
const unsigned char *rgbaData);
void vncSetCursorPos(int scrIdx, int x, int y);

void vncPreScreenResize(int scrIdx);
void vncPostScreenResize(int scrIdx, int success, int width, int height);

+ 26
- 0
unix/xserver/hw/vnc/vncHooks.c View File

@@ -62,6 +62,9 @@ typedef struct _vncHooksScreenRec {
CopyWindowProcPtr CopyWindow;
ClearToBackgroundProcPtr ClearToBackground;
DisplayCursorProcPtr DisplayCursor;
#if XORG >= 119
CursorWarpedToProcPtr CursorWarpedTo;
#endif
ScreenBlockHandlerProcPtr BlockHandler;
#ifdef RENDER
CompositeProcPtr Composite;
@@ -113,6 +116,12 @@ static void vncHooksClearToBackground(WindowPtr pWin, int x, int y, int w,
int h, Bool generateExposures);
static Bool vncHooksDisplayCursor(DeviceIntPtr pDev,
ScreenPtr pScreen, CursorPtr cursor);
#if XORG >= 119
static void vncHooksCursorWarpedTo(DeviceIntPtr pDev,
ScreenPtr pScreen_, ClientPtr pClient,
WindowPtr pWindow, SpritePtr pSprite,
int x, int y);
#endif
#if XORG <= 118
static void vncHooksBlockHandler(ScreenPtr pScreen, void * pTimeout,
void * pReadmask);
@@ -271,6 +280,9 @@ int vncHooksInit(int scrIdx)
wrap(vncHooksScreen, pScreen, CopyWindow, vncHooksCopyWindow);
wrap(vncHooksScreen, pScreen, ClearToBackground, vncHooksClearToBackground);
wrap(vncHooksScreen, pScreen, DisplayCursor, vncHooksDisplayCursor);
#if XORG >= 119
wrap(vncHooksScreen, pScreen, CursorWarpedTo, vncHooksCursorWarpedTo);
#endif
wrap(vncHooksScreen, pScreen, BlockHandler, vncHooksBlockHandler);
#ifdef RENDER
ps = GetPictureScreenIfSet(pScreen);
@@ -631,6 +643,20 @@ out:
return ret;
}

// CursorWarpedTo - notify that the cursor was warped

#if XORG >= 119
static void vncHooksCursorWarpedTo(DeviceIntPtr pDev,
ScreenPtr pScreen_, ClientPtr pClient,
WindowPtr pWindow, SpritePtr pSprite,
int x, int y)
{
SCREEN_PROLOGUE(pScreen_, CursorWarpedTo);
vncSetCursorPos(pScreen->myNum, x, y);
SCREEN_EPILOGUE(CursorWarpedTo);
}
#endif

// BlockHandler - ignore any changes during the block handler - it's likely
// these are just drawing the cursor.


+ 6
- 0
vncviewer/CConn.cxx View File

@@ -84,6 +84,7 @@ CConn::CConn(const char* vncServerName, network::Socket* socket=NULL)
sock = socket;

supportsLocalCursor = true;
supportsCursorPosition = true;
supportsDesktopResize = true;
supportsLEDState = false;

@@ -430,6 +431,11 @@ void CConn::setCursor(int width, int height, const Point& hotspot,
desktop->setCursor(width, height, hotspot, data);
}

void CConn::setCursorPos(const Point& pos)
{
desktop->setCursorPos(pos);
}

void CConn::fence(rdr::U32 flags, unsigned len, const char data[])
{
CMsgHandler::fence(flags, len, data);

+ 1
- 0
vncviewer/CConn.h View File

@@ -63,6 +63,7 @@ public:

void setCursor(int width, int height, const rfb::Point& hotspot,
const rdr::U8* data);
void setCursorPos(const rfb::Point& pos);

void fence(rdr::U32 flags, unsigned len, const char data[]);


+ 32
- 0
vncviewer/DesktopWindow.cxx View File

@@ -51,6 +51,7 @@

#ifdef __APPLE__
#include "cocoa.h"
#include <Carbon/Carbon.h>
#endif

#define EDGE_SCROLL_SIZE 32
@@ -186,6 +187,14 @@ DesktopWindow::DesktopWindow(int w, int h, const char *name,

// Show hint about menu key
Fl::add_timeout(0.5, menuOverlay, this);

// By default we get a slight delay when we warp the pointer, something
// we don't want or we'll get jerky movement
#ifdef __APPLE__
CGEventSourceRef event = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
CGEventSourceSetLocalEventsSuppressionInterval(event, 0);
CFRelease(event);
#endif
}


@@ -322,6 +331,29 @@ void DesktopWindow::setCursor(int width, int height,
}


void DesktopWindow::setCursorPos(const rfb::Point& pos)
{
if (!mouseGrabbed) {
// Do nothing if we do not have the mouse captured.
return;
}
#if defined(WIN32)
SetCursorPos(pos.x + x_root() + viewport->x(),
pos.y + y_root() + viewport->y());
#elif defined(__APPLE__)
CGPoint new_pos;
new_pos.x = pos.x + x_root() + viewport->x();
new_pos.y = pos.y + y_root() + viewport->y();
CGWarpMouseCursorPosition(new_pos);
#else // Assume this is Xlib
Window rootwindow = DefaultRootWindow(fl_display);
XWarpPointer(fl_display, rootwindow, rootwindow, 0, 0, 0, 0,
pos.x + x_root() + viewport->x(),
pos.y + y_root() + viewport->y());
#endif
}


void DesktopWindow::show()
{
Fl_Window::show();

+ 3
- 0
vncviewer/DesktopWindow.h View File

@@ -66,6 +66,9 @@ public:
void setCursor(int width, int height, const rfb::Point& hotspot,
const rdr::U8* data);

// Server-provided cursor position
void setCursorPos(const rfb::Point& pos);

// Change client LED state
void setLEDState(unsigned int state);


+ 1
- 1
win/rfb_win32/SDisplay.cxx View File

@@ -417,7 +417,7 @@ SDisplay::processEvent(HANDLE event) {
// Update the cursor position
// NB: First translate from Screen coordinates to Desktop
Point desktopPos = info.position.translate(screenRect.tl.negate());
server->setCursorPos(desktopPos);
server->setCursorPos(desktopPos, false);

old_cursor = info;
}

Loading…
Cancel
Save