Internal
Public Access
Implements RFB's Cursor pseudo-encoding (RFC 6143 SS7.8.2, type -239): a FramebufferUpdate rectangle carrying a cursor shape instead of screen content (x/y are the hotspot, not position; width/height are the cursor image size), decoded into an ARGB32 QImage using the rectangle's RGB pixel data plus its opacity bitmask, then never painted into the framebuffer. A 0x0 rectangle means "hide the cursor" per spec. VncDisplayWidget gains RdpDisplayWidget's setCursorImage/Hidden/ Default() + applyCursor() shape, reusing its own renderRect()/ effectiveRemoteSize() so cursor scaling works correctly in both the scale-to-fit and actual-size display modes with no special-casing. VNC never emits cursorReset() (RFB's Cursor pseudo-encoding has no "reset to system default" signal, unlike RDP's SetDefault callback) -- setCursorDefault() exists for symmetry but is unused today. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
95 lines
3.1 KiB
C++
95 lines
3.1 KiB
C++
#ifndef ORBITHUB_VNC_DISPLAY_WIDGET_H
|
|
#define ORBITHUB_VNC_DISPLAY_WIDGET_H
|
|
|
|
#include <QImage>
|
|
#include <QPoint>
|
|
#include <QWidget>
|
|
|
|
class QKeyEvent;
|
|
class QMouseEvent;
|
|
class QPaintEvent;
|
|
class QResizeEvent;
|
|
class QTimer;
|
|
class QWheelEvent;
|
|
|
|
// Renders a VNC framebuffer and forwards local input, scaled-to-fit --
|
|
// same shape as RdpDisplayWidget, including remote cursor-shape sync.
|
|
class VncDisplayWidget : public QWidget
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit VncDisplayWidget(QWidget* parent = nullptr);
|
|
|
|
void setFrame(const QImage& frame);
|
|
void setRemoteDesktopSize(int width, int height);
|
|
void clearFrame();
|
|
|
|
// true (default): scale the whole remote screen to fit the widget,
|
|
// like RdpDisplayWidget. false: render at the remote's actual pixel
|
|
// size -- meant to be placed inside a QScrollArea, whose scrollbars
|
|
// then let the user pan around a screen larger than the window
|
|
// instead of shrinking small text to illegibility. VNC has no
|
|
// equivalent of RDP's MS-RDPEDISP to request a different resolution
|
|
// from the guest, so this is the only way to see it at native size.
|
|
void setScaleToFit(bool scaleToFit);
|
|
bool scaleToFit() const
|
|
{
|
|
return m_scaleToFit;
|
|
}
|
|
|
|
// Mirrors RdpDisplayWidget's cursor handling. VNC's Cursor pseudo-
|
|
// encoding never signals "reset to default" the way RDP's SetDefault
|
|
// callback does -- it only ever supplies a shape or hides the cursor --
|
|
// so setCursorDefault() exists for symmetry/future use but VNC sessions
|
|
// never call it today.
|
|
void setCursorImage(const QImage& image, const QPoint& hotspot);
|
|
void setCursorHidden();
|
|
void setCursorDefault();
|
|
|
|
signals:
|
|
void keyInput(int key, quint32 nativeScanCode, const QString& text, bool pressed, int modifiers);
|
|
void mouseMoveInput(int x, int y);
|
|
void mouseButtonInput(int x, int y, int button, bool pressed);
|
|
void mouseWheelInput(int x, int y, int deltaX, int deltaY);
|
|
void viewportSizeChanged(int width, int height);
|
|
void displayScaleChanged(qreal devicePixelRatio);
|
|
|
|
protected:
|
|
void paintEvent(QPaintEvent* event) override;
|
|
void resizeEvent(QResizeEvent* event) override;
|
|
bool event(QEvent* event) override;
|
|
void keyPressEvent(QKeyEvent* event) override;
|
|
void keyReleaseEvent(QKeyEvent* event) override;
|
|
void mousePressEvent(QMouseEvent* event) override;
|
|
void mouseReleaseEvent(QMouseEvent* event) override;
|
|
void mouseMoveEvent(QMouseEvent* event) override;
|
|
void wheelEvent(QWheelEvent* event) override;
|
|
bool focusNextPrevChild(bool next) override;
|
|
|
|
private:
|
|
enum class CursorMode {
|
|
Default,
|
|
Hidden,
|
|
Custom,
|
|
};
|
|
|
|
QImage m_frame;
|
|
QSize m_remoteSize;
|
|
QTimer* m_resizeDebounceTimer;
|
|
bool m_scaleToFit;
|
|
QImage m_cursorImage;
|
|
QPoint m_cursorHotspot;
|
|
CursorMode m_cursorMode;
|
|
|
|
QRectF renderRect() const;
|
|
QPoint mapToRemote(const QPointF& pos) const;
|
|
QSize effectiveRemoteSize() const;
|
|
void emitViewportGeometry();
|
|
void scheduleViewportGeometryEmit();
|
|
void applySizeConstraint();
|
|
void applyCursor();
|
|
};
|
|
|
|
#endif
|