mirror of
https://github.com/kasmtech/KasmVNC.git
synced 2024-11-21 15:43:28 +01:00
Add support for notifying clients about pointer movements
This change adds support for the VMware Mouse Position pseudo-encoding[1], which is used to notify VNC clients when X11 clients call `XWarpPointer()`[2]. This function is called by SDL (and other similar libraries) when they detect that the server does not support native relative motion, like some RFB clients. With this, RFB clients can choose to adjust the local cursor position under certain circumstances to match what the server has set. For instance, if pointer lock has been enabled on the client's machine and the cursor is not being drawn locally, the local position of the cursor is irrelevant, so the RFB client can use what the server sends as the canonical absolute position of the cursor. This ultimately enables the possibility of games (especially FPS games) to behave how users expect (if the clients implement the corresponding change). Part of: #619 1: https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#vmware-cursor-position-pseudo-encoding 2: https://tronche.com/gui/x/xlib/input/XWarpPointer.html 3: https://hg.libsdl.org/SDL/file/28e3b60e2131/src/events/SDL_mouse.c#l804
This commit is contained in:
parent
d8caab699d
commit
25b8e64adb
@ -36,6 +36,7 @@ ConnParams::ConnParams()
|
|||||||
width(0), height(0), useCopyRect(false),
|
width(0), height(0), useCopyRect(false),
|
||||||
supportsLocalCursor(false), supportsLocalXCursor(false),
|
supportsLocalCursor(false), supportsLocalXCursor(false),
|
||||||
supportsLocalCursorWithAlpha(false),
|
supportsLocalCursorWithAlpha(false),
|
||||||
|
supportsCursorPosition(false),
|
||||||
supportsDesktopResize(false), supportsExtendedDesktopSize(false),
|
supportsDesktopResize(false), supportsExtendedDesktopSize(false),
|
||||||
supportsDesktopRename(false), supportsLastRect(false),
|
supportsDesktopRename(false), supportsLastRect(false),
|
||||||
supportsLEDState(false), supportsQEMUKeyEvent(false),
|
supportsLEDState(false), supportsQEMUKeyEvent(false),
|
||||||
@ -43,7 +44,7 @@ ConnParams::ConnParams()
|
|||||||
supportsSetDesktopSize(false), supportsFence(false),
|
supportsSetDesktopSize(false), supportsFence(false),
|
||||||
supportsContinuousUpdates(false),
|
supportsContinuousUpdates(false),
|
||||||
compressLevel(2), qualityLevel(-1), fineQualityLevel(-1),
|
compressLevel(2), qualityLevel(-1), fineQualityLevel(-1),
|
||||||
subsampling(subsampleUndefined), name_(0), verStrPos(0),
|
subsampling(subsampleUndefined), name_(0), cursorPos_(0, 0), verStrPos(0),
|
||||||
ledState_(ledUnknown), shandler(NULL)
|
ledState_(ledUnknown), shandler(NULL)
|
||||||
{
|
{
|
||||||
memset(kasmPassed, 0, KASM_NUM_SETTINGS);
|
memset(kasmPassed, 0, KASM_NUM_SETTINGS);
|
||||||
@ -101,6 +102,11 @@ void ConnParams::setCursor(const Cursor& other)
|
|||||||
cursor_ = new Cursor(other);
|
cursor_ = new Cursor(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConnParams::setCursorPos(const Point& pos)
|
||||||
|
{
|
||||||
|
cursorPos_ = pos;
|
||||||
|
}
|
||||||
|
|
||||||
bool ConnParams::supportsEncoding(rdr::S32 encoding) const
|
bool ConnParams::supportsEncoding(rdr::S32 encoding) const
|
||||||
{
|
{
|
||||||
return encodings_.count(encoding) != 0;
|
return encodings_.count(encoding) != 0;
|
||||||
@ -147,6 +153,9 @@ void ConnParams::setEncodings(int nEncodings, const rdr::S32* encodings)
|
|||||||
case pseudoEncodingExtendedDesktopSize:
|
case pseudoEncodingExtendedDesktopSize:
|
||||||
supportsExtendedDesktopSize = true;
|
supportsExtendedDesktopSize = true;
|
||||||
break;
|
break;
|
||||||
|
case pseudoEncodingVMwareCursorPosition:
|
||||||
|
supportsCursorPosition = true;
|
||||||
|
break;
|
||||||
case pseudoEncodingDesktopName:
|
case pseudoEncodingDesktopName:
|
||||||
supportsDesktopRename = true;
|
supportsDesktopRename = true;
|
||||||
break;
|
break;
|
||||||
|
@ -84,6 +84,9 @@ namespace rfb {
|
|||||||
const Cursor& cursor() const { return *cursor_; }
|
const Cursor& cursor() const { return *cursor_; }
|
||||||
void setCursor(const Cursor& cursor);
|
void setCursor(const Cursor& cursor);
|
||||||
|
|
||||||
|
const Point& cursorPos() const { return cursorPos_; }
|
||||||
|
void setCursorPos(const Point& pos);
|
||||||
|
|
||||||
bool supportsEncoding(rdr::S32 encoding) const;
|
bool supportsEncoding(rdr::S32 encoding) const;
|
||||||
|
|
||||||
void setEncodings(int nEncodings, const rdr::S32* encodings);
|
void setEncodings(int nEncodings, const rdr::S32* encodings);
|
||||||
@ -96,6 +99,7 @@ namespace rfb {
|
|||||||
bool supportsLocalCursor;
|
bool supportsLocalCursor;
|
||||||
bool supportsLocalXCursor;
|
bool supportsLocalXCursor;
|
||||||
bool supportsLocalCursorWithAlpha;
|
bool supportsLocalCursorWithAlpha;
|
||||||
|
bool supportsCursorPosition;
|
||||||
bool supportsDesktopResize;
|
bool supportsDesktopResize;
|
||||||
bool supportsExtendedDesktopSize;
|
bool supportsExtendedDesktopSize;
|
||||||
bool supportsDesktopRename;
|
bool supportsDesktopRename;
|
||||||
@ -136,6 +140,7 @@ namespace rfb {
|
|||||||
PixelFormat pf_;
|
PixelFormat pf_;
|
||||||
char* name_;
|
char* name_;
|
||||||
Cursor* cursor_;
|
Cursor* cursor_;
|
||||||
|
Point cursorPos_;
|
||||||
std::set<rdr::S32> encodings_;
|
std::set<rdr::S32> encodings_;
|
||||||
char verStr[13];
|
char verStr[13];
|
||||||
int verStrPos;
|
int verStrPos;
|
||||||
|
@ -39,6 +39,7 @@ SMsgWriter::SMsgWriter(ConnParams* cp_, rdr::OutStream* os_)
|
|||||||
needSetDesktopSize(false), needExtendedDesktopSize(false),
|
needSetDesktopSize(false), needExtendedDesktopSize(false),
|
||||||
needSetDesktopName(false), needSetCursor(false),
|
needSetDesktopName(false), needSetCursor(false),
|
||||||
needSetXCursor(false), needSetCursorWithAlpha(false),
|
needSetXCursor(false), needSetCursorWithAlpha(false),
|
||||||
|
needCursorPos(false),
|
||||||
needLEDState(false), needQEMUKeyEvent(false)
|
needLEDState(false), needQEMUKeyEvent(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -204,6 +205,14 @@ bool SMsgWriter::writeSetCursorWithAlpha()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SMsgWriter::writeCursorPos()
|
||||||
|
{
|
||||||
|
if (!cp->supportsEncoding(pseudoEncodingVMwareCursorPosition))
|
||||||
|
throw Exception("Client does not support cursor position");
|
||||||
|
|
||||||
|
needCursorPos = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool SMsgWriter::writeLEDState()
|
bool SMsgWriter::writeLEDState()
|
||||||
{
|
{
|
||||||
if (!cp->supportsLEDState)
|
if (!cp->supportsLEDState)
|
||||||
@ -232,6 +241,8 @@ bool SMsgWriter::needFakeUpdate()
|
|||||||
return true;
|
return true;
|
||||||
if (needSetCursor || needSetXCursor || needSetCursorWithAlpha)
|
if (needSetCursor || needSetXCursor || needSetCursorWithAlpha)
|
||||||
return true;
|
return true;
|
||||||
|
if (needCursorPos)
|
||||||
|
return true;
|
||||||
if (needLEDState)
|
if (needLEDState)
|
||||||
return true;
|
return true;
|
||||||
if (needQEMUKeyEvent)
|
if (needQEMUKeyEvent)
|
||||||
@ -284,6 +295,8 @@ void SMsgWriter::writeFramebufferUpdateStart(int nRects)
|
|||||||
nRects++;
|
nRects++;
|
||||||
if (needSetCursorWithAlpha)
|
if (needSetCursorWithAlpha)
|
||||||
nRects++;
|
nRects++;
|
||||||
|
if (needCursorPos)
|
||||||
|
nRects++;
|
||||||
if (needLEDState)
|
if (needLEDState)
|
||||||
nRects++;
|
nRects++;
|
||||||
if (needQEMUKeyEvent)
|
if (needQEMUKeyEvent)
|
||||||
@ -399,6 +412,18 @@ void SMsgWriter::writePseudoRects()
|
|||||||
needSetCursorWithAlpha = false;
|
needSetCursorWithAlpha = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needCursorPos) {
|
||||||
|
const Point& cursorPos = cp->cursorPos();
|
||||||
|
|
||||||
|
if (cp->supportsEncoding(pseudoEncodingVMwareCursorPosition)) {
|
||||||
|
writeSetVMwareCursorPositionRect(cursorPos.x, cursorPos.y);
|
||||||
|
} else {
|
||||||
|
throw Exception("Client does not support cursor position");
|
||||||
|
}
|
||||||
|
|
||||||
|
needCursorPos = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (needSetDesktopName) {
|
if (needSetDesktopName) {
|
||||||
writeSetDesktopNameRect(cp->name());
|
writeSetDesktopNameRect(cp->name());
|
||||||
needSetDesktopName = false;
|
needSetDesktopName = false;
|
||||||
@ -577,6 +602,20 @@ void SMsgWriter::writeSetCursorWithAlphaRect(int width, int height,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SMsgWriter::writeSetVMwareCursorPositionRect(int hotspotX, int hotspotY)
|
||||||
|
{
|
||||||
|
if (!cp->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)
|
void SMsgWriter::writeLEDStateRect(rdr::U8 state)
|
||||||
{
|
{
|
||||||
if (!cp->supportsLEDState)
|
if (!cp->supportsLEDState)
|
||||||
|
@ -83,6 +83,9 @@ namespace rfb {
|
|||||||
bool writeSetXCursor();
|
bool writeSetXCursor();
|
||||||
bool writeSetCursorWithAlpha();
|
bool writeSetCursorWithAlpha();
|
||||||
|
|
||||||
|
// Notifies the client that the cursor pointer was moved by the server.
|
||||||
|
void writeCursorPos();
|
||||||
|
|
||||||
// Same for LED state message
|
// Same for LED state message
|
||||||
bool writeLEDState();
|
bool writeLEDState();
|
||||||
|
|
||||||
@ -138,6 +141,7 @@ namespace rfb {
|
|||||||
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 writeSetVMwareCursorPositionRect(int hotspotX, int hotspotY);
|
||||||
void writeLEDStateRect(rdr::U8 state);
|
void writeLEDStateRect(rdr::U8 state);
|
||||||
void writeQEMUKeyEventRect();
|
void writeQEMUKeyEventRect();
|
||||||
|
|
||||||
@ -153,6 +157,7 @@ namespace rfb {
|
|||||||
bool needSetCursor;
|
bool needSetCursor;
|
||||||
bool needSetXCursor;
|
bool needSetXCursor;
|
||||||
bool needSetCursorWithAlpha;
|
bool needSetCursorWithAlpha;
|
||||||
|
bool needCursorPos;
|
||||||
bool needLEDState;
|
bool needLEDState;
|
||||||
bool needQEMUKeyEvent;
|
bool needQEMUKeyEvent;
|
||||||
|
|
||||||
|
@ -517,6 +517,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
|
// needRenderedCursor() returns true if this client needs the server-side
|
||||||
// rendered cursor. This may be because it does not support local cursor or
|
// 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.
|
// because the current cursor position has not been set by this client.
|
||||||
@ -1482,6 +1491,21 @@ void VNCSConnectionST::setCursor()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 (cp.supportsCursorPosition) {
|
||||||
|
cp.setCursorPos(server->cursorPos);
|
||||||
|
writer()->writeCursorPos();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VNCSConnectionST::setDesktopName(const char *name)
|
void VNCSConnectionST::setDesktopName(const char *name)
|
||||||
{
|
{
|
||||||
cp.setName(name);
|
cp.setName(name);
|
||||||
|
@ -97,6 +97,11 @@ namespace rfb {
|
|||||||
// cursor.
|
// cursor.
|
||||||
void renderedCursorChange();
|
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
|
// needRenderedCursor() returns true if this client needs the server-side
|
||||||
// rendered cursor. This may be because it does not support local cursor
|
// 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.
|
// or because the current cursor position has not been set by this client.
|
||||||
@ -223,6 +228,7 @@ namespace rfb {
|
|||||||
|
|
||||||
void screenLayoutChange(rdr::U16 reason);
|
void screenLayoutChange(rdr::U16 reason);
|
||||||
void setCursor();
|
void setCursor();
|
||||||
|
void setCursorPos();
|
||||||
void setDesktopName(const char *name);
|
void setDesktopName(const char *name);
|
||||||
void setLEDState(unsigned int state);
|
void setLEDState(unsigned int state);
|
||||||
void setSocketTimeouts();
|
void setSocketTimeouts();
|
||||||
|
@ -69,8 +69,10 @@ namespace rfb {
|
|||||||
virtual void setCursor(int width, int height, const Point& hotspot,
|
virtual void setCursor(int width, int height, const Point& hotspot,
|
||||||
const rdr::U8* cursorData) = 0;
|
const rdr::U8* cursorData) = 0;
|
||||||
|
|
||||||
// setCursorPos() tells the server the current position of the cursor.
|
// setCursorPos() tells the server the current position of the cursor, and
|
||||||
virtual void setCursorPos(const Point& p) = 0;
|
// 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
|
// setName() tells the server what desktop title to supply to clients
|
||||||
virtual void setName(const char* name) = 0;
|
virtual void setName(const char* name) = 0;
|
||||||
|
@ -565,14 +565,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)) {
|
if (!cursorPos.equals(pos)) {
|
||||||
cursorPos = pos;
|
cursorPos = pos;
|
||||||
renderedCursorInvalid = true;
|
renderedCursorInvalid = true;
|
||||||
std::list<VNCSConnectionST*>::iterator ci;
|
std::list<VNCSConnectionST*>::iterator ci;
|
||||||
for (ci = clients.begin(); ci != clients.end(); ci++)
|
for (ci = clients.begin(); ci != clients.end(); ci++) {
|
||||||
(*ci)->renderedCursorChange();
|
(*ci)->renderedCursorChange();
|
||||||
|
if (warped)
|
||||||
|
(*ci)->cursorPositionChange();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ namespace rfb {
|
|||||||
virtual void add_copied(const Region &dest, const Point &delta);
|
virtual void add_copied(const Region &dest, const Point &delta);
|
||||||
virtual void setCursor(int width, int height, const Point& hotspot,
|
virtual void setCursor(int width, int height, const Point& hotspot,
|
||||||
const rdr::U8* data);
|
const rdr::U8* data);
|
||||||
virtual void setCursorPos(const Point& p);
|
virtual void setCursorPos(const Point& p, bool warped);
|
||||||
virtual void setLEDState(unsigned state);
|
virtual void setLEDState(unsigned state);
|
||||||
|
|
||||||
virtual void bell();
|
virtual void bell();
|
||||||
|
@ -85,6 +85,9 @@ namespace rfb {
|
|||||||
const int pseudoEncodingVideoOutTimeLevel1 = -1986;
|
const int pseudoEncodingVideoOutTimeLevel1 = -1986;
|
||||||
const int pseudoEncodingVideoOutTimeLevel100 = -1887;
|
const int pseudoEncodingVideoOutTimeLevel100 = -1887;
|
||||||
|
|
||||||
|
// VMware-specific
|
||||||
|
const int pseudoEncodingVMwareCursorPosition = 0x574d5666;
|
||||||
|
|
||||||
int encodingNum(const char* name);
|
int encodingNum(const char* name);
|
||||||
const char* encodingName(int num);
|
const char* encodingName(int num);
|
||||||
}
|
}
|
||||||
|
@ -241,6 +241,15 @@ void XserverDesktop::setCursor(int width, int height, int hotX, int hotY,
|
|||||||
delete [] cursorData;
|
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 ®ion)
|
void XserverDesktop::add_changed(const rfb::Region ®ion)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@ -358,7 +367,7 @@ void XserverDesktop::blockHandler(int* timeout)
|
|||||||
if (oldCursorPos.x != cursorX || oldCursorPos.y != cursorY) {
|
if (oldCursorPos.x != cursorX || oldCursorPos.y != cursorY) {
|
||||||
oldCursorPos.x = cursorX;
|
oldCursorPos.x = cursorX;
|
||||||
oldCursorPos.y = cursorY;
|
oldCursorPos.y = cursorY;
|
||||||
server->setCursorPos(oldCursorPos);
|
server->setCursorPos(oldCursorPos, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger timers and check when the next will expire
|
// Trigger timers and check when the next will expire
|
||||||
|
@ -66,6 +66,7 @@ public:
|
|||||||
void setDesktopName(const char* name);
|
void setDesktopName(const char* name);
|
||||||
void setCursor(int width, int height, int hotX, int hotY,
|
void setCursor(int width, int height, int hotX, int hotY,
|
||||||
const unsigned char *rgbaData);
|
const unsigned char *rgbaData);
|
||||||
|
void setCursorPos(int x, int y, bool warped);
|
||||||
void add_changed(const rfb::Region ®ion);
|
void add_changed(const rfb::Region ®ion);
|
||||||
void add_copied(const rfb::Region &dest, const rfb::Point &delta);
|
void add_copied(const rfb::Region &dest, const rfb::Point &delta);
|
||||||
void handleSocketEvent(int fd, bool read, bool write);
|
void handleSocketEvent(int fd, bool read, bool write);
|
||||||
|
@ -418,6 +418,11 @@ void vncSetCursor(int width, int height, int hotX, int hotY,
|
|||||||
desktop[scr]->setCursor(width, height, hotX, hotY, rgbaData);
|
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)
|
void vncPreScreenResize(int scrIdx)
|
||||||
{
|
{
|
||||||
// We need to prevent the RFB core from accessing the framebuffer
|
// We need to prevent the RFB core from accessing the framebuffer
|
||||||
|
@ -86,6 +86,7 @@ void vncAddCopied(int scrIdx, const struct UpdateRect *extents,
|
|||||||
|
|
||||||
void vncSetCursor(int width, int height, int hotX, int hotY,
|
void vncSetCursor(int width, int height, int hotX, int hotY,
|
||||||
const unsigned char *rgbaData);
|
const unsigned char *rgbaData);
|
||||||
|
void vncSetCursorPos(int scrIdx, int x, int y);
|
||||||
|
|
||||||
void vncPreScreenResize(int scrIdx);
|
void vncPreScreenResize(int scrIdx);
|
||||||
void vncPostScreenResize(int scrIdx, int success, int width, int height);
|
void vncPostScreenResize(int scrIdx, int success, int width, int height);
|
||||||
|
@ -65,6 +65,9 @@ typedef struct _vncHooksScreenRec {
|
|||||||
RestoreAreasProcPtr RestoreAreas;
|
RestoreAreasProcPtr RestoreAreas;
|
||||||
#endif
|
#endif
|
||||||
DisplayCursorProcPtr DisplayCursor;
|
DisplayCursorProcPtr DisplayCursor;
|
||||||
|
#if XORG >= 119
|
||||||
|
CursorWarpedToProcPtr CursorWarpedTo;
|
||||||
|
#endif
|
||||||
ScreenBlockHandlerProcPtr BlockHandler;
|
ScreenBlockHandlerProcPtr BlockHandler;
|
||||||
#ifdef RENDER
|
#ifdef RENDER
|
||||||
CompositeProcPtr Composite;
|
CompositeProcPtr Composite;
|
||||||
@ -137,6 +140,12 @@ static RegionPtr vncHooksRestoreAreas(WindowPtr pWin, RegionPtr prgnExposed);
|
|||||||
#endif
|
#endif
|
||||||
static Bool vncHooksDisplayCursor(DeviceIntPtr pDev,
|
static Bool vncHooksDisplayCursor(DeviceIntPtr pDev,
|
||||||
ScreenPtr pScreen, CursorPtr cursor);
|
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 <= 112
|
#if XORG <= 112
|
||||||
static void vncHooksBlockHandler(int i, pointer blockData, pointer pTimeout,
|
static void vncHooksBlockHandler(int i, pointer blockData, pointer pTimeout,
|
||||||
pointer pReadmask);
|
pointer pReadmask);
|
||||||
@ -316,6 +325,9 @@ int vncHooksInit(int scrIdx)
|
|||||||
wrap(vncHooksScreen, pScreen, RestoreAreas, vncHooksRestoreAreas);
|
wrap(vncHooksScreen, pScreen, RestoreAreas, vncHooksRestoreAreas);
|
||||||
#endif
|
#endif
|
||||||
wrap(vncHooksScreen, pScreen, DisplayCursor, vncHooksDisplayCursor);
|
wrap(vncHooksScreen, pScreen, DisplayCursor, vncHooksDisplayCursor);
|
||||||
|
#if XORG >= 119
|
||||||
|
wrap(vncHooksScreen, pScreen, CursorWarpedTo, vncHooksCursorWarpedTo);
|
||||||
|
#endif
|
||||||
wrap(vncHooksScreen, pScreen, BlockHandler, vncHooksBlockHandler);
|
wrap(vncHooksScreen, pScreen, BlockHandler, vncHooksBlockHandler);
|
||||||
#ifdef RENDER
|
#ifdef RENDER
|
||||||
ps = GetPictureScreenIfSet(pScreen);
|
ps = GetPictureScreenIfSet(pScreen);
|
||||||
@ -725,6 +737,20 @@ out:
|
|||||||
return ret;
|
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
|
// BlockHandler - ignore any changes during the block handler - it's likely
|
||||||
// these are just drawing the cursor.
|
// these are just drawing the cursor.
|
||||||
|
|
||||||
|
@ -385,7 +385,7 @@ SDisplay::processEvent(HANDLE event) {
|
|||||||
// Update the cursor position
|
// Update the cursor position
|
||||||
// NB: First translate from Screen coordinates to Desktop
|
// NB: First translate from Screen coordinates to Desktop
|
||||||
Point desktopPos = info.position.translate(screenRect.tl.negate());
|
Point desktopPos = info.position.translate(screenRect.tl.negate());
|
||||||
server->setCursorPos(desktopPos);
|
server->setCursorPos(desktopPos, false);
|
||||||
|
|
||||||
old_cursor = info;
|
old_cursor = info;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user