mirror of
https://github.com/danbulant/node-x11
synced 2026-06-10 02:00:26 +00:00
Merge branch 'master' of https://github.com/sidorares/node-x11
This commit is contained in:
commit
dfb9ff059a
15 changed files with 377 additions and 34 deletions
|
|
@ -4,5 +4,4 @@ before_script:
|
|||
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.8
|
||||
|
|
@ -59,7 +59,7 @@ Core requsests usage:
|
|||
|
||||
# Other implementations
|
||||
|
||||
- C: XLib - http://codesearch.google.com/codesearch/p?hl=en#xEHUuo8Crmg/sites/ftp.x.org/pub/X11R7.2/src/update/everything/libX11-X11R7.2-1.1.1.tar.bz2%7CnOqwAyDlYlo/libX11-X11R7.2-1.1.1/src/OpenDis.c&q=XOpenDisplay&d=3
|
||||
- C: XLib - http://www.sbin.org/doc/Xlib/ http://www.tronche.com/gui/x/xlib/ http://www.x.org/docs/X11/xlib.pdf
|
||||
- C: XCB - http://xcb.freedesktop.org/
|
||||
- Python: http://sourceforge.net/projects/python-xlib/ ( github fork: https://github.com/Ademan/python-xlib-branch pypi: http://pypi.python.org/pypi/Python%20Xlib )
|
||||
- Python/twisted: https://launchpad.net/twisted-x11
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ function packValueMask(reqname, values)
|
|||
var args = [];
|
||||
for (m in masksList)
|
||||
{
|
||||
valueName = reqValueMaskName[masksList[m]];
|
||||
var valueName = reqValueMaskName[masksList[m]];
|
||||
args.push( values[valueName] );
|
||||
}
|
||||
return [bitmask, args]
|
||||
|
|
@ -162,7 +162,7 @@ module.exports = {
|
|||
|
||||
// add values in the order of the bits
|
||||
// TODO: maybe it's better just to scan all 32 bits anstead of sorting parameters we are actually have?
|
||||
for (m in masksList)
|
||||
for (var m in masksList)
|
||||
{
|
||||
var valueName = valueMaskName['CreateWindow'][masksList[m]];
|
||||
args.push( values[valueName] );
|
||||
|
|
@ -179,7 +179,7 @@ module.exports = {
|
|||
var vals = packValueMask('CreateWindow', values);
|
||||
var args = [2, packetLength, wid, vals[0]];
|
||||
var valArr = vals[1];
|
||||
for (v in valArr)
|
||||
for (var v in valArr)
|
||||
{
|
||||
format += 'L';
|
||||
args.push(valArr[v]);
|
||||
|
|
@ -244,6 +244,12 @@ module.exports = {
|
|||
}
|
||||
],
|
||||
|
||||
RaiseWindow: [
|
||||
function(win) {
|
||||
return ['CxSLSxxCxxx', [12, 4, win, 64]];
|
||||
}
|
||||
],
|
||||
|
||||
|
||||
QueryTree: [
|
||||
['CxSL', [15, 2]],
|
||||
|
|
@ -385,6 +391,14 @@ module.exports = {
|
|||
return res;
|
||||
}
|
||||
],
|
||||
|
||||
SetInputFocus: [
|
||||
|
||||
function (wid, revertTo) // revertTo: 0 - None, 1 - PointerRoot, 2 - Parent
|
||||
{
|
||||
return [ 'CCSLL', [42, revertTo, 3, wid, 0] ];
|
||||
}
|
||||
],
|
||||
|
||||
WarpPointer: [
|
||||
|
||||
|
|
@ -439,7 +453,7 @@ module.exports = {
|
|||
var vals = packValueMask('CreateGC', values);
|
||||
args.push(vals[0]); // values bitmask
|
||||
var valArr = vals[1];
|
||||
for (v in valArr)
|
||||
for (var v in valArr)
|
||||
{
|
||||
format += 'L'; // TODO: we know format string length in advance and += inefficient for string
|
||||
args.push(valArr[v]);
|
||||
|
|
@ -456,7 +470,7 @@ module.exports = {
|
|||
var vals = packValueMask('CreateGC', values);
|
||||
args.push(vals[0]); // values bitmask
|
||||
var valArr = vals[1];
|
||||
for (v in valArr)
|
||||
for (var v in valArr)
|
||||
{
|
||||
format += 'L'; // TODO: we know format string length in advance and += inefficient for string
|
||||
args.push(valArr[v]);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ exports.requireExt = function(display, callback)
|
|||
X.QueryExtension('BIG-REQUESTS', function(err, ext) {
|
||||
|
||||
if (!ext.present)
|
||||
callback(new Error('extension not available'));
|
||||
return callback(new Error('extension not available'));
|
||||
|
||||
ext.Enable = function( cb )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ exports.requireExt = function(display, callback)
|
|||
X.QueryExtension('Composite', function(err, ext) {
|
||||
|
||||
if (!ext.present)
|
||||
callback(new Error('extension not available'));
|
||||
return callback(new Error('extension not available'));
|
||||
|
||||
ext.Redirect = {
|
||||
Automatic: 0,
|
||||
|
|
|
|||
100
lib/x11/ext/dpms.js
Normal file
100
lib/x11/ext/dpms.js
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
// http://www.x.org/releases/X11R7.6/doc/xextproto/dpms.txt
|
||||
|
||||
var x11 = require('..');
|
||||
// TODO: move to templates
|
||||
exports.requireExt = function(display, callback)
|
||||
{
|
||||
var X = display.client;
|
||||
X.QueryExtension('DPMS', function(err, ext) {
|
||||
|
||||
if (!ext.present)
|
||||
return callback(new Error('extension not available'));
|
||||
|
||||
ext.GetVersion = function(clientMaj, clientMin, callback)
|
||||
{
|
||||
X.seq_num++;
|
||||
X.pack_stream.pack('CCSSS', [ext.majorOpcode, 0, 2, clientMaj, clientMin]);
|
||||
X.replies[X.seq_num] = [
|
||||
function(buf, opt) {
|
||||
var res = buf.unpack('SS');
|
||||
return res;
|
||||
},
|
||||
callback
|
||||
];
|
||||
X.pack_stream.flush();
|
||||
};
|
||||
|
||||
ext.Capable = function(callback)
|
||||
{
|
||||
X.seq_num++;
|
||||
X.pack_stream.pack('CCS', [ext.majorOpcode, 1, 1]);
|
||||
X.replies[X.seq_num] = [
|
||||
function(buf, opt) {
|
||||
var res = buf.unpack('C');
|
||||
return res;
|
||||
},
|
||||
callback
|
||||
];
|
||||
X.pack_stream.flush();
|
||||
};
|
||||
|
||||
ext.GetTimeouts = function(callback)
|
||||
{
|
||||
X.seq_num++;
|
||||
X.pack_stream.pack('CCS', [ext.majorOpcode, 2, 1]);
|
||||
X.replies[X.seq_num] = [
|
||||
function(buf, opt) {
|
||||
var res = buf.unpack('SSS');
|
||||
return res;
|
||||
},
|
||||
callback
|
||||
];
|
||||
X.pack_stream.flush();
|
||||
};
|
||||
|
||||
ext.SetTimeouts = function(standby_t, suspend_t, off_t)
|
||||
{
|
||||
X.seq_num++;
|
||||
X.pack_stream.pack('CCSSSSxx', [ext.majorOpcode, 3, 3, standby_t, suspend_t, off_t]);
|
||||
X.pack_stream.flush();
|
||||
};
|
||||
|
||||
ext.Enable = function()
|
||||
{
|
||||
X.seq_num++;
|
||||
X.pack_stream.pack('CCS', [ext.majorOpcode, 4, 1]);
|
||||
X.pack_stream.flush();
|
||||
};
|
||||
|
||||
ext.Disable = function()
|
||||
{
|
||||
X.seq_num++;
|
||||
X.pack_stream.pack('CCS', [ext.majorOpcode, 5, 1]);
|
||||
X.pack_stream.flush();
|
||||
};
|
||||
|
||||
ext.ForceLevel = function(level) // 0 : On, 1 : Standby, 2 : Suspend, 3 : Off
|
||||
{
|
||||
X.seq_num++;
|
||||
X.pack_stream.pack('CCSSxx', [ext.majorOpcode, 6, 2, level]);
|
||||
X.pack_stream.flush();
|
||||
};
|
||||
|
||||
ext.Info = function(callback)
|
||||
{
|
||||
X.seq_num++;
|
||||
X.pack_stream.pack('CCS', [ext.majorOpcode, 7, 1]);
|
||||
X.replies[X.seq_num] = [
|
||||
function(buf, opt) {
|
||||
var res = buf.unpack('SC');
|
||||
return res;
|
||||
},
|
||||
callback
|
||||
];
|
||||
X.pack_stream.flush();
|
||||
};
|
||||
|
||||
callback(ext);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ exports.requireExt = function(display, callback)
|
|||
|
||||
if (!ext.present)
|
||||
{
|
||||
callback(new Error('extension not available'));
|
||||
return callback(new Error('extension not available'));
|
||||
}
|
||||
|
||||
ext.QueryVersion = function(clientMaj, clientMin, callback)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ exports.requireExt = function(display, callback)
|
|||
X.QueryExtension('SHAPE', function(err, ext) {
|
||||
|
||||
if (!ext.present)
|
||||
callback(new Error('extension not available'));
|
||||
return callback(new Error('extension not available'));
|
||||
|
||||
ext.Kind = {
|
||||
Bounding: 0,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ exports.requireExt = function(display, callback)
|
|||
X.QueryExtension('XC-MISC', function(err, ext) {
|
||||
|
||||
if (!ext.present)
|
||||
callback(new Error('extension not available'));
|
||||
return callback(new Error('extension not available'));
|
||||
|
||||
ext.QueryVersion = function(clientMaj, clientMin, cb)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,16 +8,18 @@ exports.requireExt = function(display, callback)
|
|||
X.QueryExtension('XTEST', function(err, ext) {
|
||||
|
||||
if (!ext.present)
|
||||
callback(new Error('extension not available'));
|
||||
return callback(new Error('extension not available'));
|
||||
|
||||
ext.QueryVersion = function(clientMaj, clientMin, callback)
|
||||
ext.GetVersion = function(clientMaj, clientMin, callback)
|
||||
{
|
||||
X.seq_num++;
|
||||
X.pack_stream.pack('CCSLL', [ext.majorOpcode, 0, 3, clientMaj, clientMin]);
|
||||
X.pack_stream.pack('CCSCxS', [ext.majorOpcode, 0, 2, clientMaj, clientMin]);
|
||||
X.replies[X.seq_num] = [
|
||||
function(buf, opt) {
|
||||
var res = buf.unpack('LL');
|
||||
return res;
|
||||
var res = buf.unpack('S');
|
||||
// Major version is in byte 1 of Reply Header
|
||||
// Minor version is in the body of the reply
|
||||
return [ opt, res[0] ];
|
||||
},
|
||||
callback
|
||||
];
|
||||
|
|
|
|||
|
|
@ -290,19 +290,19 @@ XClient.prototype.unpackEvent = function(type, seq, extra, code, raw)
|
|||
event.name = 'SelectionRequest';
|
||||
event.time = extra;
|
||||
var values = raw.unpack('LLLLL');
|
||||
event.owner = raw[0];
|
||||
event.requestor = raw[1];
|
||||
event.selection = raw[2];
|
||||
event.target = raw[3];
|
||||
event.property = raw[4];
|
||||
event.owner = values[0];
|
||||
event.requestor = values[1];
|
||||
event.selection = values[2];
|
||||
event.target = values[3];
|
||||
event.property = values[4];
|
||||
} else if (type == 31) {// SelectionNotify
|
||||
event.name = 'SelectionNotify';
|
||||
event.time = extra;
|
||||
var values = raw.unpack('LLLL');
|
||||
event.requestor = raw[0];
|
||||
event.selection = raw[1];
|
||||
event.target = raw[2];
|
||||
event.property = raw[3];
|
||||
event.requestor = values[0];
|
||||
event.selection = values[1];
|
||||
event.target = values[2];
|
||||
event.property = values[3];
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
|
|
|||
14
package.json
14
package.json
|
|
@ -3,7 +3,7 @@
|
|||
, "description": "A pure node.js JavaScript client implementing X Window (X11) protocol."
|
||||
, "keywords": ["X Window", "ui", "gui", "widgets", "desktop", "XWindow", "X"]
|
||||
, "homepage": "https://github.com/sidorares/node-x11"
|
||||
, "version" : "0.0.10"
|
||||
, "version" : "0.0.11"
|
||||
, "maintainers" :
|
||||
[ { "name": "Andrey Sidorov"
|
||||
, "email": "sidoares@yandex.ru"
|
||||
|
|
@ -11,19 +11,17 @@
|
|||
]
|
||||
, "bugs" : { "url" : "http://github.com/sidorares/node-x11/issues" }
|
||||
, "licenses" : [ { "type" : "MIT" } ]
|
||||
, "repositories" :
|
||||
[ { "type" : "git"
|
||||
, "url" : "http://github.com/sidorares/node-x11"
|
||||
}
|
||||
]
|
||||
, "repository" : { "type" : "git", "url" : "http://github.com/sidorares/node-x11.git" }
|
||||
|
||||
, "main" : "./lib/x11"
|
||||
, "engines" : { "node" : "*" }
|
||||
, "devDependencies": {
|
||||
"mocha": "*",
|
||||
"should": "*"
|
||||
"should": "*",
|
||||
"async": "*"
|
||||
}
|
||||
, "scripts": {
|
||||
"test": "mocha -t 80000",
|
||||
"test": "node test-runner.js",
|
||||
"prepublish" : "npm prune"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
89
test-runner.js
Normal file
89
test-runner.js
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
var x11 = require('./lib/x11');
|
||||
var Mocha = require('mocha');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var util = require('util');
|
||||
var async = require('async');
|
||||
|
||||
var mocha = new Mocha({
|
||||
timeout : 80000
|
||||
});
|
||||
|
||||
// To be able to perform the tests we need the server:
|
||||
// 1 - to support the dpms extension.
|
||||
// 2 - dpms version is 1.1.
|
||||
// 3 - to be dpms capable.
|
||||
var run_dpms_test = function(cb) {
|
||||
var client = x11.createClient(function(dpy) {
|
||||
var display = dpy;
|
||||
var X = display.client;
|
||||
X.require('dpms', function(ext) {
|
||||
if (!util.isError(ext)) {
|
||||
dpms = ext;
|
||||
dpms.GetVersion(undefined, undefined, function(err, version) {
|
||||
if (!err && version[0] === 1 && version[1] === 1) {
|
||||
dpms.Capable(function(err, capable) {
|
||||
if (!err && capable[0] == 1) cb(true);
|
||||
else cb(false);
|
||||
});
|
||||
} else {
|
||||
cb(false);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
cb(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
client.on('error', function() {
|
||||
cb(false);
|
||||
});
|
||||
};
|
||||
|
||||
var run_xtest_test = function(cb) {
|
||||
var client = x11.createClient(function(dpy) {
|
||||
var display = dpy;
|
||||
var X = display.client;
|
||||
X.require('dpms', function(ext) {
|
||||
if (!util.isError(ext)) cb(true);
|
||||
else cb(false);
|
||||
});
|
||||
});
|
||||
|
||||
client.on('error', function() {
|
||||
cb(false);
|
||||
});
|
||||
};
|
||||
|
||||
// Add all files from test root directory
|
||||
async.forEach(
|
||||
fs.readdirSync('./test'),
|
||||
function(file, cb) {
|
||||
if (file === 'dpms.js') {
|
||||
run_dpms_test(function(run) {
|
||||
if (run) {
|
||||
mocha.addFile(path.join('./test', file));
|
||||
}
|
||||
|
||||
cb();
|
||||
});
|
||||
} else if (file === 'xtest.js') {
|
||||
run_xtest_test(function(run) {
|
||||
if (run) {
|
||||
mocha.addFile(path.join('./test', file));
|
||||
}
|
||||
|
||||
cb();
|
||||
});
|
||||
} else {
|
||||
mocha.addFile(path.join('./test', file));
|
||||
cb();
|
||||
}
|
||||
},
|
||||
function(err) {
|
||||
mocha.run(function() {
|
||||
process.exit();
|
||||
});
|
||||
}
|
||||
);
|
||||
101
test/dpms.js
Normal file
101
test/dpms.js
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
var x11 = require('../lib/x11');
|
||||
var should = require('should');
|
||||
var assert = require('assert');
|
||||
var util = require('util');
|
||||
|
||||
describe('DPMS extension', function() {
|
||||
var display;
|
||||
var X;
|
||||
var dpms;
|
||||
before(function(done) {
|
||||
var client = x11.createClient(function(dpy) {
|
||||
display = dpy;
|
||||
X = display.client;
|
||||
X.require('dpms', function(ext) {
|
||||
if (util.isError(ext)) {
|
||||
done(ext);
|
||||
} else {
|
||||
dpms = ext;
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
client.on('error', done);
|
||||
});
|
||||
|
||||
describe('Setting the DPMS timeouts to specific values', function() {
|
||||
|
||||
var prev_timeouts;
|
||||
before(function(done) {
|
||||
dpms.GetTimeouts(function(err, timeouts) {
|
||||
prev_timeouts = timeouts;
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('GetTimeouts should return those values', function(done) {
|
||||
dpms.SetTimeouts(110, 110, 110);
|
||||
dpms.GetTimeouts(function(err, timeouts) {
|
||||
if (!err) timeouts.should.eql([110, 110, 110]);
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
dpms.SetTimeouts(prev_timeouts[0], prev_timeouts[1], prev_timeouts[2]);
|
||||
dpms.GetTimeouts(function(err, timeouts) {
|
||||
if (!err) timeouts.should.eql(prev_timeouts);
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Changing status and level of DPMS', function() {
|
||||
var prev_status;
|
||||
var prev_level;
|
||||
before(function(done) {
|
||||
dpms.Info(function(err, info) {
|
||||
if (!err) {
|
||||
prev_level = info[0];
|
||||
prev_status = info[1];
|
||||
}
|
||||
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('Info should return the correct values', function(done) {
|
||||
if (prev_status === 0) dpms.Enable(); // for force level to work dpms must be enabled
|
||||
var new_level = prev_level === 0 ? 1 : 0;
|
||||
dpms.ForceLevel(new_level);
|
||||
dpms.Info(function(err, info) {
|
||||
if (!err) {
|
||||
info[0].should.equal(new_level);
|
||||
info[1].should.equal(1);
|
||||
}
|
||||
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
dpms.ForceLevel(prev_level);
|
||||
if (prev_status) dpms.Enable();
|
||||
else dpms.Disable();
|
||||
dpms.Info(function(err, info) {
|
||||
if (!err) {
|
||||
info[0].should.equal(prev_level);
|
||||
info[1].should.equal(prev_status);
|
||||
}
|
||||
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
X.terminate();
|
||||
X.on('end', done);
|
||||
});
|
||||
});
|
||||
40
test/xtest.js
Normal file
40
test/xtest.js
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
var x11 = require('../lib/x11');
|
||||
var should = require('should');
|
||||
var assert = require('assert');
|
||||
var util = require('util');
|
||||
|
||||
describe('XTEST extension', function() {
|
||||
var display;
|
||||
var X;
|
||||
var xtest;
|
||||
before(function(done) {
|
||||
var client = x11.createClient(function(dpy) {
|
||||
display = dpy;
|
||||
X = display.client;
|
||||
X.require('xtest', function(ext) {
|
||||
if (util.isError(ext)) {
|
||||
done(ext);
|
||||
} else {
|
||||
xtest = ext;
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
client.on('error', done);
|
||||
});
|
||||
|
||||
describe('GetVersion', function() {
|
||||
it('should return version 2.2', function(done) {
|
||||
xtest.GetVersion(2, 2, function(err, version) {
|
||||
version.should.eql([2, 2]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
X.terminate();
|
||||
X.on('end', done);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue