From 4164611a06fc9ee8d817e6579f266cfe0dab161a Mon Sep 17 00:00:00 2001 From: sidorares Date: Mon, 18 Jul 2011 13:16:20 +1000 Subject: [PATCH] InternAtom/GetAtomName requests --- lib/x11/corereqs.js | 18 ++++++++++++------ lib/x11/unpackbuffer.js | 24 +++++++++++++++++++++--- lib/x11/unpackstream.js | 2 +- lib/x11/xcore.js | 41 +++++++++++++++++++++++++++-------------- test/atoms.js | 7 +++---- 5 files changed, 64 insertions(+), 28 deletions(-) diff --git a/lib/x11/corereqs.js b/lib/x11/corereqs.js index 5297da4..61b6f5a 100644 --- a/lib/x11/corereqs.js +++ b/lib/x11/corereqs.js @@ -1,4 +1,5 @@ var xutil = require('./xutil'); +var hexy = require('./hexy').hexy; var valueMask = { CreateWindow: { @@ -186,18 +187,23 @@ module.exports = { function (returnOnlyIfExist, value) { var padded = xutil.padded_string(value); - return ['CCSSa', [16, returnOnlyIfExist ? 1 : 0, 2+padded.length/4, value.length, value] ]; + return ['CCSSxxa', [16, returnOnlyIfExist ? 1 : 0, 2+padded.length/4, value.length, padded] ]; }, - function(stream, buf) { - console.error('Intern Atom reply !!!!'); + function(buf) { + var res = buf.unpack('L')[0]; + return res; } ], GetAtomName: [ [ 'CxSL', [17, 2] ], - function(stream, buf) { - console.error('Intern GetAtomName reply !!!!'); + function(buf) { + var nameLen = buf.unpack('S')[0]; + return buf.unpackString(nameLen, 24); } - ] + ], + + //TODO: remove when finished + DummyLast: [] } diff --git a/lib/x11/unpackbuffer.js b/lib/x11/unpackbuffer.js index 410c8f1..4ed0c49 100644 --- a/lib/x11/unpackbuffer.js +++ b/lib/x11/unpackbuffer.js @@ -1,5 +1,5 @@ // unpack for static buffer - + // TODO: use as fallback only if v0.5+ fuffer is not available // TODO: remove duplicate code var argument_length = {}; @@ -11,10 +11,12 @@ argument_length.x = 1; module.exports.addUnpack = function(Buffer) { - Buffer.prototype.unpack = function(format) + Buffer.prototype.unpack = function(format, offset) { + if (!offset) + offset = 0; + var data = []; - var offset = 0; var current_arg = 0; while (current_arg < format.length) { @@ -43,4 +45,20 @@ module.exports.addUnpack = function(Buffer) } return data; } + + /* + Buffer.prototype.skip = function(n) + { + offset += n; + } + */ + + Buffer.prototype.unpackString = function(n, offset) + { + var res = ''; + var end = offset + n; + while(offset < end) + res += String.fromCharCode(this[offset++]); + return res; + } } diff --git a/lib/x11/unpackstream.js b/lib/x11/unpackstream.js index a37dc9b..ed7e5be 100644 --- a/lib/x11/unpackstream.js +++ b/lib/x11/unpackstream.js @@ -260,7 +260,7 @@ UnpackStream.prototype.pack = function(format, arguments) var str = arguments[arg++]; // TODO: buffer.write could be faster for (var c = 0; c < str.length; ++c) - buf[offset++] = str[c]; + buf[offset++] = str.charCodeAt(c); break; case 'p': // padded string var str = arguments[arg++]; diff --git a/lib/x11/xcore.js b/lib/x11/xcore.js index f1db47f..22d44bd 100644 --- a/lib/x11/xcore.js +++ b/lib/x11/xcore.js @@ -47,7 +47,7 @@ function XClient(stream) this.pack_stream = pack_stream; this.rcrc_id = 0; // generated for each new resource - this.seq_num = 1; // incremented in each request. (even if we don't expect reply) + this.seq_num = 0; // incremented in each request. (even if we don't expect reply) // in/out packets indexed by sequence ID this.requests = {}; @@ -85,12 +85,12 @@ XClient.prototype.importRequestsFromTemplates = function(target, reqs) target[r] = (function(reqName) { var reqFunc = function req_proxy() { client.seq_num++; // TODO: handle overflow (seq should be last 15 (?) bits of the number - // is it fast? var args = Array.prototype.slice.call(req_proxy.arguments); - // TODO: setup last argument to be reply/error callback - // var callback = args.length > 0 ? null : args[args.length - 1]; + var callback = args.length > 0 ? args[args.length - 1] : null; + if (callback && callback.constructor.name != 'Function') + callback = null; // TODO: see how much we can calculate in advance (not in each request) var reqReplTemplate = reqs[reqName]; @@ -107,7 +107,11 @@ XClient.prototype.importRequestsFromTemplates = function(target, reqs) reqPack = reqTemplate.apply(this, req_proxy.arguments); var format = reqPack[0]; var requestArguments = reqPack[1]; - console.error([format, requestArguments]); + + if (callback) + this.replies[this.seq_num] = [reqName, callback]; + + //console.error([format, requestArguments]); client.pack_stream.pack(format, requestArguments); client.pack_stream.flush(); } else if (templateType == 'Array'){ @@ -115,7 +119,11 @@ XClient.prototype.importRequestsFromTemplates = function(target, reqs) var requestArguments = reqTemplate[1]; for (a in args) requestArguments.push(args[a]); - console.error([format, requestArguments]); + + if (callback) + this.replies[this.seq_num] = [reqName, callback]; + + //console.error([format, requestArguments]); client.pack_stream.pack(format, requestArguments); client.pack_stream.flush(); } else { @@ -161,6 +169,8 @@ XClient.prototype.unpackEvent = function(type, seq, extra, raw) XClient.prototype.expectReplyHeader = function() { + // TODO: BigReq!!!! + var client = this; client.pack_stream.unpack( 'CCSL', function(res) { @@ -190,19 +200,22 @@ XClient.prototype.expectReplyHeader = function() } ); return; } + var opt_data = res[1]; var length_total = res[3]; // in 4-bytes units, _including_ this header var bodylength = 24 + length_total*4; // 24 is rest if 32-bytes header - console.log(res); - console.log('reply of length ' + bodylength + ' should follow'); client.pack_stream.get( bodylength, function( data ) { - - var handler = this.replyHandlers[seq_num]; - - // TODO: decode and dispatch, use sequence number - console.error('reply data!!!!!!!!!!'); - console.error(hexy(data, { prefix: 'InternAtom reply' })); + + var handler = client.replies[seq_num]; + if (handler) { + var reqName = handler[0]; + var req = coreRequests[reqName]; + var unpack = req[1]; + var result = unpack( data ); + var callback = handler[1]; + callback(result); + } // wait for new packet from server client.expectReplyHeader(); diff --git a/test/atoms.js b/test/atoms.js index fba1db7..0cd4ec6 100644 --- a/test/atoms.js +++ b/test/atoms.js @@ -6,9 +6,8 @@ xclient.on('connect', function(display) { var X = this; var hello = 'Hello, node.js'; X.InternAtom(false, hello, function(atomId) { - console.log(atomId); - }); - X.InternAtom(true, 'test', function(atomId) { - console.log(atomId); + X.GetAtomName(atomId, function(str) { + console.log('Value for atom ' + atomId + ' is \"' + str + '\"'); + }); }); });