hextile fixes

This commit is contained in:
Andrey Sidorov 2012-04-12 17:05:02 +10:00
parent 58d5f02509
commit e7e06be354
2 changed files with 126 additions and 71 deletions

View file

@ -54,6 +54,12 @@ PackStream.prototype.readString = function(strcb)
}); });
} }
RfbClient.prototype.terminate = function()
{
debugger;
this.stream.end();
}
RfbClient.prototype.readError = function() RfbClient.prototype.readError = function()
{ {
var cli = this; var cli = this;
@ -225,7 +231,7 @@ RfbClient.prototype.setEncodings = function()
// build encodings list // build encodings list
// TODO: API // TODO: API
var encodings = [rfb.encodings.raw, rfb.encodings.copyRect, rfb.encodings.pseudoDesktopSize]; //, rfb.encodings.hextile]; var encodings = [rfb.encodings.raw, rfb.encodings.copyRect, rfb.encodings.pseudoDesktopSize, rfb.encodings.hextile];
stream.pack('CxS', [rfb.clientMsgTypes.setEncodings, encodings.length]); stream.pack('CxS', [rfb.clientMsgTypes.setEncodings, encodings.length]);
stream.pack(repeat('l', encodings.length), encodings); stream.pack(repeat('l', encodings.length), encodings);
@ -339,7 +345,6 @@ RfbClient.prototype.readHextile = function(rect, cb)
RfbClient.prototype.readHextileTile = function(rect, cb) RfbClient.prototype.readHextileTile = function(rect, cb)
{ {
var tile = {}; var tile = {};
clog('read hextile tile');
var stream = this.pack_stream; var stream = this.pack_stream;
var cli = this; var cli = this;
@ -353,13 +358,11 @@ RfbClient.prototype.readHextileTile = function(rect, cb)
tile.height = rect.bottomRectHeight; tile.height = rect.bottomRectHeight;
// calculate next tilex & tiley and move up 'stack' if we at the last tile // calculate next tilex & tiley and move up 'stack' if we at the last tile
function nextTile(rect, cb) function nextTile()
{ {
//clog('nextTile ===================== '); clog('nextTile');
rect.tiles.push(tile); rect.emit('tile', tile);
//clog(tile);
tile = {}; tile = {};
if (rect.tilex < rect.widthTiles) if (rect.tilex < rect.widthTiles)
{ {
rect.tilex++; rect.tilex++;
@ -382,93 +385,134 @@ RfbClient.prototype.readHextileTile = function(rect, cb)
} }
var bytesPerPixel = cli.bpp >> 3; var bytesPerPixel = cli.bpp >> 3;
console.log('bytesPerPixel: ' + bytesPerPixel);
var tilebuflen = bytesPerPixel*tile.width*tile.height;
stream.unpack('C', function(subEnc) { stream.unpack('C', function(subEnc) {
//clog('tile flags: ' + subEnc[0]); clog('tile flags: ' + subEnc[0]);
tile.subEncoding = subEnc[0]; tile.subEncoding = subEnc[0];
var hextile = rfb.subEncodings.hextile; var hextile = rfb.subEncodings.hextile;
if (tile.subEncoding & hextile.raw) { if (tile.subEncoding & hextile.raw) {
clog('raw tile!!!'); stream.get(tilebuflen, function(rawbuff)
stream.get(bytesPerPixel*tile.width*tile.height, function(rawbuff)
{ {
clog('raw tile');
tile.buffer = rawbuff; tile.buffer = rawbuff;
setTimeout(function(){nextTile(rect, cb);}, 10); nextTile();
}); });
return; return;
} }
// TODO: rewrite to be DRY tile.buffer = new Buffer(tilebuflen);
function solidBackground() {
clog('solidBackground');
// the whole tile is just single colored width x height
for (var i=0; i < tilebuflen; i+= bytesPerPixel)
tile.backgroundColor.copy(tile.buffer, i);
}
function readBackground() {
clog('readBackground');
if (tile.subEncoding & hextile.backgroundSpecified) { if (tile.subEncoding & hextile.backgroundSpecified) {
//clog('hextile.backgroundSpecified'); clog('hextile.backgroundSpecified');
stream.get(bytesPerPixel, function(pixelValue) stream.get(bytesPerPixel, function(pixelValue)
{ {
//clog(['tile.backgroundColor', pixelValue, tile.subEncoding]); clog(['tile.backgroundColor', pixelValue, tile.subEncoding]);
tile.backgroundColor = pixelValue; tile.backgroundColor = pixelValue;
rect.backgroundColor = pixelValue; rect.backgroundColor = pixelValue;
if (!(tile.subEncoding & hextile.anySubrects)) readForeground();
{
return setTimeout(function() { nextTile(rect, cb) }, 10);
}
}); });
} else { } else {
//clog(['not specified, using prev: tile.backgroundColor', rect.backgroundColor]);
tile.backgroundColor = rect.backgroundColor; tile.backgroundColor = rect.backgroundColor;
readForeground();
} }
}
function readForeground() {
clog('readForeground');
// we should have background color set here
solidBackground();
if (rect.subEncoding & hextile.foregroundSpecified) { if (rect.subEncoding & hextile.foregroundSpecified) {
clog('foreground specified');
stream.get(bytesPerPixel, function(pixelValue) stream.get(bytesPerPixel, function(pixelValue)
{ {
tile.foreroundColor = pixelValue; tile.foreroundColor = pixelValue;
rect.foreroundColor = pixelValue; rect.foreroundColor = pixelValue;
console.log(rect);
readSubrects();
}); });
} else { } else {
if (rect.foregroundColor) { clog('foreground NOT specified');
//clog(['not specified, using prev: tile.foregroundColor', rect.foregroundColor]); clog(rect);
tile.backgroundColor = rect.backgroundColor; tile.foregroundColor = rect.foregroundColor;
readSubrects();
} }
} }
tile.subrects = []; function readSubrects() {
clog('readSubrects');
if (tile.subEncoding & hextile.anySubrects) { if (tile.subEncoding & hextile.anySubrects) {
clog('have subrects');
// read number of subrectangles // read number of subrectangles
stream.get('C', function(subrectsNum) { stream.get('C', function(subrectsNum) {
tile.subrectsNum = subrectsNum[0]; tile.subrectsNum = subrectsNum[0];
clog('============================= subrects! ========' + tile.subrectsNum); clog('number of subrects = ' + tile.subrectsNum);
readSubrect();
}); });
} else { } else {
return setTimeout(function() { nextTile(rect, cb) }, 10); nextTile();
//return nextTile(rect, cb); }
}
function drawRect(x, y, w, h)
{
console.log(tile);
console.log(['drawRect', x, y, w, h, tile.foregroundColor]);
// TODO: optimise
for(var px = x; px < x+w; ++px)
{
for(var py = x; py < y+h; ++py)
{
var offset = bytesPerPixel*(tile.width*py + px);
tile.foregroundColor.copy(tile.buffer, offset);
}
}
} }
function readSubrect() { function readSubrect() {
//clog('reading subrects'); clog('readSubrect');
//clog(tile);
var subrect = {};
if (tile.subEncoding & hextile.subrectsColored) { if (tile.subEncoding & hextile.subrectsColored) {
// we have color + rect data
stream.get(bytesPerPixel, function(pixelValue) stream.get(bytesPerPixel, function(pixelValue)
{ {
subrect.foreroundColor = pixelValue; clog(['coloredSubrect: ', pixelValue]);
tile.foreroundColor = pixelValue; tile.foreroundColor = pixelValue;
rect.foreroundColor = pixelValue;
readSubrectRect();
}); });
} else { } else // we have just rect data
subrect.foreroundColor = tile.foregroundColor; readSubrectRect();
} }
function readSubrectRect() {
clog('readSubrectRect');
// read subrect x y w h encoded in two bytes // read subrect x y w h encoded in two bytes
stream.get(2, function(subrectRaw) { stream.get(2, function(subrectRaw) {
subrect.x = (subrectRaw[0] & 0xf0) >> 4; var x = (subrectRaw[0] & 0xf0) >> 4;
subrect.y = (subrectRaw[0] & 0x0f); var y = (subrectRaw[0] & 0x0f);
subrect.width = (subrectRaw[1] & 0xf0) >> 4; var width = (subrectRaw[1] & 0xf0) >> 4 + 1;
subrect.height = (subrectRaw[1] & 0x0f); var height = (subrectRaw[1] & 0x0f) + 1;
tile.subrects.push(subrect); clog(['readSubrectRect', x, y, width, height, tile.subrectsNum]);
if (tile.subrects.length == tile.subrectsNum) drawRect(x, y, width, height);
tile.subrectsNum--;
if (tile.subrectsNum === 0)
{ {
//delete tile..subrectsNum; nextTile();
//cli.emit('rect', rect);
return setTimeout(function() { nextTile(rect, cb) }, 500);
//return nextTile(rect, cb);
} else } else
setTimeout(readSubrect, 500); readSubrect();
}); });
} }
readSubrect();
readBackground();
}); });
} }
@ -556,7 +600,6 @@ RfbClient.prototype.requestUpdate = function(incremental, x, y, width, height)
var fs = require('fs'); var fs = require('fs');
function createRfbStream(name) function createRfbStream(name)
{ {
console.log("WAT?" + name);
var stream = new EventEmitter(); var stream = new EventEmitter();
var fileStream = fs.createReadStream(name); var fileStream = fs.createReadStream(name);
var pack = new PackStream(); var pack = new PackStream();
@ -577,10 +620,12 @@ function createRfbStream(name)
pack.unpack('L', function(timestamp) { pack.unpack('L', function(timestamp) {
var padding = 3 - ((size - 1) & 0x03); var padding = 3 - ((size - 1) & 0x03);
pack.get(padding, function() { pack.get(padding, function() {
if (!stream.ending) {
stream.emit('data', databuf); stream.emit('data', databuf);
var now = +new Date - start; var now = +new Date - start;
var timediff = timestamp[0] - now; var timediff = timestamp[0] - now;
setTimeout(readData, 1);//timediff); stream.timeout = setTimeout(readData, timediff);
}
}); });
}); });
}); });
@ -591,6 +636,12 @@ function createRfbStream(name)
readData(); readData();
}); });
stream.end = function() {
stream.ending = true;
if (stream.timeout)
clearTimeout(stream.timeout);
};
stream.write = function(buf) { stream.write = function(buf) {
// ignore // ignore
} }

View file

@ -111,11 +111,15 @@ x11.createClient(function(display) {
console.log('hextile rec! (currently not fully supported'); console.log('hextile rec! (currently not fully supported');
console.log(rect); console.log(rect);
rect.on('tile', function(tile) { rect.on('tile', function(tile) {
console.log(tile); X.PutImage(2, wid, gc, 16, 16, tile.x, tile.y, 0, 24, tile.buffer);
}); });
} }
}); });
X.on('end', function() {
r.terminate();
});
}); // r.on('connect) }); // r.on('connect)
}); // GetKeyboardMapping }); // GetKeyboardMapping
}); // BigReq.Enable }); // BigReq.Enable