diff --git a/lib/x11/corereqs.js b/lib/x11/corereqs.js index 96495fb..1dddafa 100644 --- a/lib/x11/corereqs.js +++ b/lib/x11/corereqs.js @@ -256,6 +256,17 @@ module.exports = { return [format, args]; } ], + + PutImage: [ + // format: 0 - Bitmap, 1 - XYPixmap, 2 - ZPixmap + function(format, drawable, gc, width, height, dstX, dstY, leftPad, depth, data) { + var padded = xutil.padded_length(data.length); + var reqLen = 6 + padded/4; // (length + 3) >> 2 ??? + var padLength = padded - data.length; + var pad = new Buffer(padLength); // TODO: new pack format 'X' - skip amount of bytes supplied in numerical argument + return [ 'CCSLLSSssCCxxaa', [72, format, reqLen, drawable, gc, width, height, dstX, dstY, leftPad, depth, data, pad]]; + } + ], PolyText8: [ function(drawable, gc, x, y, items) { diff --git a/test/bmp.js b/test/bmp.js new file mode 100644 index 0000000..96558ef --- /dev/null +++ b/test/bmp.js @@ -0,0 +1,45 @@ +// http://atlc.sourceforge.net/bmp.html +// Any better format documentation? + +var fs = require('fs'); +var Pixmap = require('./pixmap').Pixmap; +var Buffer = require('buffer').Buffer; +require('../lib/x11/unpackbuffer').addUnpack(Buffer); + +var reversed = new Buffer(256); +for (var i=0; i < 256; ++i) +{ + var res = 0; + for (b = 0; b < 8; ++b) + { + res += ((i & (1 << b) ) >> b) << (7-b); + } + reversed[i] = res; +} + +module.exports.decodeBuffer = function(buffer) +{ + var h = buffer.unpack('CCLxxxxLLLLSSLLLL'); + var header = {}; + header.filesize = h[2]; + header.data_offset = h[3]; + header.header_size = h[4]; + header.width = h[5]; + header.height = h[6]; + header.num_planes = h[7]; + header.bpp = h[8]; + header.compression = h[9]; + header.data_size = h[10]; + header.hresolution = h[11]; // pixels per METER! + header.vresolution = h[12]; + // skipped: num colors, num important colors, palette + var data = buffer.slice(header.data_offset, header.data_offset+header.data_size); + // TODO: decode compressed bitmap + //console.log(header); + + // mirror bits & invert + for (var i=0; i < data.length; ++i) + data[i] = 255 - reversed[data[i]]; + + return new Pixmap(header.bpp, header.width, header.height, data); +} \ No newline at end of file diff --git a/test/nodejs-black.bmp b/test/nodejs-black.bmp new file mode 100644 index 0000000..a932692 Binary files /dev/null and b/test/nodejs-black.bmp differ diff --git a/test/pixmap.js b/test/pixmap.js new file mode 100644 index 0000000..bb09fb3 --- /dev/null +++ b/test/pixmap.js @@ -0,0 +1,9 @@ +function Pixmap(depth, width, height, buffer) +{ + this.depth = depth; + this.width = width; + this.height = height; + this.data = buffer; +} + +module.exports.Pixmap = Pixmap; \ No newline at end of file diff --git a/test/putimage.js b/test/putimage.js new file mode 100644 index 0000000..a866e2e --- /dev/null +++ b/test/putimage.js @@ -0,0 +1,48 @@ +var Buffer = require('buffer').Buffer; +var x11 = require('../lib/x11'); +var fs = require('fs'); +var logo1bit = fs.readFileSync('./nodejs-black.bmp'); +var pixmap = require('./bmp').decodeBuffer(logo1bit); + +var xclient = x11.createClient(); +var Exposure = x11.eventMask.Exposure; +var PointerMotion = x11.eventMask.PointerMotion; + +var bitmap = new Buffer(128*128/8); // 16384 bits, 2048 bytes bitmap +for (var i=0; i < bitmap.length; ++i) +{ + bitmap[i] = i % 256; +} + +xclient.on('connect', function(display) { + var X = this; + var root = display.screen[0].root; + var white = display.screen[0].white_pixel; + var black = display.screen[0].black_pixel; + //console.log(display.screen[0]); + + var wid = X.AllocID(); + X.CreateWindow( + wid, root, + 10, 10, 400, 300, + 1, 1, 0, + { + backgroundPixel: white, eventMask: Exposure|PointerMotion + } + ); + X.MapWindow(wid); + + var gc = X.AllocID(); + X.CreateGC(gc, wid, { foreground: black, background: white } ); + + X.on('event', function(ev) { + if (ev.type == 12) // expose + { + //X.PutImage(0, wid, gc, 128, 128, 20, 20, 0, 1, bitmap); + X.PutImage(0, wid, gc, pixmap.width, pixmap.height, 20, 20, 0, pixmap.depth, pixmap.data); + } + }); + X.on('error', function(e) { + console.log(e); + }); +}); diff --git a/test/query_pointer.js b/test/query_pointer.js new file mode 100644 index 0000000..ccc18a2 --- /dev/null +++ b/test/query_pointer.js @@ -0,0 +1,20 @@ +var x11 = require('../lib/x11'); +var X = x11.createClient(); + +X.on('connect', function(display) { + + var screen = display.screen[0]; + var wid = X.AllocID(); + X.CreateWindow(wid, screen.root, 10, 10, 400, 300, 1, 1, 0, { backgroundPixel: screen.white_pixel }); + X.MapWindow(wid); + setInterval( function() { + X.QueryPointer(wid, function(res) { + console.log(res); + }); + }, 1000); + +}); + +X.on('error', function(err) { + console.log(err); +}); diff --git a/test/query_pointer_benchmark_sync.js b/test/query_pointer_benchmark_sync.js new file mode 100644 index 0000000..3e786fa --- /dev/null +++ b/test/query_pointer_benchmark_sync.js @@ -0,0 +1,48 @@ +// test results: + +// WinServ2008R2, Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz + Xming 6.9.0.31 +// +// 0.4.3/cygwin 32bit : 2900 +/- 300 req/sec +// 0.5.1/win32 : 5500 +/- 1000 req/sec +// cygwin x11perf -sync -pointer : 2800 +/- 200 req/sec +// cygwin x11perf -pointer : 5600 +/- 200 req/sec + +// +// Ubuntu 11.04 32bit, Intel(R) Core(TM)2 Duo CPU T7250 @2.00GHz, XOrg 1:7.6+4ubuntu3.1 +// 0.4.9pre : +// x11perf -sync -pointer : +// x11perf -pointer : + +var x11 = require('../lib/x11'); +var X = x11.createClient(); + +var total = 50000; +var num_qp_left = total; +var start = +new Date(); + +function benchmarkQP(wid) +{ + X.QueryPointer(wid, function(res) { + num_qp_left--; + if (num_qp_left > 0) + benchmarkQP(wid); + else { + var end = +new Date(); + var delta = (end - start)/1000 + console.log( 'Finished ' + total + ' requests in ' + delta + ' sec, ' + total/delta + ' req/sec'); + X.terminate(); + } + }); +} + +X.on('connect', function(display) { + var screen = display.screen[0]; + var wid = X.AllocID(); + X.CreateWindow(wid, screen.root, 10, 10, 400, 300, 1, 1, 0, { backgroundPixel: screen.white_pixel }); + X.MapWindow(wid); + benchmarkQP(wid); +}); + +X.on('error', function(err) { + console.log(err); +});