Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scale remote screen to window (X11) #1672

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion vncviewer/DesktopWindow.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,9 @@ void DesktopWindow::resizeFramebuffer(int new_w, int new_h)
}
}

viewport->size(new_w, new_h);
viewport->resizeFramebuffer(new_w, new_h);

fitWindow(w(), h());

repositionWidgets();
}
Expand Down Expand Up @@ -598,6 +600,18 @@ void DesktopWindow::handleClipboardData(const char* data)
}


void DesktopWindow::fitWindow(int w, int h)
{
double viewport_ratio =
static_cast<double>(viewport->frameBufferWidth())/viewport->frameBufferHeight();
double window_ratio = static_cast<double>(w)/h;
if (window_ratio < viewport_ratio)
viewport->size(w, w/viewport_ratio);
else
viewport->size(h*viewport_ratio, h);
}


void DesktopWindow::resize(int x, int y, int w, int h)
{
bool resizing;
Expand Down Expand Up @@ -660,6 +674,8 @@ void DesktopWindow::resize(int x, int y, int w, int h)

Fl_Window::resize(x, y, w, h);

fitWindow(w, h);

if (resizing) {
// Try to get the remote size to match our window size, provided
// the following conditions are true:
Expand Down
2 changes: 2 additions & 0 deletions vncviewer/DesktopWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ class DesktopWindow : public Fl_Window {

void repositionWidgets();

void fitWindow(int w, int h);

static void handleClose(Fl_Widget *wnd, void *data);

static void handleOptions(void *data);
Expand Down
5 changes: 5 additions & 0 deletions vncviewer/Surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,18 @@ class Surface {
void blend(int src_x, int src_y, int x, int y, int w, int h, int a=255);
void blend(Surface* dst, int src_x, int src_y, int x, int y, int w, int h, int a=255);

void setScale(double x, double y);
double scaleX() { return scale_x; }
double scaleY() { return scale_y; }

protected:
void alloc();
void dealloc();
void update(const Fl_RGB_Image* image);

protected:
int w, h;
double scale_x, scale_y;

#if defined(WIN32)
RGBQUAD* data;
Expand Down
14 changes: 14 additions & 0 deletions vncviewer/Surface_X11.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ void Surface::draw(int src_x, int src_y, int x, int y, int w, int h)
XRenderFreePicture(fl_display, winPict);
}

void Surface::setScale(double x, double y)
{
scale_x = x;
scale_y = y;

XTransform transform_matrix = {{
{XDoubleToFixed(x), XDoubleToFixed(0), XDoubleToFixed(0)},
{XDoubleToFixed(0), XDoubleToFixed(y), XDoubleToFixed(0)},
{XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1)}
}};
XRenderSetPictureTransform(fl_display, picture, &transform_matrix);
XRenderSetPictureFilter(fl_display, picture, FilterBilinear, 0, 0 );
}

void Surface::draw(Surface* dst, int src_x, int src_y, int x, int y, int w, int h)
{
XRenderComposite(fl_display, PictOpSrc, picture, None, dst->picture,
Expand Down
41 changes: 37 additions & 4 deletions vncviewer/Viewport.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ void Viewport::updateWindow()
Rect r;

r = frameBuffer->getDamage();
damage(FL_DAMAGE_USER1, r.tl.x + x(), r.tl.y + y(), r.width(), r.height());
damage(FL_DAMAGE_USER1, r.tl.x/frameBuffer->scaleX() + x(), r.tl.y/frameBuffer->scaleY() + y(),
r.width()/frameBuffer->scaleX(), r.height()/frameBuffer->scaleY());
}

static const char * dotcursor_xpm[] = {
Expand Down Expand Up @@ -543,17 +544,45 @@ void Viewport::draw()
}


void Viewport::resize(int x, int y, int w, int h)
void Viewport::updateFrameBufferScale(int w, int h)
{
double new_scale_x = static_cast<double>(frameBuffer->width())/w;
double new_scale_y = static_cast<double>(frameBuffer->height())/h;
frameBuffer->setScale(new_scale_x, new_scale_y);
}


void Viewport::resizeFramebuffer(int w, int h)
{
if ((w != frameBuffer->width()) || (h != frameBuffer->height())) {
vlog.debug("Resizing framebuffer from %dx%d to %dx%d",
frameBuffer->width(), frameBuffer->height(), w, h);

// XXX: memory leak?
frameBuffer = new PlatformPixelBuffer(w, h);
assert(frameBuffer);
cc->setFramebuffer(frameBuffer);

updateFrameBufferScale(this->w(), this->h());
}
}


int Viewport::frameBufferWidth()
{
return frameBuffer->width();
}


int Viewport::frameBufferHeight()
{
return frameBuffer->height();
}


void Viewport::resize(int x, int y, int w, int h)
{
updateFrameBufferScale(w, h);
Fl_Widget::resize(x, y, w, h);
}

Expand Down Expand Up @@ -667,9 +696,13 @@ void Viewport::sendPointerEvent(const rfb::Point& pos, int buttonMask)
if (viewOnly)
return;

rfb::Point scaled_pos;
scaled_pos.x = pos.x * frameBuffer->scaleX();
scaled_pos.y = pos.y * frameBuffer->scaleY();

if ((pointerEventInterval == 0) || (buttonMask != lastButtonMask)) {
try {
cc->writer()->writePointerEvent(pos, buttonMask);
cc->writer()->writePointerEvent(scaled_pos, buttonMask);
} catch (rdr::Exception& e) {
vlog.error("%s", e.str());
abort_connection_with_unexpected_error(e);
Expand All @@ -679,7 +712,7 @@ void Viewport::sendPointerEvent(const rfb::Point& pos, int buttonMask)
Fl::add_timeout((double)pointerEventInterval/1000.0,
handlePointerTimeout, this);
}
lastPointerPos = pos;
lastPointerPos = scaled_pos;
lastButtonMask = buttonMask;
}

Expand Down
6 changes: 6 additions & 0 deletions vncviewer/Viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ class Viewport : public Fl_Widget, public EmulateMB {

void resize(int x, int y, int w, int h);

void resizeFramebuffer(int w, int h);
int frameBufferWidth();
int frameBufferHeight();

int handle(int event);

protected:
Expand Down Expand Up @@ -105,6 +109,8 @@ class Viewport : public Fl_Widget, public EmulateMB {

static void handleOptions(void *data);

void updateFrameBufferScale(int w, int h);

private:
CConn* cc;

Expand Down
Loading