diff --git a/lib/x11/corereqs.js b/lib/x11/corereqs.js index b8d4fd0..ab3c5c6 100644 --- a/lib/x11/corereqs.js +++ b/lib/x11/corereqs.js @@ -224,6 +224,14 @@ module.exports = { } ], + SendEvent: [ + + function(destination, propagate, eventMask, eventRawData) + { + return [ 'CCSLLa', [25, propagate, 11, destination, eventMask, eventRawData] ]; + } + ], + QueryPointer: [ [ 'CxSL', [38, 2] ], function(buf) { diff --git a/lib/x11/unpackstream.js b/lib/x11/unpackstream.js index 77ee773..fd0f34b 100644 --- a/lib/x11/unpackstream.js +++ b/lib/x11/unpackstream.js @@ -208,7 +208,7 @@ UnpackStream.prototype.pstr = function(str) */ // TODO: measure node 0.5+ buffer serialisers performance -UnpackStream.prototype.pack = function(format, arguments) +UnpackStream.prototype.pack = function(format, args) { var packetlength = 0; @@ -220,9 +220,9 @@ UnpackStream.prototype.pack = function(format, arguments) { packetlength++; } else if (f == 'p') { - packetlength += xutil.padded_length(arguments[arg++].length); + packetlength += xutil.padded_length(args[arg++].length); } else if (f == 'a') { - packetlength += arguments[arg].length; + packetlength += args[arg].length; arg++; } else { // this is a fixed-length format, get length from argument_length table @@ -242,25 +242,25 @@ UnpackStream.prototype.pack = function(format, arguments) buf[offset++] = 0; break; case 'C': - var n = arguments[arg++]; + var n = args[arg++]; buf[offset++] = n; break; case 's': // TODO: implement signed INT16!!! case 'S': - var n = arguments[arg++]; + var n = args[arg++]; buf[offset++] = n & 0xff; buf[offset++] = (n >> 8) & 0xff; break; case 'l': // TODO: implement signed INT32!!! case 'L': - var n = arguments[arg++]; + var n = args[arg++]; buf[offset++] = n & 0xff; buf[offset++] = (n >> 8) & 0xff; buf[offset++] = (n >> 16) & 0xff; buf[offset++] = (n >> 24) & 0xff; break; case 'a': // string or buffer - var str = arguments[arg++]; + var str = args[arg++]; if (Buffer.isBuffer(str)) { str.copy(buf, offset); @@ -272,7 +272,7 @@ UnpackStream.prototype.pack = function(format, arguments) } break; case 'p': // padded string - var str = arguments[arg++]; + var str = args[arg++]; var len = padded(str); // TODO: buffer.write could be faster var c = 0; diff --git a/lib/x11/xcore.js b/lib/x11/xcore.js index 25d77cd..648a83e 100644 --- a/lib/x11/xcore.js +++ b/lib/x11/xcore.js @@ -172,7 +172,7 @@ XClient.prototype.unpackEvent = function(type, seq, extra, code, raw) event.seq = seq; if (type == 2 || type == 4 || type == 5 || type == 6) { // motion event - var values = raw.unpack('LLLSSSSSC'); //TODO: should be LLLLsssssSC + var values = raw.unpack('LLLssssSC'); //event.raw = values; // TODO: use unpackTo??? event.time = extra; @@ -212,8 +212,8 @@ XClient.prototype.expectReplyHeader = function() // TODO: BigReq!!!! var client = this; - client.pack_stream.unpack( - 'CCSL', function(res) { + client.pack_stream.get( 8, function(headerBuf) { + var res = headerBuf.unpack('CCSL'); var type = res[0]; var seq_num = res[2]; @@ -252,6 +252,13 @@ XClient.prototype.expectReplyHeader = function() var extra = res[3]; var code = res[1]; var ev = client.unpackEvent(type, seq_num, extra, code, buf); + + // raw event 32-bytes packet (primarily for use in SendEvent); + // TODO: Event::pack based on event parameters, inverse to unpackEvent + ev.rawData = new Buffer(32); + headerBuf.copy(ev.rawData); + buf.copy(ev.rawData, 8); + client.emit('event', ev); var ee = client.event_consumers[ev.wid]; if (ee) { diff --git a/test/sendevent.js b/test/sendevent.js new file mode 100644 index 0000000..3b6a257 --- /dev/null +++ b/test/sendevent.js @@ -0,0 +1,65 @@ +var x11 = require('../lib/x11'); + +var xclient = x11.createClient(); +var Exposure = x11.eventMask.Exposure; +var PointerMotion = x11.eventMask.PointerMotion; +var pts = []; + +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; + + function createWindow() + { + + var wid = X.AllocID(); + X.CreateWindow( + wid, root, + 10, 10, 400, 300, + 1, 1, 0, + { + backgroundPixel: white, eventMask: Exposure|PointerMotion + } + ); + X.MapWindow(wid); + return wid; + } + + var wid = createWindow(); + var wid1 = createWindow(); + + var gc = X.AllocID(); + X.CreateGC(gc, wid, { foreground: black, background: white } ); + + X.on('event', function(ev) { + //console.log(ev); + if (ev.type == 12) + { + // expose + } else if (ev.type == 6) { + X.PolyPoint(0, ev.wid, gc, [ev.x, ev.y]); + // send copy of event to the second window + if (ev.wid == wid) // don't send it from second window + { + // set window in the event we are sending + var n = wid1; + var offset = 12; + var buf = ev.rawData; + buf[offset++] = n & 0xff; + buf[offset++] = (n >> 8) & 0xff; + buf[offset++] = (n >> 16) & 0xff; + buf[offset++] = (n >> 24) & 0xff; + + X.SendEvent(wid1, 1, PointerMotion, ev.rawData); + } else { + console.log('GotData!'); + } + } + }); + + X.on('error', function(e) { + console.log(e); + }); +});