Merge pull request #20 from santigimeno/new_create_client

Change createClient signature
This commit is contained in:
Andrey Sidorov 2012-12-19 01:22:52 -08:00
commit 568465da52
13 changed files with 177 additions and 117 deletions

View file

@ -5,7 +5,7 @@
`npm install x11`
Windows users:
1) install [XMing](http://www.straightrunning.com/XmingNotes/) or [Cygwin/X](http://x.cygwin.com/)
1) install [XMing](http://www.straightrunning.com/XmingNotes/) or [Cygwin/X](http://x.cygwin.com/)
2) get node-x11 copy (using [git](http://code.google.com/p/msysgit/downloads/list?can=3) or from [Github](https://github.com/sidorares/node-x11/archives/master ))
#CI build status:
@ -14,42 +14,46 @@ Windows users:
# example
Core requsests usage:
Core requests usage:
var x11 = require('x11');
var Exposure = x11.eventMask.Exposure;
var PointerMotion = x11.eventMask.PointerMotion;
x11.createClient(function(display) {
var X = display.client;
var root = display.screen[0].root;
var wid = X.AllocID();
X.CreateWindow(
wid, root, // new window id, parent
0, 0, 100, 100, // x, y, w, h
0, 0, 0, 0, // border, depth, class, visual
{ eventMask: Exposure|PointerMotion } // other parameters
);
X.MapWindow(wid);
var gc = X.AllocID();
X.CreateGC(gc, wid);
X.on('event', function(ev) {
if (ev.type == 12)
{
X.PolyText8(wid, gc, 50, 50, ['Hello, Node.JS!']);
}
});
X.on('error', function(e) {
console.log(e);
});
x11.createClient(function(err, display) {
if (!err) {
var X = display.client;
var root = display.screen[0].root;
var wid = X.AllocID();
X.CreateWindow(
wid, root, // new window id, parent
0, 0, 100, 100, // x, y, w, h
0, 0, 0, 0, // border, depth, class, visual
{ eventMask: Exposure|PointerMotion } // other parameters
);
X.MapWindow(wid);
var gc = X.AllocID();
X.CreateGC(gc, wid);
X.on('event', function(ev) {
if (ev.type == 12)
{
X.PolyText8(wid, gc, 50, 50, ['Hello, Node.JS!']);
}
});
X.on('error', function(e) {
console.log(e);
});
} else {
console.log(err);
}
});
# Screenshots
![tetris game](https://lh6.googleusercontent.com/-RCRY9A7WwnA/Tlww0FHP7NI/AAAAAAAAAwo/nxfSxsw6xow/s400/tetris.png)
![XRENDER gradients](https://lh4.googleusercontent.com/-VS0BMYYmq6M/Tlww0Y1ij0I/AAAAAAAAAws/pVWsPZ63Yeo/s400/render-gradients.png)
# Protocol documentation
@ -59,7 +63,7 @@ Core requsests usage:
# Other implementations
- C: XLib - http://www.sbin.org/doc/Xlib/ http://www.tronche.com/gui/x/xlib/ http://www.x.org/docs/X11/xlib.pdf
- 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

View file

@ -430,15 +430,18 @@ XClient.prototype.require = function(extName, callback)
ext.requireExt(this.display, callback);
}
module.exports.createClient = function(initCb, display, options)
module.exports.createClient = function(options, initCb)
{
if (!options)
options = false;
if (typeof options === 'function') {
initCb = options;
options = {};
}
if (!options) options = {};
var display = options.display;
if (!display)
display = process.env.DISPLAY;
if (!display)
display = ':0';
display = (process.env.DISPLAY) ? process.env.DISPLAY : ':0';
var displayMatch = display.match(/^(?:[^:]*?\/)?(.*):(\d+)(?:.(\d+))?$/);
if (!displayMatch)
@ -485,18 +488,25 @@ module.exports.createClient = function(initCb, display, options)
if (initCb)
{
client.on('connect', function(display) {
// Once connected don't call initCb on error, just emit
stream.removeListener('error', initCb);
stream.on('error', function(err) {
client.emit('error', err);
});
// opt-in BigReq
if (!options.disableBigRequests) {
client.require('big-requests', function(BigReq) {
BigReq.Enable(function(err, maxLen) {
display.max_request_length = maxLen;
initCb(display);
initCb(undefined, display);
});
});
} else {
initCb(display);
initCb(undefined, display);
}
});
}
return client;
stream.on('error', initCb);
}
return client;
}

View file

@ -14,7 +14,8 @@ var mocha = new Mocha({
// 2 - dpms version is 1.1.
// 3 - to be dpms capable.
var run_dpms_test = function(cb) {
var client = x11.createClient(function(dpy) {
var client = x11.createClient(function(err, dpy) {
if (err) return cb(false);
var display = dpy;
var X = display.client;
X.require('dpms', function(ext) {
@ -42,7 +43,8 @@ var run_dpms_test = function(cb) {
};
var run_xtest_test = function(cb) {
var client = x11.createClient(function(dpy) {
var client = x11.createClient(function(err, dpy) {
if (err) return cb(false);
var display = dpy;
var X = display.client;
X.require('dpms', function(ext) {

View file

@ -1,16 +1,22 @@
var x11 = require('../lib/x11');
var should = require('should');
var assert = require('assert');
var util = require('util');
describe('Client', function() {
var display;
beforeEach(function(done) {
var client = x11.createClient(function(dpy) {
display=dpy;
done();
client.removeListener('error', done);
var client = x11.createClient(function(err, dpy) {
if (!err) {
display = dpy;
done();
client.removeListener('error', done);
} else {
done(err);
}
});
client.on('error', done);
});
@ -22,13 +28,11 @@ describe('Client', function() {
should.exist(display.major);
done();
});
it('uses display variable from parameter if present ignoring anvironment $DISPLAY', function(done) {
var disp = process.env.DISPLAY;
process.env.DISPLAY = 'BOGUS DISPLAY';
var client = x11.createClient(function(display) {
done();
}, disp);
var client = x11.createClient({ display : disp }, done);
client.on('error', done);
process.env.DISPLAY=disp;
});
@ -36,14 +40,21 @@ describe('Client', function() {
it('throws error if $DISPLAY is bogus', function(done) {
try {
assert.throws(function() {
var client = x11.createClient(function(display) {
var client = x11.createClient({ display : 'BOGUS DISPLAY' }, function(err, display) {
done('Should not reach here');
}, 'BOGUS DISPLAY');
});
client.on('error', function(err) { done(); });
}, /Cannot parse display/);
done();
} catch(e) {
done();
done();
}
});
it('returns error when connecting to non existent display', function(done) {
var client = x11.createClient({ display : ':44' }, function(err, display) {
assert(util.isError(err));
done();
});
});
});

View file

@ -6,12 +6,16 @@ describe('Client', function() {
var display;
beforeEach(function(done) {
var client = x11.createClient(function(dpy) {
display=dpy;
done();
client.removeListener('error', done);
});
client.on('error', done);
var client = x11.createClient(function(err, dpy) {
if (!err) {
display = dpy;
done();
client.removeListener('error', done);
} else {
done(err);
}
});
client.on('error', done);
});
it('should respond to ping()', function(done) {
@ -21,7 +25,7 @@ describe('Client', function() {
it('should allow to enqueue requests and gracefully execute them before close()', function(done) {
var count = 0;
var pong = function(err) { if (err) return done(err); count++; }
display.client.ping(pong);
display.client.ping(pong);
display.client.ping(pong);
display.client.ping(pong);
display.client.ping(pong);

View file

@ -12,10 +12,13 @@ describe('CreateWindow request', function() {
var display;
var X;
beforeEach(function(done) {
var client = x11.createClient(function(dpy) {
display=dpy;
X = display.client;
done();
var client = x11.createClient(function(err, dpy) {
if (!err) {
display = dpy;
X = display.client;
}
done(err);
});
client.on('error', done);
});

View file

@ -7,10 +7,13 @@ describe('ForceScreenSaver request', function() {
var display;
var X;
beforeEach(function(done) {
var client = x11.createClient(function(dpy) {
display=dpy;
X = display.client;
done();
var client = x11.createClient(function(err, dpy) {
if (!err) {
display = dpy;
X = display.client;
}
done(err);
});
client.on('error', done);
});

View file

@ -7,13 +7,15 @@ describe('KillKlient request', function() {
var display;
var X;
beforeEach(function(done) {
var client = x11.createClient(function(dpy) {
display=dpy;
X = display.client;
done();
var client = x11.createClient(function(err, dpy) {
if (!err) {
display = dpy;
X = display.client;
}
done(err);
});
client.on('error', function(err) {
console.log(err);
done(err);
});
});
@ -32,12 +34,16 @@ describe('KillKlient request', function() {
});
it('should terminate other client connection', function(done) {
x11.createClient(function(dpy) {
var otherclient = dpy.client;
var wnd = otherclient.AllocID();
otherclient.CreateWindow(wnd, dpy.screen[0].root, 0, 0, 1, 1);
otherclient.on('end', done);
X.KillKlient(wnd);
x11.createClient(function(err, dpy) {
if (!err) {
var otherclient = dpy.client;
var wnd = otherclient.AllocID();
otherclient.CreateWindow(wnd, dpy.screen[0].root, 0, 0, 1, 1);
otherclient.on('end', done);
X.KillKlient(wnd);
} else {
done(err);
}
});
});

View file

@ -13,13 +13,17 @@ describe('Window property', function() {
var X;
var wid;
beforeEach(function(done) {
var client = x11.createClient(function(dpy) {
display=dpy;
X = display.client;
wid = X.AllocID();
X.CreateWindow(wid, display.screen[0].root, 0, 0, 100, 100, 0, 0, 0, 0, { eventMask: x11.eventMask.PropertyChange});
done();
client.removeListener('error', done); // all future errors should be attached to corresponding test 'done'
var client = x11.createClient(function(err, dpy) {
if (!err) {
display = dpy;
X = display.client;
wid = X.AllocID();
X.CreateWindow(wid, display.screen[0].root, 0, 0, 100, 100, 0, 0, 0, 0, { eventMask: x11.eventMask.PropertyChange});
done();
client.removeListener('error', done); // all future errors should be attached to corresponding test 'done'
} else {
done(err);
}
});
client.on('error', done);
});
@ -38,7 +42,7 @@ describe('Window property', function() {
X.GetProperty(0, wid, X.atoms.WM_NAME, X.atoms.STRING, 0, 10000000, function(err, prop) {
if (err) return done(err);
var propvalget = prop.data.toString();
assert.equal(propvalset, propvalget, 'get property result different from set property value');
assert.equal(propvalset, propvalget, 'get property result different from set property value');
done();
});
});
@ -60,7 +64,7 @@ describe('Window property', function() {
done('unexpexted event');
});
});
it('should not exist after DeleteProperty called', function(done) {
X.on('error', done);
var propvalset = "some property value";
@ -68,7 +72,7 @@ describe('Window property', function() {
X.GetProperty(0, wid, X.atoms.WM_NAME, X.atoms.STRING, 0, 10000000, function(err, prop) {
if (err) return done(err);
var propvalget = prop.data.toString();
assert.equal(propvalset, propvalget, 'get property result different from set property value');
assert.equal(propvalset, propvalget, 'get property result different from set property value');
X.DeleteProperty(wid, X.atoms.WM_NAME);
X.GetProperty(0, wid, X.atoms.WM_NAME, X.atoms.STRING, 0, 10000000, function(err, prop) {
assert.equal(prop.type, 0, 'non-existent property type should be 0');

View file

@ -8,17 +8,21 @@ describe('DPMS extension', function() {
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();
}
});
var client = x11.createClient(function(err, dpy) {
if (!err) {
display = dpy;
X = display.client;
X.require('dpms', function(ext) {
if (util.isError(ext)) {
done(ext);
} else {
dpms = ext;
done();
}
});
} else {
done(err);
}
});
client.on('error', done);

View file

@ -6,13 +6,14 @@ describe('Client', function() {
var display;
beforeEach(function(done) {
var client = x11.createClient(function(dpy) {
display=dpy;
done();
});
var client = x11.createClient(function(err, dpy) {
console.log(err)
display = dpy;
done(err);
});
});
it('should emit error which is instance of Error with seqence number corresponding to source request', function(done) {
it('should emit error which is instance of Error with sequence number corresponding to source request', function(done) {
display.client.options.debug = true;
display.client.CreateWindow(); // should emit error
var seq = display.client.seq_num;

View file

@ -6,10 +6,14 @@ describe('Client', function() {
var display;
beforeEach(function(done) {
var client = x11.createClient(function(dpy) {
display=dpy;
done();
client.removeListener('error', done);
var client = x11.createClient(function(err, dpy) {
if (!err) {
display = dpy;
done();
client.removeListener('error', done);
} else {
done(err);
}
});
client.on('error', done);
});
@ -33,7 +37,7 @@ describe('Client', function() {
left--;
display.client.GetAtomName(1, test);
}
left++;
test(); // first call starts sequens and not a callback from GetAtomName, thus left++
});

View file

@ -8,17 +8,21 @@ describe('XTEST extension', function() {
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();
}
});
var client = x11.createClient(function(err, dpy) {
if (!err) {
display = dpy;
X = display.client;
X.require('xtest', function(ext) {
if (util.isError(ext)) {
done(ext);
} else {
xtest = ext;
done();
}
});
} else {
done(err);
}
});
client.on('error', done);