Commit 9192cbe3 authored by Joel Martin's avatar Joel Martin

Merge branch 'master' into mobile

Conflicts:
	include/rfb.js
parents 6ea8bece 54e7cbdf
...@@ -25,8 +25,12 @@ var that = {}, // Public API methods ...@@ -25,8 +25,12 @@ var that = {}, // Public API methods
imageDataCreate, imageDataGet, rgbxImageData, cmapImageData, imageDataCreate, imageDataGet, rgbxImageData, cmapImageData,
rgbxImageFill, cmapImageFill, setFillColor, rescale, flush, rgbxImageFill, cmapImageFill, setFillColor, rescale, flush,
c_width = 0, // The full frame buffer (logical canvas) size
c_height = 0, fb_width = 0,
fb_height = 0,
// The visible "physical canvas" viewport
viewport = {'x': 0, 'y': 0, 'w' : 0, 'h' : 0 },
cleanRect = {'x1': 0, 'y1': 0, 'x2': -1, 'y2': -1},
c_prevStyle = "", c_prevStyle = "",
...@@ -55,11 +59,11 @@ that.get_context = function () { return c_ctx; }; ...@@ -55,11 +59,11 @@ that.get_context = function () { return c_ctx; };
that.set_scale = function(scale) { rescale(scale); }; that.set_scale = function(scale) { rescale(scale); };
that.set_width = function (val) { that.resize(val, c_height); }; that.set_width = function (val) { that.resize(val, fb_height); };
that.get_width = function() { return c_width; }; that.get_width = function() { return fb_width; };
that.set_height = function (val) { that.resize(c_width, val); }; that.set_height = function (val) { that.resize(fb_width, val); };
that.get_height = function() { return c_height; }; that.get_height = function() { return fb_height; };
that.set_prefer_js = function(val) { that.set_prefer_js = function(val) {
if (val && c_forceCanvas) { if (val && c_forceCanvas) {
...@@ -217,7 +221,10 @@ rescale = function(factor) { ...@@ -217,7 +221,10 @@ rescale = function(factor) {
return; return;
} }
if (factor > 1.0) {
if (typeof(factor) === "undefined") {
factor = conf.scale;
} else if (factor > 1.0) {
factor = 1.0; factor = 1.0;
} else if (factor < 0.1) { } else if (factor < 0.1) {
factor = 0.1; factor = 0.1;
...@@ -234,6 +241,174 @@ rescale = function(factor) { ...@@ -234,6 +241,174 @@ rescale = function(factor) {
c.style[tp] = "scale(" + conf.scale + ") translate(-" + x + "px, -" + y + "px)"; c.style[tp] = "scale(" + conf.scale + ") translate(-" + x + "px, -" + y + "px)";
}; };
that.viewportChange = function(deltaX, deltaY, width, height) {
var c = conf.target, v = viewport, cr = cleanRect,
saveImg = null, saveStyle, x1, y1, vx2, vy2, w, h;
if (typeof(deltaX) === "undefined") { deltaX = 0; }
if (typeof(deltaY) === "undefined") { deltaY = 0; }
if (typeof(width) === "undefined") { width = v.w; }
if (typeof(height) === "undefined") { height = v.h; }
// Size change
if (width > fb_width) { width = fb_width; }
if (height > fb_height) { height = fb_height; }
if ((v.w !== width) || (v.h !== height)) {
// Change width
if ((width < v.w) && (cr.x2 > v.x + width -1)) {
cr.x2 = v.x + width - 1;
}
v.w = width;
// Change height
if ((height < v.h) && (cr.y2 > v.y + height -1)) {
cr.y2 = v.y + height - 1;
}
v.h = height;
if (v.w > 0 && v.h > 0) {
saveImg = c_ctx.getImageData(0, 0,
(c.width < v.w) ? c.width : v.w,
(c.height < v.h) ? c.height : v.h);
}
c.width = v.w;
c.height = v.h;
if (saveImg) {
c_ctx.putImageData(saveImg, 0, 0);
}
}
vx2 = v.x + v.w - 1;
vy2 = v.y + v.h - 1;
// Position change
if ((deltaX < 0) && ((v.x + deltaX) < 0)) {
deltaX = - v.x;
}
if ((vx2 + deltaX) >= fb_width) {
deltaX -= ((vx2 + deltaX) - fb_width + 1);
}
if ((v.y + deltaY) < 0) {
deltaY = - v.y;
}
if ((vy2 + deltaY) >= fb_height) {
deltaY -= ((vy2 + deltaY) - fb_height + 1);
}
if ((deltaX === 0) && (deltaY === 0)) {
//message("skipping");
return;
}
message("deltaX: " + deltaX + ", deltaY: " + deltaY);
v.x += deltaX;
vx2 += deltaX;
v.y += deltaY;
vy2 += deltaY;
// Update the clean rectangle
if (v.x > cr.x1) {
cr.x1 = v.x;
}
if (vx2 < cr.x2) {
cr.x2 = vx2;
}
if (v.y > cr.y1) {
cr.y1 = v.y;
}
if (vy2 < cr.y2) {
cr.y2 = vy2;
}
if (deltaX < 0) {
// Shift viewport left, redraw left section
x1 = 0;
w = - deltaX;
} else {
// Shift viewport right, redraw right section
x1 = v.w - deltaX;
w = deltaX;
}
if (deltaY < 0) {
// Shift viewport up, redraw top section
y1 = 0;
h = - deltaY;
} else {
// Shift viewport down, redraw bottom section
y1 = v.h - deltaY;
h = deltaY;
}
// Copy the valid part of the viewport to the shifted location
saveStyle = c_ctx.fillStyle;
c_ctx.fillStyle = "rgb(255,255,255)";
if (deltaX !== 0) {
//that.copyImage(0, 0, -deltaX, 0, v.w, v.h);
//that.fillRect(x1, 0, w, v.h, [255,255,255]);
c_ctx.drawImage(c, 0, 0, v.w, v.h, -deltaX, 0, v.w, v.h);
c_ctx.fillRect(x1, 0, w, v.h);
}
if (deltaY !== 0) {
//that.copyImage(0, 0, 0, -deltaY, v.w, v.h);
//that.fillRect(0, y1, v.w, h, [255,255,255]);
c_ctx.drawImage(c, 0, 0, v.w, v.h, 0, -deltaY, v.w, v.h);
c_ctx.fillRect(0, y1, v.w, h);
}
c_ctx.fillStyle = saveStyle;
}
that.getCleanDirtyReset = function() {
var v = viewport, c = cleanRect, cleanBox, dirtyBoxes = [],
vx2 = v.x + v.w - 1, vy2 = v.y + v.h - 1;
// Copy the cleanRect
cleanBox = {'x': c.x1, 'y': c.y1,
'w': c.x2 - c.x1 + 1, 'h': c.y2 - c.y1 + 1};
if ((c.x1 >= c.x2) || (c.y1 >= c.y2)) {
// Whole viewport is dirty
dirtyBoxes.push({'x': v.x, 'y': v.y, 'w': v.w, 'h': v.h});
} else {
// Redraw dirty regions
if (v.x < c.x1) {
// left side dirty region
dirtyBoxes.push({'x': v.x, 'y': v.y,
'w': c.x1 - v.x + 1, 'h': v.h});
}
if (vx2 > c.x2) {
// right side dirty region
dirtyBoxes.push({'x': c.x2 + 1, 'y': v.y,
'w': vx2 - c.x2, 'h': v.h});
}
if (v.y < c.y1) {
// top/middle dirty region
dirtyBoxes.push({'x': c.x1, 'y': v.y,
'w': c.x2 - c.x1 + 1, 'h': c.y1 - v.y});
}
if (vy2 > c.y2) {
// bottom/middle dirty region
dirtyBoxes.push({'x': c.x1, 'y': c.y2 + 1,
'w': c.x2 - c.x1 + 1, 'h': vy2 - c.y2});
}
}
// Reset the cleanRect to the whole viewport
cleanRect = {'x1': v.x, 'y1': v.y,
'x2': v.x + v.w - 1, 'y2': v.y + v.h - 1};
return {'cleanBox': cleanBox, 'dirtyBoxes': dirtyBoxes};
}
// Force canvas redraw (for webkit bug #46319 workaround) // Force canvas redraw (for webkit bug #46319 workaround)
flush = function() { flush = function() {
var old_val; var old_val;
...@@ -266,27 +441,25 @@ setFillColor = function(color) { ...@@ -266,27 +441,25 @@ setFillColor = function(color) {
// //
that.resize = function(width, height) { that.resize = function(width, height) {
var c = conf.target;
c_prevStyle = ""; c_prevStyle = "";
c.width = width; fb_width = width;
c.height = height; fb_height = height;
c_width = c.offsetWidth;
c_height = c.offsetHeight;
rescale(conf.scale); rescale(conf.scale);
that.viewportChange();
}; };
that.clear = function() { that.clear = function() {
if (conf.logo) { if (conf.logo) {
that.resize(conf.logo.width, conf.logo.height); that.resize(conf.logo.width, conf.logo.height);
that.viewportChange(0, 0, conf.logo.width, conf.logo.height);
that.blitStringImage(conf.logo.data, 0, 0); that.blitStringImage(conf.logo.data, 0, 0);
} else { } else {
that.resize(640, 20); that.resize(640, 20);
c_ctx.clearRect(0, 0, c_width, c_height); that.viewportChange(0, 0, 640, 20);
c_ctx.clearRect(0, 0, viewport.w, viewport.h);
} }
// No benefit over default ("source-over") in Chrome and firefox // No benefit over default ("source-over") in Chrome and firefox
...@@ -295,12 +468,13 @@ that.clear = function() { ...@@ -295,12 +468,13 @@ that.clear = function() {
that.fillRect = function(x, y, width, height, color) { that.fillRect = function(x, y, width, height, color) {
setFillColor(color); setFillColor(color);
c_ctx.fillRect(x, y, width, height); c_ctx.fillRect(x - viewport.x, y - viewport.y, width, height);
}; };
that.copyImage = function(old_x, old_y, new_x, new_y, width, height) { that.copyImage = function(old_x, old_y, new_x, new_y, w, h) {
c_ctx.drawImage(conf.target, old_x, old_y, width, height, var x1 = old_x - viewport.x, y1 = old_y - viewport.y,
new_x, new_y, width, height); x2 = new_x - viewport.x, y2 = new_y - viewport.y;
c_ctx.drawImage(conf.target, x1, y1, w, h, x2, y2, w, h);
}; };
/* /*
...@@ -386,7 +560,7 @@ rgbxImageData = function(x, y, width, height, arr, offset) { ...@@ -386,7 +560,7 @@ rgbxImageData = function(x, y, width, height, arr, offset) {
data[i + 2] = arr[j + 2]; data[i + 2] = arr[j + 2];
data[i + 3] = 255; // Set Alpha data[i + 3] = 255; // Set Alpha
} }
c_ctx.putImageData(img, x, y); c_ctx.putImageData(img, x - viewport.x, y - viewport.y);
}; };
// really slow fallback if we don't have imageData // really slow fallback if we don't have imageData
...@@ -414,7 +588,7 @@ cmapImageData = function(x, y, width, height, arr, offset) { ...@@ -414,7 +588,7 @@ cmapImageData = function(x, y, width, height, arr, offset) {
data[i + 2] = rgb[2]; data[i + 2] = rgb[2];
data[i + 3] = 255; // Set Alpha data[i + 3] = 255; // Set Alpha
} }
c_ctx.putImageData(img, x, y); c_ctx.putImageData(img, x - viewport.x, y - viewport.y);
}; };
cmapImageFill = function(x, y, width, height, arr, offset) { cmapImageFill = function(x, y, width, height, arr, offset) {
...@@ -441,7 +615,9 @@ that.blitImage = function(x, y, width, height, arr, offset) { ...@@ -441,7 +615,9 @@ that.blitImage = function(x, y, width, height, arr, offset) {
that.blitStringImage = function(str, x, y) { that.blitStringImage = function(str, x, y) {
var img = new Image(); var img = new Image();
img.onload = function () { c_ctx.drawImage(img, x, y); }; img.onload = function () {
c_ctx.drawImage(img, x - viewport.x, y - viewport.y);
};
img.src = str; img.src = str;
}; };
......
.fullscreen { html,body {
display: block; margin: 0px;
position: absolute; padding: 0px;
top: 0px;
left: 0px;
width: 100%; width: 100%;
height: 100%; height: 100%;
z-index: 9999;
margin: 0;
padding: 0;
} }
.flex-layout { .flex-layout {
width: 100%;
height: 100%;
display: box; display: box;
display: -webkit-box; display: -webkit-box;
display: -moz-box; display: -moz-box;
display: -ms-box; display: -ms-box;
box-orient: vertical; box-orient: vertical;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
-moz-box-orient: vertical; -moz-box-orient: vertical;
-ms-box-orient: vertical; -ms-box-orient: vertical;
box-align: stretch;
-webkit-box-align: stretch;
-moz-box-align: stretch;
-ms-box-align: stretch;
} }
.flex-box { .flex-box {
box-flex: 1; box-flex: 1;
...@@ -27,3 +31,13 @@ ...@@ -27,3 +31,13 @@
-ms-box-flex: 1; -ms-box-flex: 1;
} }
.container {
margin: 0px;
padding: 0px;
}
.canvas {
position: absolute;
border-style: dotted;
border-width: 1px;
}
...@@ -778,6 +778,7 @@ init_msg = function() { ...@@ -778,6 +778,7 @@ init_msg = function() {
display.set_true_color(conf.true_color); display.set_true_color(conf.true_color);
display.resize(fb_width, fb_height); display.resize(fb_width, fb_height);
display.viewportChange(0, 0, fb_width, fb_height);
keyboard.grab(); keyboard.grab();
mouse.grab(); mouse.grab();
...@@ -840,7 +841,7 @@ normal_msg = function() { ...@@ -840,7 +841,7 @@ normal_msg = function() {
blue = parseInt(ws.rQshift16() / 256, 10); blue = parseInt(ws.rQshift16() / 256, 10);
display.set_colourMap([red, green, blue], first_colour + c); display.set_colourMap([red, green, blue], first_colour + c);
} }
Util.Debug("*** colourMap: " + display.get_colourMap()); Util.Debug("colourMap: " + display.get_colourMap());
Util.Info("Registered " + num_colours + " colourMap entries"); Util.Info("Registered " + num_colours + " colourMap entries");
//Util.Debug("colourMap: " + display.get_colourMap()); //Util.Debug("colourMap: " + display.get_colourMap());
break; break;
...@@ -1308,6 +1309,7 @@ encHandlers.DesktopSize = function set_desktopsize() { ...@@ -1308,6 +1309,7 @@ encHandlers.DesktopSize = function set_desktopsize() {
fb_width = FBU.width; fb_width = FBU.width;
fb_height = FBU.height; fb_height = FBU.height;
display.resize(fb_width, fb_height); display.resize(fb_width, fb_height);
display.viewportChange(0, 0, fb_width, fb_height);
timing.fbu_rt_start = (new Date()).getTime(); timing.fbu_rt_start = (new Date()).getTime();
// Send a new non-incremental request // Send a new non-incremental request
ws.send(fbUpdateRequest(0)); ws.send(fbUpdateRequest(0));
......
This diff is collapsed.
...@@ -295,7 +295,7 @@ Sec-WebSocket-Accept: %s\r ...@@ -295,7 +295,7 @@ Sec-WebSocket-Accept: %s\r
if has_mask: if has_mask:
# unmask payload # unmask payload
f['mask'] = buf[f['hlen']:f['hlen']+4] f['mask'] = buf[f['hlen']:f['hlen']+4]
b = c = '' b = c = s2b('')
if f['length'] >= 4: if f['length'] >= 4:
mask = numpy.frombuffer(buf, dtype=numpy.dtype('<u4'), mask = numpy.frombuffer(buf, dtype=numpy.dtype('<u4'),
offset=f['hlen'], count=1) offset=f['hlen'], count=1)
...@@ -635,7 +635,7 @@ Sec-WebSocket-Accept: %s\r ...@@ -635,7 +635,7 @@ Sec-WebSocket-Accept: %s\r
# Generate the hash value for the accept header # Generate the hash value for the accept header
accept = b64encode(sha1(s2b(key + self.GUID)).digest()) accept = b64encode(sha1(s2b(key + self.GUID)).digest())
response = self.server_handshake_hybi % accept response = self.server_handshake_hybi % b2s(accept)
if self.base64: if self.base64:
response += "Sec-WebSocket-Protocol: base64\r\n" response += "Sec-WebSocket-Protocol: base64\r\n"
else: else:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment