Compare commits

..

No commits in common. "master" and "1.0.2" have entirely different histories.

62 changed files with 1919 additions and 5481 deletions

4
.gitignore vendored
View file

@ -1,4 +0,0 @@
*.log
yarn.lock
package-lock.json
node_modules

View file

@ -1,16 +1,7 @@
before_script: before_script:
- "export XAUTHORITY=/tmp/.Xauthority-Xvfb" - "export DISPLAY=:99.0"
- "xauth add :99 . $(mcookie)" - "sh -e /etc/init.d/xvfb start"
- "xauth add 127.0.0.2:99 . $(mcookie)"
- "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -nolisten $NOLISTEN -auth $XAUTHORITY"
- "sleep 1"
env:
- NOLISTEN=tcp DISPLAY=:99.0
# - NOLISTEN=unix DISPLAY=:99.0
# - NOLISTEN=unix DISPLAY=127.0.0.2:99.0
language: node_js language: node_js
node_js: node_js:
- '12' - 0.10
- '14'

View file

@ -1,2 +0,0 @@
1.0.3 - 19/02/2015
- cleanup debug logs #83

169
README.md
View file

@ -1,119 +1,92 @@
# node-x11 # About
[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/sidorares/node-x11?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
X11 protocol client for node.js
X11 protocol client for Node.js: implements the core X11 protocol, as well as Xrender, Damage, Composite, Big-Requests, Dpms, Screensaver, XFixes, Shape, XTest, XC-Misc, GLX, and Apple-WM extensions. Implements core X11 protocol, as well as Xrender, Damage, Composite, Big-Requests, Dpms, Screensaver, XFixes, Shape, XTest, XC-Misc, GLX and Apple-WM extensions.
# install
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/sidorares/node-x11?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) `npm install x11`
[![Build Status](https://secure.travis-ci.org/sidorares/node-x11.png)](http://travis-ci.org/sidorares/node-x11)
## Install
npm install x11
Windows users: Windows users:
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 ))
1. install [XMing](http://www.straightrunning.com/XmingNotes/) or [Cygwin/X](http://x.cygwin.com/) #CI build status:
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))
## Example [![Build Status](https://secure.travis-ci.org/sidorares/node-x11.png)](http://travis-ci.org/sidorares/node-x11)
# example
Core requests usage: Core requests usage:
```js var x11 = require('x11');
var x11 = require('x11');
var Exposure = x11.eventMask.Exposure; var Exposure = x11.eventMask.Exposure;
var PointerMotion = x11.eventMask.PointerMotion; var PointerMotion = x11.eventMask.PointerMotion;
x11.createClient(function(err, display) { x11.createClient(function(err, display) {
if (!err) { if (!err) {
var X = display.client; var X = display.client;
var root = display.screen[0].root; var root = display.screen[0].root;
var wid = X.AllocID(); var wid = X.AllocID();
X.CreateWindow( X.CreateWindow(
wid, wid, root, // new window id, parent
root, // new window id, parent 0, 0, 100, 100, // x, y, w, h
0, 0, 0, 0, 0, // border, depth, class, visual
0, { eventMask: Exposure|PointerMotion } // other parameters
500, );
500, // x, y, w, h X.MapWindow(wid);
0, var gc = X.AllocID();
0, X.CreateGC(gc, wid);
0, X.on('event', function(ev) {
0, // border, depth, class, visual if (ev.type == 12)
{ eventMask: Exposure | PointerMotion } // other parameters {
); X.PolyText8(wid, gc, 50, 50, ['Hello, Node.JS!']);
X.MapWindow(wid); }
var gc = X.AllocID(); });
X.CreateGC(gc, wid); X.on('error', function(e) {
var white = display.screen[0].white_pixel; console.log(e);
var black = display.screen[0].black_pixel; });
cidBlack = X.AllocID(); } else {
cidWhite = X.AllocID(); console.log(err);
X.CreateGC(cidBlack, wid, { foreground: black, background: white }); }
X.CreateGC(cidWhite, wid, { foreground: white, background: black });
X.on('event', function(ev) {
if (ev.type == 12) {
X.PolyFillRectangle(wid, cidWhite, [0, 0, 500, 500]);
X.PolyText8(wid, cidBlack, 50, 50, ['Hello, Node.JS!']);
}
}); });
X.on('error', function(e) {
console.log(e);
});
} else {
console.log(err);
}
});
```
## Screenshots # Screenshots
![tetris game](https://lh6.googleusercontent.com/-RCRY9A7WwnA/Tlww0FHP7NI/AAAAAAAAAwo/nxfSxsw6xow/s400/tetris.png) ![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) ![XRENDER gradients](https://lh4.googleusercontent.com/-VS0BMYYmq6M/Tlww0Y1ij0I/AAAAAAAAAws/pVWsPZ63Yeo/s400/render-gradients.png)
![OpenGL glxgears](http://img-fotki.yandex.ru/get/4123/37511094.30/0_81712_6c2ebb11_L) ![OpenGL glxgears](http://img-fotki.yandex.ru/get/4123/37511094.30/0_81712_6c2ebb11_L)
![OpenGL teapot](http://img-fotki.yandex.ru/get/4132/37511094.30/0_81713_82a5ac48_L) ![OpenGL teapot](http://img-fotki.yandex.ru/get/4132/37511094.30/0_81713_82a5ac48_L)
## In use # In use
- [ntk](https://github.com/sidorares/ntk) - higher level toolkit on top of X11
- [node-remote](https://github.com/AndrewSwerlick/node-remote) - metia center controller
- [tiles](https://github.com/dominictarr/tiles) - tiling window manager
- [vnc](https://github.com/sidorares/node-vnc) - vnc client.
- [node-ewmh](https://github.com/santigimeno/node-ewmh) - set of EWMH helpers.
- [OdieWM](https://github.com/bu/OdieWM) - window manager
- [Dbusmenu](https://github.com/sidorares/node-dbusmenu) - unity global menu client.
- [ntk](https://github.com/sidorares/ntk) - higher level toolkit on top of X11 # Protocol documentation
- [node-remote](https://github.com/AndrewSwerlick/node-remote) - media center controller
- [tiles](https://github.com/dominictarr/tiles) - tiling window manager
- [vnc](https://github.com/sidorares/node-vnc) - vnc client.
- [node-ewmh](https://github.com/santigimeno/node-ewmh) - set of EWMH helpers.
- [OdieWM](https://github.com/bu/OdieWM) - window manager
- [Dbusmenu](https://github.com/sidorares/node-dbusmenu) - unity global menu client.
- [AirWM](https://github.com/AirWM/AirWM) - tiling window manager
- [npdf](https://github.com/sidorares/npdf) - pdf viewer
- [tinywm](https://github.com/Airblader/node-tinywm) The famous [TinyWM](https://github.com/mackstann/tinywm) written in node.js
- [basedwm](https://github.com/anko/basedwm) Infinite-desktop panning X window manager in LiveScript
## X11 resources/documentation: - http://www.x.org/releases/X11R7.6/doc/
- http://www.x.org/releases/X11R7.6/doc/xproto/x11protocol.pdf
- C Xlib to X11 request mapping table http://tronche.com/gui/x/xlib/appendix/a.html
- [Xplain](https://github.com/magcius/xplain) - A series of articles to help explain the X Window System http://magcius.github.io/xplain/article/ # Other implementations
- [Official X11 docs](http://www.x.org/releases/X11R7.6/doc/)
- [protocol specification](http://www.x.org/releases/X11R7.6/doc/xproto/x11protocol.pdf)
- C Xlib to X11 request mapping table http://tronche.com/gui/x/xlib/appendix/a.html
- [How to write composite manager](http://www.talisman.org/~erlkonig/misc/x11-composite-tutorial/)
- [Extended Window Manager Hints specification](http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html)
## 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: 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 )
- https://github.com/alexer/python-xlib-render
- Python/twisted: https://launchpad.net/twisted-x11
- Perl: http://search.cpan.org/~smccam/X11-Protocol-0.56/Protocol.pm
- Go: https://github.com/BurntSushi/xgb
- Java: https://github.com/xderoche/J11
- Ruby: https://github.com/dj2/x-ruby-bindings
- Clojure: https://github.com/noodlewiz/xcljb
- Guile: https://github.com/mwitmer/guile-xcb
- C: XLib - http://www.sbin.org/doc/Xlib/ http://www.tronche.com/gui/x/xlib/ http://www.x.org/docs/X11/xlib.pdf [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/sidorares/node-x11/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
- 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 )
- https://github.com/alexer/python-xlib-render
- Python/twisted: https://launchpad.net/twisted-x11
- Perl: http://search.cpan.org/~smccam/X11-Protocol-0.56/Protocol.pm
- Go: https://github.com/BurntSushi/xgb
- Java: https://github.com/xderoche/J11
- Ruby: https://github.com/dj2/x-ruby-bindings
- Clojure: https://github.com/noodlewiz/xcljb
- Guile: https://github.com/mwitmer/guile-xcb
- Emacs lisp: https://github.com/ch11ng/xelb ( autogenerated from XCB XML )
## Server side (protocol + functionality) implementations for js + DOM
would be really great to make completely web based playground page, connecting node-x11 api to DOM based implementation
- https://github.com/GothAck/javascript-x-server
- https://github.com/ttaubert/x-server-js

View file

@ -252,7 +252,7 @@ function genReq(req, last)
if (req.body.length == 0) if (req.body.length == 0)
{ {
result.push(' function() {'); result.push(' function() {');
result.push(' return Buffer.from([' + req.opcode + ', 0, 1, 0]);'); result.push(' return new Buffer([' + req.opcode + ', 0, 1, 0]);');
} else { } else {
result.push(' function (args) {'); result.push(' function (args) {');
result.push(' var extraLength = 0;'); result.push(' var extraLength = 0;');
@ -287,10 +287,10 @@ function genReq(req, last)
var reqLen4 = ((reqLen + 3) >> 2); var reqLen4 = ((reqLen + 3) >> 2);
if (extraLength) if (extraLength)
result.push(' var data = Buffer.alloc(' + reqLen + ' + extraLength);'); result.push(' var data = new Buffer(' + reqLen + ' + extraLength);');
else { else {
result.pop(); result.pop();
result.push(' var data = Buffer.alloc(' + reqLen + ');'); result.push(' var data = new Buffer(' + reqLen + ');');
} }
result.push(' data[0] = ' + req.opcode + ';'); result.push(' data[0] = ' + req.opcode + ';');
if (req.body.length != 0) { if (req.body.length != 0) {

View file

@ -12,7 +12,7 @@ var ButtonRelease = x11.eventMask.ButtonRelease;
// image and coords file from http://www.patrick-wied.at/projects/heatmap-keyboard/ // image and coords file from http://www.patrick-wied.at/projects/heatmap-keyboard/
// TODO: add simple tool to use&tag coords in own keyboard photo // TODO: add simple tool to use&tag coords in own keyboard photo
// jpeg decoder is slightly modified version of https://github.com/notmasteryet/jpgjs // jpeg decoder is slightly modified version of https://github.com/notmasteryet/jpgjs
var kbdImg = require('./node-jpg').readJpeg(__dirname+'/keyboard.jpg'); var kbdImg = require('./node-jpg').readJpeg('./keyboard.jpg');
var keycoords = require('./coordinates'); var keycoords = require('./coordinates');
// from https://github.com/substack/node-keysym // from https://github.com/substack/node-keysym

View file

@ -571,7 +571,7 @@ module.exports.readJpeg = function(path)
var imageData = {}; var imageData = {};
imageData.width = j.width; imageData.width = j.width;
imageData.height = j.height; imageData.height = j.height;
imageData.data = Buffer.from(j.width*j.height*4); imageData.data = new Buffer(j.width*j.height*4);
j.copyToImageData(imageData); j.copyToImageData(imageData);
return imageData; return imageData;
} }

View file

@ -1,69 +0,0 @@
var x11 = require('..');
// The list provided by GetKeyboardMapping has sublists where each position
// represents the result for some key composition.
keyComposition = [
'Key',
'shift + Key',
'modeSwitch + Key',
'modeSwitch + shift + Key',
'altGr + Key',
'altGr + shift + Key'
]
x11.createClient(function(err, display){
if (err) throw err
var min = display.min_keycode, // TODO: explain min_keycode
max = display.max_keycode, // TODO: explain max_keycode
chr2Data = [], // allow us to find a char by the charcode
key2Data = []; // associate chars to a keycode
// The keySyms is a hash of mnemonic char names, associated to an integer
// charcode and its description.
for (codeName in x11.keySyms) {
keyData = x11.keySyms[codeName];
chr2Data[keyData.code] = { codeName: codeName, description: keyData.description };
}
var X = display.client,
wid = X.AllocID(), // Get a free integer id to a new window.
root = display.screen[0].root, // The mother window. Like your window manager.
evKeyPress = x11.eventMask.KeyPress, // Allow to filter for KeyPress events.
white = display.screen[0].white_pixel; // Will paint the window.
// Get the local key mapping to build key2Data.
X.GetKeyboardMapping(min, max-min, function(err, list) {
for (var i=0; i < list.length; ++i) {
var name = key2Data[i+min] = [];
var sublist = list[i];
for (var j=0; j < sublist.length; ++j)
name.push(chr2Data[sublist[j]]);
}
});
// Launch a window to listen by key events:
X.CreateWindow(wid, root, 0, 0, 100, 100, 0, 0, 0, 0, { backgroundPixel: white, eventMask: evKeyPress });
X.MapWindow(wid);
X.on('event', function(ev) {
if (ev.type == 2) { // filter by KeyPress. Useful if you have a more open eventMask.
var key = key2Data[ev.keycode]; // key is a list of chars related to the pressed key.
if (key) {
console.log('\n>> key pressed:', ev.keycode);
for (var i=0; i<key.length; i++) // Describe each related char
if (key[i])
console.log(
key[i].codeName, '\t', (
key[i].description ? key[i].description : 'no description'
), (
keyComposition[i] ? '\t' + keyComposition[i] : ''
)
);
}
else
console.log('>> keyCode '+ ev.keycode +' was not recognized.');
}
});
});

View file

@ -874,7 +874,7 @@ module.exports.readPng = function(path)
var imageData = {}; var imageData = {};
imageData.width = j.width; imageData.width = j.width;
imageData.height = j.height; imageData.height = j.height;
imageData.data = Buffer.alloc(j.width*j.height*4); imageData.data = new Buffer(j.width*j.height*4);
j.render(imageData); j.render(imageData);
return imageData; return imageData;
} }

View file

@ -1,344 +0,0 @@
/*
* Simple png decoder
* https://github.com/b37t1td/png-decoder
*/
var CRCTable = new Int32Array([
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
]);
var crc32 = function(buf) {
var crc = -1;
for (var i = 0; i < buf.length; i++) {
crc = CRCTable[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8);
}
return crc ^ -1;
};
/*
* BE byteArray implementation
* by Svetlana Linuxenko <linuxenko@yahoo.com>
*/
/* eslint no-undef: 0 */
var byteArray = Uint8Array;
var cmp = function(a, b) {
if (!b) b = a; a = this;
return a.filter(function(c,i) { return c === b[i]; }).length === a.length;
};
var toInt = function(a) {
if (!a) a = this.slice(this.off, 4);
return (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3];
//return a[0] | (a[1] << 8) | (a[2] << 16) | (a[3] << 24);
};
var toBytes = function(int) {
return new byteArray([
(int >> 24) & 0xff,
(int >> 16) & 0xff,
(int >> 8) & 0xff,
int & 0xff
]);
};
var nextInt = function() {
return this.toInt(this.slice(this.off, (this.off += 4)));
};
var nextIntBytes = function() {
return this.nextBytes(4);
};
var nextBytes = function(size) {
return this.slice(this.off, (this.off += size));
};
var nextByte = function() {
return this.nextBytes(1)[0];
};
var insertInt = function(int) {
this.insertBytes(this.toBytes(int));
};
var insertBytes = function(bytes, length) {
length = length || 4;
this.set(bytes, this.off, length);
this.off += length;
};
var insertByte = function(byte) {
this.set([byte], this.off, (this.off += 1));
};
byteArray.prototype.cmp = cmp;
byteArray.prototype.toInt = toInt;
byteArray.prototype.nextInt = nextInt;
byteArray.prototype.nextIntBytes = nextIntBytes;
byteArray.prototype.toBytes = toBytes;
byteArray.prototype.insertInt = insertInt;
byteArray.prototype.insertBytes = insertBytes;
byteArray.prototype.nextBytes = nextBytes;
byteArray.prototype.nextByte = nextByte;
byteArray.prototype.insertByte = insertByte;
Object.defineProperty(byteArray.prototype , 'off', {
enumerable: false,
configurable: false,
writable: true,
value : 0
});
var SIGNATURE = new byteArray([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
var IHDR = new byteArray([0x49, 0x48, 0x44, 0x52]);
var IDAT = new byteArray([0x49, 0x44, 0x41, 0x54]);
var IEND = new byteArray([0x49, 0x45, 0x4e, 0x44]);
/*
* Decoder
*/
var zlib = require('zlib');
var inflateFunction = function(data) {
return zlib.inflateSync(Buffer.from(data));
};
var Decoder = function() { };
Decoder.prototype.parse = function(data) {
if (!(data instanceof byteArray)) {
data = new byteArray(data);
}
if (!SIGNATURE.cmp(data.nextBytes(SIGNATURE.length))) {
throw new Error('Not png');
}
while (data.off < data.length) {
var len = data.nextInt();
var hdr = data.nextBytes(len + 4);
if (crc32(hdr) !== data.nextInt()) {
throw new Error('Crc error');
}
if (IHDR.cmp(hdr)) {
this._IHDR = this._chunkIHDR(hdr.slice(4, len + 4));
if (this._IHDR.palette !== 8) {
throw new Error('Depth error');
}
if (this._IHDR.compression !== 0) {
throw new Error('Compression error');
}
if (this._IHDR.filter !== 0) {
throw new Error('Filter error');
}
if (this._IHDR.interlace !== 0) {
throw new Error('Interlace error');
}
switch (this._IHDR.colorType){
case 0: this.bpp = 1; break;
case 2: this.bpp = 3; break;
case 3: this.bpp = 1; break;
case 4: this.bpp = 2; break;
case 6: this.bpp = 4; break;
default: throw new Error('ColorType error');
}
this.chunks = [];
}
if (IDAT.cmp(hdr)) {
if (!this._IHDR) {
throw new Error('IHDR error');
}
this._chunkIDAT(hdr.slice(4, len + 4));
}
if (IEND.cmp(hdr)) {
return this._chunkIEND();
}
}
throw new Error('Data error');
};
Decoder.prototype._chunkIEND = function() {
var tmp = [];
for (var i = 0; i < this.chunks.length; i++) {
for (var j = 0; j < this.chunks[i].length; j++) {
tmp.push(this.chunks[i][j]);
}
}
return this.filter(inflateFunction(tmp));
};
Decoder.prototype._chunkIDAT = function(chunk) {
this.chunks.push(chunk);
};
Decoder.prototype._chunkIHDR = function(chunk) {
return {
width : chunk.nextInt(),
height : chunk.nextInt(),
palette : chunk.nextByte(),
colorType : chunk.nextByte(),
compression : chunk.nextByte(),
filter : chunk.nextByte(),
interlace : chunk.nextByte()
};
};
Decoder.prototype.filter = function(data) {
var bpp = this.bpp;
var width = this._IHDR.width, height = this._IHDR.height;
var pixels = new byteArray((width * height) * bpp);
var filter, line, left, leftup, up, pixel;
var lineWidth = width * bpp, byte, off;
for (var y = 0; y < height; y++) {
filter = data.nextByte();
line = data.nextBytes(lineWidth);
for (var x = 0; x < lineWidth; x++) {
if (filter !== 0) {
off = (y * lineWidth) + x;
}
byte = line.nextByte();
switch(filter) {
case 0: //None
pixel = byte;
break;
case 1: // Sub Raw(x) + Raw(x - bpp)
if (x < bpp) {
pixel = byte;
break;
}
pixel = pixels[off - bpp] + byte & 0xff;
break;
case 2: // Up(x) = Raw(x) + Prior(x)
if (y === 0) {
pixel = byte;
break;
}
pixel = pixels[off - lineWidth] + byte & 0xff;
break;
case 3: // Average(x) = Raw(x) + floor((Raw(x-bpp)+Prior(x))/2)
if (y === 0) {
if (x < bpp) {
pixel = byte;
} else {
pixel = (byte + (pixels[off - bpp] >> 1)) & 0xff;
}
break;
}
if (x < bpp) {
pixel = (byte + (pixels[off - lineWidth] >> 1)) & 0xff;
break;
}
pixel = (byte + (pixels[off - bpp] + pixels[off - lineWidth] >> 1)) & 0xff;
break;
case 4: // Paeth
if (y === 0) {
if (x < bpp) {
pixel = byte;
} else {
pixel = (byte + (pixels[off - bpp])) & 0xff;
}
break;
}
if (x < bpp) {
pixel = (byte + (pixels[off - lineWidth])) & 0xff;
break;
}
up = pixels[off - lineWidth];
left = pixels[off - bpp];
leftup = pixels[(off - lineWidth) - bpp];
var p = left + up - leftup,
pleft = Math.abs(p - left),
pup = Math.abs(p - up),
pleftup = Math.abs(p - leftup);
if (pleft <= pup && pleft <= pleftup){
pixel = byte + left & 0xff;
break;
} else if (pup <= pleftup) {
pixel = byte + up & 0xff;
break;
}
pixel = byte + leftup & 0xff;
break;
default:
throw new Error('Filter error: ' + filter);
}
pixels.insertByte(pixel);
}
}
return pixels;
};
module.exports = Decoder;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

View file

@ -1,80 +0,0 @@
//var logo = require('./node-png').readPng('./node-logo.png');
var fs = require('fs');
var Decoder = require('./png-decoder');
var decoder = new Decoder();
var logo = {
data : Buffer.from(decoder.parse(fs.readFileSync('./screen.png'))),
width : decoder._IHDR.width,
height : decoder._IHDR.height
};
var x11 = require('../../lib');
var Exposure = x11.eventMask.Exposure;
x11.createClient(function(err, display)
{
var X = display.client;
X.require('render', function(err, Render) {
var root = display.screen[0].root;
main(root, X, Render, display);
});
});
function main(root, X, Render, display) {
var win, picWin, pic, gc;
win = X.AllocID();
X.CreateWindow(
win, root,
0, 0, logo.width, logo.height,
0, 0, 0, 0,
{ eventMask: Exposure }
);
X.MapWindow(win);
gc = X.AllocID();
X.CreateGC(gc, win);
var logoPixmap = X.AllocID();
X.CreatePixmap(logoPixmap, win, 24, logo.width, logo.height);
var rscreen = display.screen[0];
var screen =
rscreen.depths[rscreen.root_depth][
Object.keys(rscreen.depths[rscreen.root_depth])[0]];
var rmask = parseInt(screen.red_mask, 10);
var gmask = parseInt(screen.green_mask, 10);
var bmask = parseInt(screen.blue_mask, 10);
for (var y = 0; y < logo.height; y++) {
for (var x = 0; x < logo.width; x++) {
var pixel = Buffer.from([
logo.data[(x + logo.width * y) * 4],
logo.data[(x + logo.width * y) * 4 + 1],
logo.data[(x + logo.width * y) * 4 + 2], 0]).readInt32LE();
logo.data[(x + logo.width * y) * 4 ] = (pixel & rmask) >> 16;
logo.data[(x + logo.width * y) * 4 + 1] = (pixel & gmask) >> 8;
logo.data[(x + logo.width * y) * 4 + 2] = (pixel & bmask) >> 0;
logo.data[(x + logo.width * y) * 4 + 3] = 0x00;
}
}
X.PutImage(2, logoPixmap, gc, logo.width, logo.height, 0, 0, 0, 24, logo.data);
var logoPicture = X.AllocID();
Render.CreatePicture(logoPicture, logoPixmap, Render.rgb24);
var winPicture = X.AllocID();
Render.CreatePicture(winPicture, win, Render.rgb24);
X.on('event', function(ev) {
if (ev.name == 'Expose') {
Render.Composite(3, logoPicture, 0, winPicture, 0, 0, 0, 0, 0, 0, logo.width, logo.height);
}
});
}

28
examples/screenshot.js Normal file → Executable file
View file

@ -8,16 +8,16 @@ x11.createClient(function(err, display) {
var id = wid ? wid : root; var id = wid ? wid : root;
var gc = X.AllocID(); var gc = X.AllocID();
X.CreateGC(gc, id); X.CreateGC(gc, id);
var width = 0; var width = 0;
var hwight = 0; var hwight = 0;
X.GetGeometry(id, function(err, clientGeom) { X.GetGeometry(id, function(clientGeom) {
width = clientGeom.width; width = clientGeom.width;
height = clientGeom.height; height = clientGeom.height;
var dispwin = X.AllocID(); var dispwin = X.AllocID();
X.CreateWindow(dispwin, root, 0, 0, width, height, 0, 0, 0, 0, { eventMask: x11.eventMask.Exposure }); X.CreateWindow(dispwin, root, 0, 0, width, height, 1, 1, 0, { eventMask: x11.eventMask.Exposure });
X.MapWindow(dispwin); X.MapWindow(dispwin);
//X.CopyArea(idScreenshot, dispwin, gc, 0, 0, 0, 0, width, height); //X.CopyArea(idScreenshot, dispwin, gc, 0, 0, 0, 0, width, height);
@ -25,21 +25,21 @@ x11.createClient(function(err, display) {
//var idScreenshot = X.AllocID(); //var idScreenshot = X.AllocID();
//X.CreatePixmap(idScreenshot, root, 24, clientGeom.width, clientGeom.height); //X.CreatePixmap(idScreenshot, root, 24, clientGeom.width, clientGeom.height);
// ask recursively each window to copy itself to pixmap // ask recursively each window to copy itself to pixmap
function drawWithKids(list, cb) function drawWithKids(list, cb)
{ {
if (list.length == 0) if (list.length == 0)
return cb(); return cb();
var p = list.pop(); var p = list.pop();
var win = p.win; var win = p.win;
if (win == dispwin) if (win == dispwin)
return drawWithKids(list, cb); return drawWithKids(list, cb);
X.GetWindowAttributes(win, function(err, res) { X.GetWindowAttributes(win, function(res) {
if (res[8] == 0) if (res[8] == 0)
return drawWithKids(list, cb); return drawWithKids(list, cb);
X.GetGeometry(win, function(err, geom) { X.GetGeometry(win, function(geom) {
// (srcDrawable, dstDrawable, gc, srcX, srcY, dstX, dstY, width, height) // (srcDrawable, dstDrawable, gc, srcX, srcY, dstX, dstY, width, height)
if (win != root) if (win != root)
X.CopyArea(win, dispwin, gc, 0, 0, p.x + geom.xPos, p.y + geom.yPos, geom.width, geom.height); X.CopyArea(win, dispwin, gc, 0, 0, p.x + geom.xPos, p.y + geom.yPos, geom.width, geom.height);
//X.CopyArea(win, idScreenshot, gc, 0, 0, p.x + geom.xPos, p.y + geom.yPos, geom.width, geom.height); //X.CopyArea(win, idScreenshot, gc, 0, 0, p.x + geom.xPos, p.y + geom.yPos, geom.width, geom.height);
@ -63,19 +63,15 @@ x11.createClient(function(err, display) {
// console.log(data); // console.log(data);
//}); //});
console.log('DONE! ready'); console.log('DONE! ready');
X.terminate(); X.terminate();
//var dispwin = X.AllocID(); //var dispwin = X.AllocID();
//X.CreateWindow(dispwin, root, 0, 0, width, height, 1, 1, 0, { eventMask: x11.eventMask.Exposure }); //X.CreateWindow(dispwin, root, 0, 0, width, height, 1, 1, 0, { eventMask: x11.eventMask.Exposure });
//X.MapWindow(dispwin); //X.MapWindow(dispwin);
//X.CopyArea(idScreenshot, dispwin, gc, 0, 0, 0, 0, width, height); //X.CopyArea(idScreenshot, dispwin, gc, 0, 0, 0, 0, width, height);
}); });
*/ */
X.GetImage(2, id, 0, 0, width, height, 0xffffffff, function(err, image) { X.GetImage(2, root, 0, 0, width, height, 0xffffffff, function(image) {
if (err) {
console.log(err);
process.exit(1);
}
console.log(image); console.log(image);
// format, drawable, gc, width, height, dstX, dstY, leftPad, depth, data // format, drawable, gc, width, height, dstX, dstY, leftPad, depth, data
X.PutImage(2, dispwin, gc, width, height, 0, 0, 0, 24, image.data); X.PutImage(2, dispwin, gc, width, height, 0, 0, 0, 24, image.data);

View file

@ -1,36 +0,0 @@
/*
* GCFunction usage example
*/
var x11 = require('../../lib');
x11.createClient(function(err, display) {
var X = display.client;
var root = display.screen[0].root;
var white = display.screen[0].white_pixel;
var black = display.screen[0].black_pixel;
var wid = X.AllocID();
X.CreateWindow(wid, root, 0, 0, 400, 300, 0, 0, 0, 0, {
backgroundPixel: black,
eventMask: x11.eventMask.ButtonPress|x11.eventMask.Exposure });
var gc = X.AllocID();
X.CreateGC(gc, wid, {foreground : white, 'function' : x11.gcFunction.GXinvert});
X.MapWindow(wid);
X.on('event', function(ev) {
if (ev.type === 12) {
X.PolyFillRectangle(wid, gc, [0, 0, 400, 300]);
}
if (ev.type === 4) {
var x = ev.x;
var y = ev.y;
X.PolyFillRectangle(wid, gc, [x - 25, y - 25, 50, 50]);
}
});
});

View file

@ -7,7 +7,7 @@ var xclient = x11.createClient(function(err, display) {
display.client.require('render', function(err, Render) { display.client.require('render', function(err, Render) {
var wid = X.AllocID(); var wid = X.AllocID();
var white = display.screen[0].white_pixel; var white = display.screen[0].white_pixel;
var black = display.screen[0].black_pixel; varblack = display.screen[0].black_pixel;
X.CreateWindow(wid, root, 10, 10, 400, 300, 0, 0, 0, 0, { backgroundPixel: white, eventMask: PointerMotion }); X.CreateWindow(wid, root, 10, 10, 400, 300, 0, 0, 0, 0, { backgroundPixel: white, eventMask: PointerMotion });
X.MapWindow(wid); X.MapWindow(wid);

View file

@ -26,7 +26,7 @@ function padWidth(buf, width) {
return buf; return buf;
else { else {
var stride = (width+3)&~3; var stride = (width+3)&~3;
var res = Buffer.alloc(height*stride); var res = new Buffer(height*stride);
res.fill(0); res.fill(0);
for (var y=0; y < height; ++y) { for (var y=0; y < height; ++y) {
// memcpy(tmpbitmap+y*stride, bitmap->buffer+y*ginfo.width, ginfo.width); // memcpy(tmpbitmap+y*stride, bitmap->buffer+y*ginfo.width, ginfo.width);
@ -42,7 +42,7 @@ var xclient = x11.createClient({ debug: true }, function(err, display) {
display.client.require('render', function(err, Render) { display.client.require('render', function(err, Render) {
var wid = X.AllocID(); var wid = X.AllocID();
var white = display.screen[0].white_pixel; var white = display.screen[0].white_pixel;
var black = display.screen[0].black_pixel; varblack = display.screen[0].black_pixel;
X.CreateWindow(wid, root, 10, 10, 400, 300, 0, 0, 0, 0, { backgroundPixel: white, eventMask: Exposure|PointerMotion }); X.CreateWindow(wid, root, 10, 10, 400, 300, 0, 0, 0, 0, { backgroundPixel: white, eventMask: Exposure|PointerMotion });
X.MapWindow(wid); X.MapWindow(wid);
@ -88,7 +88,7 @@ var xclient = x11.createClient({ debug: true }, function(err, display) {
var glyphFromCode = []; var glyphFromCode = [];
glyphs.forEach(function(g) { glyphs.forEach(function(g) {
if (!g.image || (g.image.length == 0)) { if (!g.image || (g.image.length == 0)) {
g.image = Buffer.alloc(64); g.image = new Buffer(64);
g.image.fill(0); g.image.fill(0);
g.width = 8; g.width = 8;
g.height = 8; g.height = 8;

View file

@ -1,51 +0,0 @@
// the code is taken from https://github.com/mattlockyer/iat455/blob/6493c882f1956703133c1bffa1d7ee9a83741cbe/assignment1/assignment/effects/blur-effect-dyn.js
// (c) Matt Lockyer, https://github.com/mattlockyer
function hypotenuse(x1, y1, x2, y2) {
var xSquare = Math.pow(x1 - x2, 2);
var ySquare = Math.pow(y1 - y2, 2);
return Math.sqrt(xSquare + ySquare);
}
/*
* Generates a kernel used for the gaussian blur effect.
*
* @param dimension is an odd integer
* @param sigma is the standard deviation used for our gaussian function.
*
* @returns an array with dimension^2 number of numbers, all less than or equal
* to 1. Represents our gaussian blur kernel.
*/
function generateGaussianKernel(dimension, sigma) {
if (!(dimension % 2) || Math.floor(dimension) !== dimension || dimension<3) {
throw new Error(
'The dimension must be an odd integer greater than or equal to 3'
);
}
var kernel = [];
var twoSigmaSquare = 2 * sigma * sigma;
var centre = (dimension - 1) / 2;
for (var i = 0; i < dimension; i++) {
for (var j = 0; j < dimension; j++) {
var distance = hypotenuse(i, j, centre, centre);
// The following is an algorithm that came from the gaussian blur
// wikipedia page [1].
//
// http://en.wikipedia.org/w/index.php?title=Gaussian_blur&oldid=608793634#Mechanics
var gaussian = (1 / Math.sqrt(
Math.PI * twoSigmaSquare
)) * Math.exp((-1) * (Math.pow(distance, 2) / twoSigmaSquare));
kernel.push(gaussian);
}
}
// Returns the unit vector of the kernel array.
var sum = kernel.reduce(function (c, p) { return c + p; });
return kernel.map(function (e) { return e / sum; });
}
module.exports = generateGaussianKernel;

View file

@ -6,7 +6,7 @@ var Pixmap = require('./pixmap').Pixmap;
var Buffer = require('buffer').Buffer; var Buffer = require('buffer').Buffer;
require('../../lib/unpackbuffer').addUnpack(Buffer); require('../../lib/unpackbuffer').addUnpack(Buffer);
var reversed = Buffer.alloc(256); var reversed = new Buffer(256);
for (var i=0; i < 256; ++i) for (var i=0; i < 256; ++i)
{ {
var res = 0; var res = 0;
@ -42,4 +42,4 @@ module.exports.decodeBuffer = function(buffer)
data[i] = 255 - reversed[data[i]]; data[i] = 255 - reversed[data[i]];
return new Pixmap(header.bpp, header.width, header.height, data); return new Pixmap(header.bpp, header.width, header.height, data);
} }

View file

@ -1,15 +0,0 @@
var x11 = require('../../lib');
var Window = require('./wndwrap');
x11.createClient(function(err, display) {
var X = display.client;
var w = new Window(X, 0, 0, 700, 500);
w.map();
w.on('expose', function() {
var gc = X.AllocID();
X.CreateGC(gc, w.id, { foreground: w.black, background: w.white });
X.PolyFillRectangle(w.id, gc, [50, 50, 600, 400]);
X.ClearArea(w.id, 0, 0, 300, 300, 0);
});
});

View file

@ -5,7 +5,7 @@ var keysym = require('keysym');
var ks = x11.keySyms; var ks = x11.keySyms;
var ks2Name = {}; var ks2Name = {};
for (var key in ks) for (var key in ks)
ks2Name[ ks[key].code ] = key; ks2Name[ ks[key] ] = key;
var kk2Name = {}; var kk2Name = {};
x11.createClient(function(err, display) { x11.createClient(function(err, display) {

View file

@ -8,7 +8,7 @@ var xclient = x11.createClient();
var Exposure = x11.eventMask.Exposure; var Exposure = x11.eventMask.Exposure;
var PointerMotion = x11.eventMask.PointerMotion; var PointerMotion = x11.eventMask.PointerMotion;
var bitmap = Buffer.alloc(128*128/8); // 16384 bits, 2048 bytes bitmap var bitmap = new Buffer(128*128/8); // 16384 bits, 2048 bytes bitmap
for (var i=0; i < bitmap.length; ++i) for (var i=0; i < bitmap.length; ++i)
{ {
bitmap[i] = i % 256; bitmap[i] = i % 256;

View file

@ -4,7 +4,7 @@ var x11 = require('../../lib');
var Exposure = x11.eventMask.Exposure; var Exposure = x11.eventMask.Exposure;
var PointerMotion = x11.eventMask.PointerMotion; var PointerMotion = x11.eventMask.PointerMotion;
var bitmap = Buffer.alloc(128*128*4); // 16384 bits, 2048 bytes bitmap var bitmap = new Buffer(128*128*4); // 16384 bits, 2048 bytes bitmap
for (var i=0; i < bitmap.length; ++i) for (var i=0; i < bitmap.length; ++i)
{ {
var byteNum = i%4; var byteNum = i%4;

View file

@ -1,11 +1,11 @@
var x11 = require('../../lib'); var x11 = require('../../lib');
var xclient = x11.createClient({debug: true}); var xclient = x11.createClient();
var Exposure = x11.eventMask.Exposure; var Exposure = x11.eventMask.Exposure;
var PointerMotion = x11.eventMask.PointerMotion; var PointerMotion = x11.eventMask.PointerMotion;
var pts = []; var pts = [];
xclient.on('connect', function(display) { xclient.on('connect', function(err, display) {
var X = this; var X = this;
var root = display.screen[0].root; var root = display.screen[0].root;
var white = display.screen[0].white_pixel; var white = display.screen[0].white_pixel;
@ -13,16 +13,18 @@ xclient.on('connect', function(display) {
function createWindow() function createWindow()
{ {
var wid = X.AllocID();
// id, parentId, x, y, width, height, borderWidth, depth, _class, visual, values var wid = X.AllocID();
X.CreateWindow( X.CreateWindow(
wid, root, wid, root,
10, 10, 400, 300, 10, 10, 400, 300,
0, 0, 0, 0, { 1, 1, 0,
backgroundPixel: white, eventMask: Exposure|PointerMotion {
}); backgroundPixel: white, eventMask: Exposure|PointerMotion
X.MapWindow(wid); }
return wid; );
X.MapWindow(wid);
return wid;
} }
var wid = createWindow(); var wid = createWindow();
@ -57,7 +59,7 @@ xclient.on('connect', function(display) {
} }
}); });
//X.on('error', function(e) { X.on('error', function(e) {
// console.log(e); console.log(e);
//}); });
}); });

View file

@ -1,22 +0,0 @@
var x11 = require('../../lib');
var Expose = 12;
x11.createClient(function(err, display) {
var X = display.client;
var root = display.screen[0].root;
X.require('shape', function(err, Shape) {
var win = X.AllocID();
X.CreateWindow(win, root, 0, 0, 200, 200);
X.ChangeWindowAttributes(win, { backgroundPixel: display.screen[0].black_pixel });
X.MapWindow(win);
Shape.Rectangles(Shape.Op.Set, Shape.Kind.Bounding, win, 0, 0, [
[40, 40, 40, 40], [120, 40, 40, 40],
[0, 120, 20, 20], [180, 120, 20, 20],
[20, 140, 30, 20], [150, 140, 30, 20],
[50, 160, 100, 20]
]);
});
X.on('error', function(err) { console.log(err); });
});

View file

@ -6,22 +6,17 @@ x11.createClient(function(err, display) {
X.require('shape', function(err, Shape) { X.require('shape', function(err, Shape) {
var win = X.AllocID(); var win = X.AllocID();
X.CreateWindow(win, root, 0, 0, 200, 200); X.CreateWindow(win, root, 0, 0, 200, 200);
X.ChangeWindowAttributes(win, { backgroundPixel: display.screen[0].white_pixel }); var gc = X.AllocID();
X.MapWindow(win); X.CreateGC(gc, win);
X.ClearArea(win, 0, 0, 200, 200, false); //X.MapWindow(win);
Shape.SelectInput(win, 1);
Shape.SelectInput(win, true);
Shape.InputSelected(win, function(err, isSelected) { Shape.InputSelected(win, function(err, isSelected) {
console.log("IsSelected: " + isSelected); console.log("IsSelected: " + isSelected);
}); });
//var pid = X.AllocID();
var bitmap = X.AllocID(); //X.CreatePixmap(pid, win, 2, 200, 200);
X.CreatePixmap(bitmap, win, 1, 200, 200); //X.PolyText8(pid, gc, 0, 0, ['Hello, Node.JS!', ' Hello, world!']);
var gc = X.AllocID(); //Shape.Mask(Shape.Op.Set, Shape.Kind.Input, win, 0, 0, pid);
X.CreateGC(gc, bitmap, { foreground: 1 });
// X.PolyText8(bitmap, gc, 0, 0, ['Hello, Node.JS!', ' Hello, world!']);
X.PolyFillArc(bitmap, gc, [0, 0, 200, 200, 0, 360 * 64]);
Shape.Mask(Shape.Op.Set, Shape.Kind.Bounding, win, 0, 0, bitmap);
X.on('event', function(ev) { X.on('event', function(ev) {
console.log(ev); console.log(ev);

View file

@ -1,125 +0,0 @@
var _ = require('underscore');
var x11 = require('../../lib');
var Exposure = x11.eventMask.Exposure;
var PointerMotion = x11.eventMask.PointerMotion;
var ButtonPress = x11.eventMask.ButtonPress;
var draw;
var useConvo3 = true;
x11.createClient({ debug: true}, function(err, display) {
var X = display.client;
var root = display.screen[0].root;
var wid = X.AllocID();
X.CreateWindow(
wid, root,
0, 0, 800, 600,
0, 0, 0, 0,
{
eventMask: Exposure|PointerMotion|ButtonPress
}
);
X.MapWindow(wid);
X.require('render', function(err, Render) {
Render.QueryFilters(console.log);
var pixMask = X.AllocID();
X.CreatePixmap(pixMask, wid, 8, 600, 600);
var pictTraps = X.AllocID();
Render.CreatePicture(pictTraps, pixMask, Render.a8);
var pictWin = X.AllocID();
Render.CreatePicture(pictWin, wid, Render.rgb24);
var pictSolid = X.AllocID();
r = 0.2; g = 0.2; b = 0.2; a = 1;
Render.CreateSolidFill(pictSolid, r, g, b, a);
var pixBuff = X.AllocID();
X.CreatePixmap(pixBuff, wid, 24, 600, 600);
var pictBuff = X.AllocID();
Render.CreatePicture(pictBuff, pixBuff, Render.rgb24);
var convo5 = [ 5, 5, 0.0030, 0.0133, 0.0219, 0.0133, 0.0030,
0.0133, 0.0596, 0.0983, 0.0596, 0.0133,
0.0219, 0.0983, 0.1621, 0.0983, 0.0219,
0.0133, 0.0596, 0.0983, 0.0596, 0.0133,
0.0030, 0.0133, 0.0219, 0.0133, 0.0030];
var convo3 = [3, 3, 0.01, 0.08, 0.01, 0.08, 0.64, 0.08, 0.01, 0.08, 0.01];
var convo5 = [21, 21].concat(require('./blur-convolution')(21, 11));
//Render.SetPictureFilter(pictBuff, 'convolution', convo3);
//Render.SetPictureFilter(pictTraps, 'convolution', convo3);
//Render.SetPictureFilter(pictBuff, 'bilinear', []);
Render.SetPictureFilter(pictBuff, 'best', []);
draw1 = function(x, y) {
console.log('draw 1', x, y);
var r = 3 + 2*Math.floor(x / 100);
var convo = [r, r].concat(require('./blur-convolution')(r, r));
Render.SetPictureFilter(pictBuff, 'convolution', convo);
var a = (x-400)/500;
var m = [
Math.cos(a), Math.sin(a), 0,
-Math.sin(a), Math.cos(a), 0,
0, 0, 1
];
// Render.SetPictureTransform(pictTraps, m)
var r, g, b;
// fill window
r = 1; g = 1; b = 1; a = 0.5;
Render.FillRectangles(1, pictBuff, [r, g, b, a], [0, 0, 1000, 1000])
// fill traps
r = 0; g = 0; b = 0; a = 0;
Render.FillRectangles(1, pictTraps, [r, g, b, a], [0, 0, 1000, 1000])
Render.AddTraps(pictTraps, 0, 0, [
x, 200, y,
//150, 200, 50,
5, 250, 300,
110, 200, 310,
50, 150, 500
]);
// (op, src, mask, dst, srcX, srcY, maskX, maskY, dstX, dstY, width, height)
//Render.Composite(Render.PictOp.Over, pictSolid, pictTraps, pictWin, 0, 0, 0, 0, 0, 0, 800, 600);
//Render.PictOp.Over
Render.Composite(Render.PictOp.Over, pictSolid, pictTraps, pictBuff, 0, 0, 0, 0, 0, 0, 800, 600);
Render.Composite(Render.PictOp.Over, pictBuff, 0, pictWin, 0, 0, 0, 0, 0, 0, 800, 600);
};
draw = function(x, y) {
var f = _.debounce(function() {
draw1(x, y);
}, 100);
f();
};
});
}).on('error', function(err) {
console.log(err);
}).on('event', function(ev) {
//console.log(ev);
if (ev.name == 'MotionNotify') {
draw(ev.x, ev.y);
} else if (ev.name == 'ButtonPress') {
useConvo3 = !useConvo3;
draw(ev.x, ev.y);
//console.log(ev);
}
});

View file

@ -25,7 +25,7 @@ var Buffer = require('buffer').Buffer;
var startpos = [4, 15]; var startpos = [4, 15];
var cupsize = [10, 20]; var cupsize = [10, 20];
var cup = Buffer.alloc(cupsize[0]*cupsize[1]); var cup = new Buffer(cupsize[0]*cupsize[1]);
var moveInterval; var moveInterval;
function clearCup() function clearCup()
@ -250,7 +250,7 @@ x11.createClient(function(err, display) {
var ks = x11.keySyms; var ks = x11.keySyms;
var ks2Name = {}; var ks2Name = {};
for (var key in ks) for (var key in ks)
ks2Name[ ks[key].code ] = key; ks2Name[ ks[key] ] = key;
var kk2Name = {}; var kk2Name = {};
var min = display.min_keycode; var min = display.min_keycode;
var max = display.max_keycode; var max = display.max_keycode;

View file

@ -56,8 +56,8 @@ var pc2 = [
function deskey(key, edf) function deskey(key, edf)
{ {
var i, j, l, m, n; var i, j, l, m, n;
var pc1m = Buffer.alloc(56); var pc1m = new Buffer(56);
var pcr = Buffer.alloc(56); var pcr = new Buffer(56);
var kn = new Array(32); var kn = new Array(32);
for ( j = 0; j < 56; j++ ) { for ( j = 0; j < 56; j++ ) {
@ -388,17 +388,17 @@ function desfunc(block, keys)
module.exports.response = function(challenge, password) module.exports.response = function(challenge, password)
{ {
var key = Buffer.alloc(8); var key = new Buffer(8);
key.fill(0); key.fill(0);
key.write(password.substring(0,8)); key.write(password.substring(0,8));
var in1 = challenge.slice(0,8); var in1 = challenge.slice(0,8);
var in2 = challenge.slice(8,16); var in2 = challenge.slice(8,16);
var res1 = Buffer.alloc(8); var res1 = new Buffer(8);
var res2 = Buffer.alloc(8); var res2 = new Buffer(8);
deskey(key, EN0); deskey(key, EN0);
des(in1, res1); des(in1, res1);
des(in2, res2); des(in2, res2);
var resp = Buffer.alloc(16); var resp = new Buffer(16);
res1.copy(resp); res1.copy(resp);
res2.copy(resp, 8); res2.copy(resp, 8);
return resp; return resp;

View file

@ -7,7 +7,7 @@
// It should create a pleasant looking hex dumb by default: // It should create a pleasant looking hex dumb by default:
// //
// var hexy = require('hexy.js'), // var hexy = require('hexy.js'),
// b = Buffer.from("\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789") // b = new Buffer("\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789")
// //
// console.log(hexy.hexy(b)) // console.log(hexy.hexy(b))
// //
@ -258,4 +258,4 @@ console.log(hexy(data, format))
console.log("doen") console.log("doen")
*/ */
exports.hexy = hexy exports.hexy = hexy

View file

@ -400,7 +400,7 @@ RfbClient.prototype.readHextileTile = function(rect, cb)
}); });
return; return;
} }
tile.buffer = Buffer.alloc(tilebuflen); tile.buffer = new Buffer(tilebuflen);
function solidBackground() { function solidBackground() {
clog('solidBackground'); clog('solidBackground');
@ -667,8 +667,8 @@ function createConnection(params)
var wstream = fs.createWriteStream(params.rfbFileOut); var wstream = fs.createWriteStream(params.rfbFileOut);
wstream.write('FBS 001.001\n'); wstream.write('FBS 001.001\n');
stream.on('data', function(data) { stream.on('data', function(data) {
var sizeBuf = Buffer.alloc(4); var sizeBuf = new Buffer(4);
var timeBuf = Buffer.alloc(4); var timeBuf = new Buffer(4);
var size = data.length; var size = data.length;
sizeBuf.writeInt32BE(size, 0); sizeBuf.writeInt32BE(size, 0);
wstream.write(sizeBuf); wstream.write(sizeBuf);
@ -676,7 +676,7 @@ function createConnection(params)
timeBuf.writeInt32BE(+new Date() - start, 0); timeBuf.writeInt32BE(+new Date() - start, 0);
wstream.write(timeBuf); wstream.write(timeBuf);
var padding = 3 - ((size - 1) & 0x03); var padding = 3 - ((size - 1) & 0x03);
var pbuf = Buffer.alloc(padding); var pbuf = new Buffer(padding);
wstream.write(pbuf); wstream.write(pbuf);
}).on('end', function() { }).on('end', function() {
wstream.end(); wstream.end();

View file

@ -62,7 +62,7 @@ RfbServer.prototype.processSecurity = function()
break; break;
case rfb.security.VNC: case rfb.security.VNC:
// generate random 16 byte challenge // generate random 16 byte challenge
serv.challenge = Buffer.alloc(16); serv.challenge = new Buffer(16);
serv.challenge.write('1234567890abcdef'); serv.challenge.write('1234567890abcdef');
console.log(['sending challenge', serv.challenge]); console.log(['sending challenge', serv.challenge]);
serv.pack_stream.pack('a', [serv.challenge]).flush(); serv.pack_stream.pack('a', [serv.challenge]).flush();

View file

@ -34,7 +34,7 @@ function ReadFixedRequest(length, callback)
this.length = length; this.length = length;
this.callback = callback; this.callback = callback;
//clog(length); //clog(length);
this.data = Buffer.alloc(length); this.data = new Buffer(length);
this.received_bytes = 0; this.received_bytes = 0;
} }
@ -328,7 +328,7 @@ UnpackStream.prototype.pack = function(format, args)
} }
} }
var buf = Buffer.alloc(packetlength); var buf = new Buffer(packetlength);
var offset = 0; var offset = 0;
var arg = 0; var arg = 0;
for (var i = 0; i < format.length; ++i) for (var i = 0; i < format.length; ++i)

View file

@ -1,75 +0,0 @@
/* XPM */
static char * node_logo_xpm[] = {
"245 66 6 1",
" c None",
". c #FFFFFF",
"+ c #8CC84B",
"@ c #8DC84C",
"# c #89C746",
"$ c #8AC748",
" .. ",
" .... ",
" ...... ",
" ....... ",
" ......... ",
" ........... ",
" ............ ",
" ............ ",
" ............ ",
" ............ ",
" ............ ",
" ............ ",
" ............ ",
" ............ ",
" ............ ",
" ............ ",
" ............ ",
" ............ ",
" ............ ",
" ............ ",
" ............ ",
" ............ ",
" ............ ",
" ............ ++ ",
" .... ++++ .. ............ .... ++++++ .. . .",
" ........ ++++++++ ...... ............ ....... +++++++++ .. .",
" ............ ++++++++++++ ....................... ........... ++++++ ++++++ ...",
" ............... ++++++++++++++ ......................... .............. +++++++ ++++++ ",
" .................. ++++++++++++++++++ .......................... .................. ++++++ ++++++ ",
" ...................... ++++++++++++++++++++++ ............................ ..................... ++++++ ++++++ ",
" .......................... +++++++++++++++++++++++++ .............................. ......................... ++++++ ++++++ ",
" ............................. ++++++++++++++++++++++++++++ ................................ ............................ +++++++ ++++++ ",
" ................................ ++++++++++++++++++++++++++++++++ ................................. ................................ ++++++ ++++++ ",
" .................................... ++++++++++++++++++++++++++++++++++++ ................................... ................................... +++++ ++++++ ",
" .................................... ++++++++++++++++++++++++++++++++++++ .................................... ..................................... ++++ ++++ ",
" .................................... ++++++++++++++++++++++++++++++++++++ ..................................... ..................................... +++ +++ ",
" .................................... ++++++++++++++++++++++++++++++++++++ ..................................... ..................................... +++ + ++++++++ +++ ",
" .................................... ++++++++++++++++++++++++++++++++++++ ..................................... ..................................... +++ +++ ++++++++++++ +++ ",
" ................ ................ ++++++++++++++++++++++++++++++++++++ .................. ................. ................. ................. +++ +++ ++++++++++++++ +++ ",
" ............... ............... ++++++++++++++++++++++++++++++++++++ ................ ............... ................ ............... +++ +++ ++++ ++++ +++ ",
" ............. ............. ++++++++++++++++++++++++++++++++++++ ............... .............. .............. .............. +++ +++ +++ +++ +++ ",
" ............ ............ ++++++++++++++++++++++++++++++++++++ ............. ............ ............. ++@# ............ +++ +++ +++ +++ +++ ",
" ............ ............ ++++++++++++++++++++++++++++++++++++ ............. ............ ............. #@+++++ .......... +++ +++ ++++++ +++ ",
" ............ ............ ++++++++++++++++++++++++++++++++++++ ............. ............ ............. +++++++ ........ +++ +++ +++++++++++ +++ ",
" ............ ............ ++++++++++++++++++++++++++++++++++++ ............. ............ ............. +++++++ ...... +++ +++ ++++++++++++ +++ ",
" ............ ............ ++++++++++++++++++++++++++++++++++++ ............. ............ ............. +++++++ .... +++ +++ +++++++++++ +++ ",
" ............ ............ ++++++++++++++++++++++++++++++++++++ ............. ............ ............. @++++++ ... +++ +++ +++++ +++ ",
" ............ ............ ++++++++++++++++++++++++++++++++++++ ............. ............ ............. $+++ +++ +++ +++ +++ +++ ",
" ............ ............ ++++++++++++++++++++++++++++++++++++ ............. ............. .............. +++ +++ ++++ +++ +++ ",
" ............ ............ ++++++++++++++++++++++++++++++++++++ ............... .............. ............... +++ +++ ++++ ++++ +++ ",
" ............ ............ ++++++++++++++++++++++++++++++++++++ ................. ................ ................. +++ +++ ++++++++++++++ +++ ",
" ............ ............ ++++++++++++++++++++++++++++++++++++ ..................................... ................... +++ +++ +++++++++++++ +++ ",
" ............ ............ ++++++++++++++++++++++++++++++++++++ ..................................... .................... +++ +++ +++++++++ +++ ",
" ............ ............ ++++++++++++++++++++++++++++++++++++ ..................................... ...................... +++ +++ +++ ",
" ............ ............ ++++++++++++++++++++++++++++++++++++ .................................... ........................ +++++ +++ ++++ ",
" ........... ........... ++++++++++++++++++++++++++++++++++++ .................................... ......................... ++++++ ++++ +++++ ",
" ......... ......... ++++++++++++++++++++++++++++++++ .................................. ........................ ++++++++++++ ++++++ ",
" ........ ........ ++++++++++++++++++++++++++++ .............................. ......................... +++++++++ ++++++ ",
" ...... ...... ++++++++++++++++++++++++++ .......................... ........................ ++++++ ++++++ ",
" .... .... ++++++++++++++++++++++ ...................... ...................... ++++++ ",
" .. .. ++++++++++++++++++ .................... .................. ++++ ++++++ ",
" ++++++++++++++ ................ ............... ++++++ ++++++ ",
" ++++++++++++ ............ ........... ++++++++++++ ",
" ++++++++ ......... ........ +++++++++ ",
" ++++ ...... .... +++++ ",
" .. "};

View file

@ -1,151 +0,0 @@
/* Extracted from https://github.com/klepthys/node-xpm
* This code is available as a standalone module named xpm
/*
The MIT License (MIT)
Copyright (c) 2015 Sebastien Dumetz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
var fs = require('fs');
function PixmapFromFile (path,options){
if(!options && typeof path == "object"){
this.options = path;
path = null;
}else{
this.options = options||{};
}
if(path){
return this.parse(fs.readFileSync(path, {encoding:"utf-8"}));
}
}
/**
*
* @param {[type]} data utf-8 file data
* @param {Function} callback optionnal callback.
*/
PixmapFromFile.prototype.parse = function (data) {
if(!/^\/\*\s*XPM\s*\*\/$/m.test(data)){
throw new Error("Not an XPM file");
}
var size = this.getSize(data);
var content = this.getArray(data,size);
var colors = this.mapColors(data,size);
size.data = this.toBuffer(colors,content,size);
return size;
};
PixmapFromFile.prototype.getSize = function(data){
var match = /{\n?"([0-9\s]*)\s?"/.exec(data);
if(!match){
throw new Error("can't parse size infos");
}
var values = match[1].split(" ").map(function(i){return parseInt(i)});
return {width:values[0],height:values[1],count:values[2],length:values[3]}
}
PixmapFromFile.prototype.getArray = function(data,size){
//var reg = new RegExp('"((?!(?:[0-9]+\\s?){4}).{'+size.length+'}(?!\\sc\\s).*)"',"g"); //Works also but much less simple
var reg = new RegExp('"(.{'+size.width*size.length+'})"',"g");
var res;
var rows = [];
while((res = reg.exec(data)) !== null){
rows.push(res[1]);
}
if(rows.length != size.height){
throw new Error("found : "+rows.length+" rows. Should have found :"+size.height+" rows.");
}
return rows;
}
// return RGBA color
PixmapFromFile.prototype.mapColors = function(content,size){
var reg = new RegExp('"(.' + ((size.length > 1)? "{"+(size.length)+"}" : "") + ")\\s+c\\s+#?(None|[0-9a-fA-F]{6})\"","gm");
var res;
var colors = {};
while((res = reg.exec(content)) !== null){
if(res[2] === "None"){
colors[res[1]] = "00000000"
}else{
colors[res[1]] = res[2]+"FF";//RGBA
}
}
if(Object.keys(colors).length != size.count){
throw new Error("found : "+Object.keys(colors).length+" colors. Should have found :"+size.count+" colors.");
}
return colors;
}
PixmapFromFile.prototype.toBuffer = function (colors,content,size) {
var buf = Buffer.alloc(size.width*size.height*4);
var offset = 0, byte,color;
var copy;
if( !this.options.format || this.options.format.toUpperCase() === "BGRA"){
copy = this.copyBGRABuffer;
}else if(this.options.format && this.options.format.toUpperCase() === "RGBA"){
copy = this.copyRGBABuffer;
}else{
throw new Error("invalid format option : ",this.options.format," valid values are BGRA (default) or RGBA")
}
content.forEach(function(row){
//console.log("parsing : ",row)
while(row && row.length >0){
var code = row.slice(0,size.length);
row = row.slice(size.length);
if(!colors[code]){
throw new Error("unknown color : ",code);
}
offset = copy(buf,offset,colors[code]);;
}
});
return buf;
};
/**
* Takes an array of rows. Each char/sequence represents a colored pixel
* @param {[type]} content [description]
* @return {Buffer} A 1d array of pixels in RGBA
*/
PixmapFromFile.prototype.copyBGRABuffer = function(buf, offset, color){
[4,2,0,6].forEach(function(i){
buf.writeUInt8(parseInt(color[i]+color[i+1],16),offset);
offset ++;
});
return offset;
}
PixmapFromFile.prototype.copyRGBABuffer = function(buf, offset, color){
buf.writeUInt32BE(parseInt(color,16),offset);
return offset+4;
}
PixmapFromFile.prototype.open = function(path,callback){
var self = this;
fs.readFile(path, {encoding:"utf-8"}, function(err,data){
if(err){
return callback(err);
}else{
callback(null,self.parse(data));
}
});
}
module.exports = PixmapFromFile;

View file

@ -1,53 +0,0 @@
#!/usr/bin/env node
var x11 = require('../../lib');
var PixmapFromFile = require('./node-xpm.js');
var Exposure = x11.eventMask.Exposure;
x11.createClient(function(err, display)
{
var X = display.client;
X.require('render', function(err, Render) {
var root = display.screen[0].root;
var pixmap = new PixmapFromFile();
pixmap.open("node-logo.xpm",function(err,logo){
if(err){
console.log(new Error().stack);
return console.error("pixmap open Error : ",err);
}
main(root, X, Render,logo);
});
});
});
function main(root, X, Render, logo) {
var win, picWin, pic, gc;
win = X.AllocID();
X.CreateWindow(
win, root,
0, 0, logo.width, logo.height,
0, 0, 0, 0,
{ eventMask: Exposure }
);
X.MapWindow(win);
gc = X.AllocID();
X.CreateGC(gc, win);
var logoPixmap = X.AllocID();
X.CreatePixmap(logoPixmap, win, 24, logo.width, logo.height);
// TODO: add proper png pixel conversion here
X.PutImage(2, logoPixmap, gc, logo.width, logo.height, 0, 0, 0, 24, logo.data);
var logoPicture = X.AllocID();
Render.CreatePicture(logoPicture, logoPixmap, Render.rgb24);
var winPicture = X.AllocID();
Render.CreatePicture(winPicture, win, Render.rgb24);
X.on('event', function(ev) {
if (ev.name == 'Expose')
Render.Composite(3, logoPicture, 0, winPicture, 0, 0, 0, 0, 0, 0, logo.width, logo.height);
});
}

View file

@ -1,110 +1,91 @@
// TODO: differentiate between auth types (i.e., MIT-MAGIC-COOKIE-1 and XDM-AUTHORIZATION-1) // TODO: http://en.wikipedia.org/wiki/X_Window_authorization
// and choose the best based on the algorithm in libXau's XauGetBestAuthByAddr
var fs = require('fs'); var fs = require('fs');
var Buffer = require('buffer').Buffer; var Buffer = require('buffer').Buffer;
// add 'unpack' method for buffer // add 'unpack' method for buffer
require('./unpackbuffer').addUnpack(Buffer); require('./unpackbuffer').addUnpack(Buffer);
var typeToName = {
256: 'Local',
65535: 'Wild',
254: 'Netname',
253: 'Krb5Principal',
252: 'LocalHost',
0: 'Internet',
1: 'DECnet',
2: 'Chaos',
5: 'ServerInterpreted',
6: 'Internet6'
};
function parseXauth( buf ) function parseXauth( buf )
{ {
var offset = 0; var offset = 0;
var auth = []; var auth = [];
var cookieProperties = ['address', 'display', 'authName', 'authData']; var cookieProperties = ['address', 'display', 'authName', 'authData'];
function handleCookieProperty(property) {
var length = buf.unpack('n', offset)[0];
offset += 2;
cookie[property] = buf.unpackString(length, offset);
offset += length;
}
while (offset < buf.length) while (offset < buf.length)
{ {
var cookie = {}; var cookie = {};
cookie.type = buf.readUInt16BE(offset); var typeToName = {
256: 'Local',
65535: 'Wild',
254: 'Netname',
253: 'Krb5Principal',
252: 'LocalHost',
0: 'Internet',
1: 'DECnet',
2: 'Chaos',
5: 'ServerInterpreted',
6: 'InternetV6'
};
cookie.type = buf.unpack('n')[0];
if (!typeToName[cookie.type]) { if (!typeToName[cookie.type]) {
console.warn('Unknown address type'); console.warn('Unknown address type');
} }
offset += 2; offset += 2;
cookieProperties.forEach(function(property) { //JSHint becomes angry when handleCookieProperty is declared inside loop
var length = buf.unpack('n', offset)[0]; cookieProperties.forEach(handleCookieProperty);
offset += 2;
if (cookie.type === 0 && property == 'address') { // Internet
// 4 bytes of ip addess, convert to w.x.y.z string
cookie.address = [ buf[offset], buf[offset+1], buf[offset+2], buf[offset+3]]
.map(function(octet) { return octet.toString(10) }).join('.');
} else {
cookie[property] = buf.unpackString(length, offset);
}
offset += length;
});
auth.push(cookie); auth.push(cookie);
} }
return auth; return auth;
} }
var homedir = require('os').homedir; module.exports = function( display, host, cb )
var path = require('path');
function readXauthority(cb) {
var filename = process.env.XAUTHORITY || path.join(homedir(), '.Xauthority');
fs.readFile(filename, function(err, data) {
if (!err)
return cb(null, data);
if(err.code == 'ENOENT') {
// Xming/windows uses %HOME%/Xauthority ( .Xauthority with no dot ) - try with this name
filename = process.env.XAUTHORITY || path.join(homedir(), 'Xauthority');
fs.readFile(filename, function (err, data) {
if (err.code == 'ENOENT') {
cb(null, null);
} else {
cb(err);
}
});
} else {
cb(err);
}
});
}
module.exports = function( display, host, socketFamily, cb )
{ {
var family; var XAuthorityFile = process.env.XAUTHORITY;
if (socketFamily === 'IPv4') { if (!XAuthorityFile)
family = 0; // Internet
} else if (socketFamily === 'IPv6') {
family = 6; // Internet6
} else {
family = 256; // Local
}
readXauthority(function(err, data) {
if(err) return cb(err);
if (!data) {
return cb(null, {
authName: '',
authData: ''
});
}
var auth = parseXauth(data);
for (var cookieNum in auth)
{ {
var cookie = auth[cookieNum]; if ( process.platform.match(/win/) ) {
if ((typeToName[cookie.family] === 'Wild' || (cookie.type === family && cookie.address === host)) && // http://www.straightrunning.com/XmingNotes/trouble.php
(cookie.display.length === 0 || cookie.display === display)) //
return cb( null, cookie ); // The Xming magic cookie program, xauth (user-based), uses an
// Xauthority file (not the traditional .Xauthority file) in
// the %HOME% directory. To use xauth from Command Processor
// e.g. on Windows machine 192.168.0.2 with user colin...
XAuthorityFile = process.env.USERPROFILE + '\\Xauthority';
} else {
XAuthorityFile = process.env.HOME + '/.Xauthority';
}
} }
// If no cookie is found, proceed without authentication
cb(null, { fs.readFile(XAuthorityFile, function (err, data) {
authName: '',
authData: '' if (err)
}); {
}); if (err.code == 'ENOENT')
{
cb('','');
return;
}
throw err;
}
var auth = parseXauth(data);
for (var cookieNum in auth)
{
var cookie = auth[cookieNum];
if (cookie.display == display && cookie.address == host)
{
cb( cookie.authName, cookie.authData );
return;
}
}
// throw 'No auth cookie matching display=' + display + ' and host=' + host;
cb( '', '' );
});
}; };

View file

@ -213,30 +213,26 @@ function packValueMask(reqname, values)
if (!reqValueMask) if (!reqValueMask)
throw new Error(reqname + ': no value mask description'); throw new Error(reqname + ': no value mask description');
for (var value in values) for (var v in values)
{ {
var v = reqValueMask[value]; var valueBit = reqValueMask[v].mask;
if (v) { if (!valueBit)
var valueBit = v.mask; throw new Error(reqname + ': incorrect value param ' + v);
if (!valueBit) masksList.push(valueBit);
throw new Error(reqname + ': incorrect value param ' + value); bitmask |= valueBit;
masksList.push(valueBit);
bitmask |= valueBit;
}
} }
/* numeric sort */ /* numeric sort */
masksList.sort(function(a, b) { masksList.sort(function(a, b) {
return a - b; return a - b;
}); });
var args = []; var args = [];
for (var i=0,length=masksList.length;i<length;i++) for (m in masksList)
{ {
var value = masksList[i]; var valueName = reqValueMaskName[masksList[m]];
var valueName = reqValueMaskName[value]; format += reqValueMask[valueName].format
format += reqValueMask[valueName].format args.push( values[valueName] );
args.push( values[valueName] );
} }
return [format, bitmask, args] return [format, bitmask, args]
} }
@ -400,11 +396,6 @@ var templates = {
} }
], ],
LowerWindow: [
function(win) {
return module.exports.ConfigureWindow[0](win, { stackMode : 1 });
}
],
QueryTree: [ QueryTree: [
['CxSL', [15, 2]], ['CxSL', [15, 2]],
@ -465,7 +456,7 @@ var templates = {
function(mode, wid, name, type, units, data) function(mode, wid, name, type, units, data)
{ {
var padded4 = (data.length + 3) >> 2; var padded4 = (data.length + 3) >> 2;
var pad = Buffer.alloc( (padded4<<2) - data.length); var pad = new Buffer( (padded4<<2) - data.length);
var format = 'CCSLLLCxxxLaa'; var format = 'CCSLLLCxxxLaa';
var requestLength = 6 + padded4; var requestLength = 6 + padded4;
var dataLenInFormatUnits = data.length / (units >> 3); var dataLenInFormatUnits = data.length / (units >> 3);
@ -614,12 +605,6 @@ var templates = {
return [ 'CCSLSxx', [ 34, key, 3, wid, modifiers ] ]; return [ 'CCSLSxx', [ 34, key, 3, wid, modifiers ] ];
} }
], ],
AllowEvents: [
function(mode, ts) {
return [ 'CCSL', [ 35, mode, 2, ts ] ];
}
],
GrabServer: [ GrabServer: [
[ 'CxS', [36, 1]] [ 'CxS', [36, 1]]
@ -727,6 +712,12 @@ var templates = {
} }
], ],
FreePixmap: [
function(pixmap) {
return [ 'CxSL', [ 54, 2, pixmap ] ];
}
],
FreePixmap: [ FreePixmap: [
function (pixmap) { function (pixmap) {
return [ 'CxSL', [54, 2, pixmap] ]; return [ 'CxSL', [54, 2, pixmap] ];
@ -766,19 +757,17 @@ var templates = {
var vals = packValueMask('CreateGC', values); var vals = packValueMask('CreateGC', values);
var packetLength = 3 + (values ? vals[2].length : 0); var packetLength = 3 + (values ? vals[2].length : 0);
var args = [56, packetLength, cid]; var args = [56, packetLength, cid];
format += vals[0] args.push(vals[0]); // values bitmask
args.push(vals[1]); // values bitmask var valArr = vals[1];
args = args.concat(vals[2]) for (var v in valArr)
{
format += 'L'; // TODO: we know format string length in advance and += inefficient for string
args.push(valArr[v]);
}
return [format, args]; return [format, args];
} }
], ],
ClearArea: [
function(wid, x, y, width, height, exposures) {
return [ 'CCSLssSS', [61, exposures, 4, wid, x, y, width, height] ];
}
],
// //
CopyArea: [ CopyArea: [
function(srcDrawable, dstDrawable, gc, srcX, srcY, dstX, dstY, width, height) { function(srcDrawable, dstDrawable, gc, srcX, srcY, dstX, dstY, width, height) {
@ -851,7 +840,7 @@ var templates = {
var padded = xutil.padded_length(data.length); var padded = xutil.padded_length(data.length);
var reqLen = 6 + padded/4; // (length + 3) >> 2 ??? var reqLen = 6 + padded/4; // (length + 3) >> 2 ???
var padLength = padded - data.length; var padLength = padded - data.length;
var pad = Buffer.alloc(padLength); // TODO: new pack format 'X' - skip amount of bytes supplied in numerical argument var pad = new Buffer(padLength); // TODO: new pack format 'X' - skip amount of bytes supplied in numerical argument
// TODO: move code to calculate reqLength and use BigReq if needed outside of corereq.js // TODO: move code to calculate reqLength and use BigReq if needed outside of corereq.js
// NOTE: big req is used here (first 'L' in format, 0 and +1 in params), won't work if not enabled // NOTE: big req is used here (first 'L' in format, 0 and +1 in params), won't work if not enabled
@ -1020,12 +1009,6 @@ var templates = {
return [ 'CxSssCCxx', [107, 3, timeout, interval, preferBlanking, allowExposures]]; return [ 'CxSssCCxx', [107, 3, timeout, interval, preferBlanking, allowExposures]];
} }
], ],
Bell: [
function(percent) {
return ["CxCs",[108,1]];
}
],
ForceScreenSaver: [ ForceScreenSaver: [
function(activate) { function(activate) {

View file

@ -258,7 +258,7 @@ exports.requireExt = function(display, callback)
ext.BindTexImage = function(ctx, drawable, buffer, attribs) { ext.BindTexImage = function(ctx, drawable, buffer, attribs) {
if (!attribs) if (!attribs)
attribs = []; attribs = [];
var data = Buffer.alloc(12 + attribs.length*4); var data = new Buffer(12 + attribs.length*4);
data.writeUInt32LE(drawable, 0); data.writeUInt32LE(drawable, 0);
data.writeUInt32LE(buffer, 4); data.writeUInt32LE(buffer, 4);
data.writeUInt32LE(attribs.length, 8); data.writeUInt32LE(attribs.length, 8);
@ -268,7 +268,7 @@ exports.requireExt = function(display, callback)
} }
ext.ReleaseTexImage = function(ctx, drawable, buffer) { ext.ReleaseTexImage = function(ctx, drawable, buffer) {
var data = Buffer.alloc(8); var data = new Buffer(8);
data.writeUint32LE(drawable, 0); data.writeUint32LE(drawable, 0);
data.writeUint32LE(buffer, 4); data.writeUint32LE(buffer, 4);
ext.VendorPrivate(ctx, 1331, data); ext.VendorPrivate(ctx, 1331, data);
@ -287,7 +287,7 @@ exports.requireExt = function(display, callback)
X.pack_stream.pack('CCSLSSL', [ext.majorOpcode, 2, length, ctx, requestNum, requestTotal, data.length]); X.pack_stream.pack('CCSLSSL', [ext.majorOpcode, 2, length, ctx, requestNum, requestTotal, data.length]);
X.pack_stream.write_queue.push(data); X.pack_stream.write_queue.push(data);
var pad = Buffer.alloc(padLength); var pad = new Buffer(padLength);
pad.fill(0); pad.fill(0);
X.pack_stream.write_queue.push(pad); X.pack_stream.write_queue.push(pad);
X.pack_stream.flush(); X.pack_stream.flush();

View file

@ -16,7 +16,7 @@ module.exports = function(GLX, ctx) {
throw Error('Buffer too big. Make sure you are using RenderLarge for large commands'); throw Error('Buffer too big. Make sure you are using RenderLarge for large commands');
currentLength += len; currentLength += len;
var res = Buffer.alloc(len); var res = Buffer(len);
res.writeUInt16LE(len, 0); res.writeUInt16LE(len, 0);
res.writeUInt16LE(opcode, 2); res.writeUInt16LE(opcode, 2);
return res; return res;
@ -266,7 +266,7 @@ module.exports = function(GLX, ctx) {
typeSize[constants.BYTE] = 1; typeSize[constants.BYTE] = 1;
typeSize[constants.UNSIGNED_BYTE] = 1; typeSize[constants.UNSIGNED_BYTE] = 1;
var res = Buffer.alloc(60 + data.length*typeSize[type]); var res = new Buffer(60 + data.length*typeSize[type]);
res.writeUInt32LE(res.length, 0); res.writeUInt32LE(res.length, 0);
res.writeUInt32LE(110, 4); res.writeUInt32LE(110, 4);

View file

@ -204,43 +204,7 @@ exports.requireExt = function(display, callback)
X.pack_stream.flush(); X.pack_stream.flush();
}, },
ext.GetOutputInfo = function(output, ts, cb)
{
X.seq_num ++;
X.pack_stream.pack('CCSLL', [ext.majorOpcode, 9, 3, output, ts ]);
X.replies[X.seq_num] = [
function(buf, opt) {
var i;
var pos = 0;
var res = buf.unpack('LLLLCCSSSSS');
var info = {
timestamp : res[0],
crtc : res[1],
mm_width : res[2],
mm_height : res[3],
connection : res[4],
subpixelOrder : res[5],
preferredModes: res[8]
};
pos += 28;
var format = Array(res[6] + 1).join('L');
info.crtcs = buf.unpack(format, pos);
pos += res[6] << 2;
format = Array(res[7] + 1).join('L');
info.modes = buf.unpack(format, pos);
pos += res[7] << 2;
format = Array(res[9] + 1).join('L');
info.clones = buf.unpack(format, pos);
pos += res[9] << 2;
info.name = buf.slice(pos, pos + res_modes[10]).toString('binary');
return info;
},
cb
];
X.pack_stream.flush();
},
ext.GetCrtcInfo = function(crtc, configTs, cb) { ext.GetCrtcInfo = function(crtc, configTs, cb) {
X.seq_num ++; X.seq_num ++;
X.pack_stream.pack('CCSLL', [ext.majorOpcode, 20, 3, crtc, configTs ]); X.pack_stream.pack('CCSLL', [ext.majorOpcode, 20, 3, crtc, configTs ]);

File diff suppressed because it is too large Load diff

View file

@ -21,7 +21,7 @@ exports.requireExt = function(display, callback)
ext.Kind = { ext.Kind = {
Bounding: 0, Bounding: 0,
Clip: 1, Clip: 1,
Input: 2 Input: 2
}; };
@ -31,19 +31,12 @@ exports.requireExt = function(display, callback)
Intersect: 2, Intersect: 2,
Subtract: 3, Subtract: 3,
Invert: 4 Invert: 4
}; }
ext.Ordering = {
Unsorted: 0,
YSorted: 1,
YXSorted: 2,
YXBanded: 3
};
ext.QueryVersion = function(cb) ext.QueryVersion = function(cb)
{ {
X.seq_num++; X.seq_num++;
// captureStack(); captureStack();
X.pack_stream.pack('CCSLL', [ext.majorOpcode, 0, 1]); X.pack_stream.pack('CCSLL', [ext.majorOpcode, 0, 1]);
X.replies[X.seq_num] = [ X.replies[X.seq_num] = [
function(buf, opt) { function(buf, opt) {
@ -55,36 +48,18 @@ exports.requireExt = function(display, callback)
X.pack_stream.flush(); X.pack_stream.flush();
} }
// Accepts rectangles as [[x, y, width, height]]
ext.Rectangles = function( op, kind, window, x, y, rectangles, ordering /* = Ordering.Unsorted */ )
{
if (ordering === undefined)
ordering = ext.Ordering.Unsorted;
var length = 4 + rectangles.length * 2;
X.seq_num++;
// captureStack();
X.pack_stream.pack('CCSCCCxLss', [ext.majorOpcode, 1, length, op, kind, ordering, window, x, y]);
for (var i = 0; i < rectangles.length; ++i) {
var r = rectangles[i];
X.pack_stream.pack('ssSS', r);
}
X.pack_stream.flush();
}
ext.Mask = function( op, kind, window, x, y, bitmap ) ext.Mask = function( op, kind, window, x, y, bitmap )
{ {
X.seq_num++; X.seq_num++;
// captureStack(); captureStack();
X.pack_stream.pack('CCSCCxxLssL', [ext.majorOpcode, 2, 5, op, kind, window, x, y, bitmap]); X.pack_stream.pack('CCSCCxxLssL', [ext.majorOpcode, 2, 5, op, kind, x, y, bitmap]);
X.pack_stream.flush(); X.pack_stream.flush();
} }
ext.SelectInput = function( window, enable ) ext.SelectInput = function( window, enable )
{ {
X.seq_num++; X.seq_num++;
// captureStack(); captureStack();
X.pack_stream.pack('CCSLCxxx', [ext.majorOpcode, 6, 3, window, enable ]); X.pack_stream.pack('CCSLCxxx', [ext.majorOpcode, 6, 3, window, enable ]);
X.pack_stream.flush(); X.pack_stream.flush();
} }
@ -92,7 +67,7 @@ exports.requireExt = function(display, callback)
ext.InputSelected = function( window, cb ) ext.InputSelected = function( window, cb )
{ {
X.seq_num++; X.seq_num++;
// captureStack(); captureStack();
X.pack_stream.pack('CCSL', [ext.majorOpcode, 7, 2, window ]); X.pack_stream.pack('CCSL', [ext.majorOpcode, 7, 2, window ]);
X.replies[X.seq_num] = [ X.replies[X.seq_num] = [
function(buf, opt) { function(buf, opt) {
@ -112,31 +87,5 @@ exports.requireExt = function(display, callback)
callback(null, ext); callback(null, ext);
}); });
*/ */
ext.events = {
ShapeNotify: 0
}
X.eventParsers[ext.firstEvent + ext.events.ShapeNotify] = function(type, seq, extra, code, raw)
{
var event = {};
event.type = type;
event.kind = code;
event.seq = seq;
event.window = extra;
var values = raw.unpack('ssSSLC');
event.x = values[0];
event.y = values[1];
event.width = values[2];
event.height = values[3];
event.time = values[4];
event.shaped = values[5];
event.name = 'ShapeNotify';
return event;
};
}); });
} }

View file

@ -1,22 +0,0 @@
/*
* GCFunction named shortcuts
*/
module.exports = {
GXclear : 0x0,
GXand : 0x1,
GXandReverse : 0x2,
GXcopy : 0x3,
GXandInverted : 0x4,
GXnoop : 0x5,
GXxor : 0x6,
GXor : 0x7,
GXnor : 0x8,
GXequiv : 0x9,
GXinvert : 0xa,
GXorReverse : 0xb,
GXcopyInverted : 0xc,
GXorInverted : 0xd,
GXnand : 0xe,
GXset : 0xf
};

View file

@ -12,15 +12,15 @@ function readVisuals(bl, visuals, n_visuals, cb)
var visual = {}; var visual = {};
bl.unpackTo( visual, bl.unpackTo( visual,
[ [
'L vid', 'L vid',
'C class', 'C class',
'C bits_per_rgb', 'C bits_per_rgb',
'S map_ent', 'S map_ent',
'L red_mask', 'L red_mask',
'L green_mask', 'L green_mask',
'L blue_mask', 'L blue_mask',
'xxxx' 'xxxx'
], ],
function() { function() {
var vid = visual.vid; var vid = visual.vid;
// delete visual.vid; // delete visual.vid;
@ -28,65 +28,57 @@ function readVisuals(bl, visuals, n_visuals, cb)
if (Object.keys(visuals).length == n_visuals) if (Object.keys(visuals).length == n_visuals)
cb() cb()
else else
readVisuals(bl, visuals, n_visuals, cb); readVisuals(bl, visuals, n_visuals, cb);
});
}
function readDepths(bl, display, depths, n_depths, cb)
{
if (n_depths == 0)
{
cb();
return;
}
bl.unpack( 'CxSxxxx', function(res) {
var dep = res[0];
var n_visuals = res[1];
var visuals = {};
readVisuals(bl, visuals, n_visuals, function()
{
depths[dep] = visuals;
if (Object.keys(depths).length == n_depths)
cb();
else
readDepths(bl, display, depths, n_depths, cb);
});
}); });
} }
function readScreens(bl, display, cbDisplayReady) function readScreens(bl, display, cbDisplayReady)
{ {
var numParsedDepths = 0;
var readDepths = function(bl, display, depths, n_depths, cb)
{
if (n_depths == 0)
{
cb();
return;
}
bl.unpack( 'CxSxxxx', function(res) {
var dep = res[0];
var n_visuals = res[1];
var visuals = {};
readVisuals(bl, visuals, n_visuals, function()
{
if (dep in depths) {
for (var visual in visuals) {
depths[dep][visual] = visuals[visual];
}
} else {
depths[dep] = visuals;
}
numParsedDepths++;
if (numParsedDepths == n_depths)
cb();
else
readDepths(bl, display, depths, n_depths, cb);
});
});
}
// for (i=0; i < display.screen_num; ++i) // for (i=0; i < display.screen_num; ++i)
{ {
var scr = {}; var scr = {};
bl.unpackTo( scr, bl.unpackTo( scr,
[ [
'L root', 'L root',
'L default_colormap', 'L default_colormap',
'L white_pixel', 'L white_pixel',
'L black_pixel', 'L black_pixel',
'L input_masks', 'L input_masks',
'S pixel_width', 'S pixel_width',
'S pixel_height', 'S pixel_height',
'S mm_width', 'S mm_width',
'S mm_height', 'S mm_height',
'S min_installed_maps', 'S min_installed_maps',
'S max_installed_maps', 'S max_installed_maps',
'L root_visual', 'L root_visual',
'C root_depth', 'C root_depth',
'C backing_stores', 'C backing_stores',
'C root_depth', 'C root_depth',
'C num_depths' 'C num_depths'
], ],
function () { function () {
var depths = {}; var depths = {};
readDepths(bl, display, depths, scr.num_depths, function() { readDepths(bl, display, depths, scr.num_depths, function() {
@ -94,17 +86,17 @@ function readScreens(bl, display, cbDisplayReady)
scr.depths = depths; scr.depths = depths;
delete scr.num_depths; delete scr.num_depths;
display.screen.push(scr); display.screen.push(scr);
if (display.screen.length == display.screen_num) if (display.screen.length == display.screen_num)
{ {
delete display.screen_num; delete display.screen_num;
cbDisplayReady(null, display); cbDisplayReady(display);
return; return;
} else { } else {
readScreens(bl, display, cbDisplayReady); readScreens(bl, display, cbDisplayReady);
} }
}); });
}); });
} }
} }
@ -112,18 +104,13 @@ function readServerHello(bl, cb)
{ {
bl.unpack('C', function(res) { bl.unpack('C', function(res) {
if (res[0] == 0) if (res[0] == 0)
{ {
// conection time error // conection time error
// unpack error // unpack error (? TODO)
bl.unpack('Cxxxxxx', function (rlen) { var err = new Error;
bl.get(rlen[0], function (reason) { cb(err); // TODO: detect that this is error on xcore side
var err = new Error;
err.message = 'X server connection failed: ' + reason.toString();
cb(err);
});
});
// TODO: do we need to close stream from our side? // TODO: do we need to close stream from our side?
// TODO: api to close source stream via attached unpackstream // TODO: api to close source stream via attached unpackstream
return; return;
@ -137,10 +124,10 @@ bl.unpack('C', function(res) {
'S major', 'S major',
'S minor', 'S minor',
'S xlen', 'S xlen',
'L release', 'L release',
'L resource_base', 'L resource_base',
'L resource_mask', 'L resource_mask',
'L motion_buffer_size', 'L motion_buffer_size',
'S vlen', 'S vlen',
'S max_request_length', 'S max_request_length',
'C screen_num', 'C screen_num',
@ -152,8 +139,8 @@ bl.unpack('C', function(res) {
'C min_keycode', 'C min_keycode',
'C max_keycode', 'C max_keycode',
'xxxx' 'xxxx'
], ],
function() function()
{ {
var pvlen = xutil.padded_length(display.vlen); var pvlen = xutil.padded_length(display.vlen);
@ -161,12 +148,12 @@ bl.unpack('C', function(res) {
// setup data to generate resource id // setup data to generate resource id
// TODO: cleaunup code here // TODO: cleaunup code here
var mask = display.resource_mask; var mask = display.resource_mask;
display.rsrc_shift = 0; display.rsrc_shift = 0;
while (!( (mask >> display.rsrc_shift) & 1) ) while (!( (mask >> display.rsrc_shift) & 1) )
display.rsrc_shift++; display.rsrc_shift++;
display.rsrc_id = 0; display.rsrc_id = 0;
bl.get(pvlen, function(vendor) bl.get(pvlen, function(vendor)
{ {
display.vendor = vendor.toString().substr(0, display.vlen); // utf8 by default? display.vendor = vendor.toString().substr(0, display.vlen); // utf8 by default?
@ -185,7 +172,7 @@ bl.unpack('C', function(res) {
readScreens(bl, display, cb); readScreens(bl, display, cb);
} }
}); });
} }
}); });
} }
); );
@ -202,28 +189,25 @@ function getByteOrder() {
} }
} }
function writeClientHello(stream, displayNum, authHost, authFamily) function writeClientHello(stream, displayNum, authHost)
{ {
getAuthString( displayNum, authHost, authFamily, function( err, cookie ) { getAuthString( displayNum, authHost, function( authType, authData ) {
if (err) {
throw err;
}
var byte_order = getByteOrder(); var byte_order = getByteOrder();
var protocol_major = 11; // TODO: config? env? var protocol_major = 11; // TODO: config? env?
var protocol_minor = 0; var protocol_minor = 0;
stream.pack( stream.pack(
'CxSSSSxxpp', 'CxSSSSxxpp',
[ [
byte_order, byte_order,
protocol_major, protocol_major,
protocol_minor, protocol_minor,
cookie.authName.length, authType.length,
cookie.authData.length, authData.length,
cookie.authName, authType,
cookie.authData authData
] ]
); );
stream.flush(); stream.flush();
}); });
} }

View file

@ -7,7 +7,7 @@
// It should create a pleasant looking hex dumb by default: // It should create a pleasant looking hex dumb by default:
// //
// var hexy = require('hexy.js'), // var hexy = require('hexy.js'),
// b = Buffer.alloc("\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789") // b = new Buffer("\000\001\003\005\037\012\011bcdefghijklmnopqrstuvwxyz0123456789")
// //
// console.log(hexy.hexy(b)) // console.log(hexy.hexy(b))
// //
@ -258,4 +258,4 @@ console.log(hexy(data, format))
console.log("doen") console.log("doen")
*/ */
exports.hexy = hexy exports.hexy = hexy

View file

@ -1,20 +1,13 @@
var core = require('./xcore'); var core = require('./xcore');
var em = require('./eventmask').eventMask; var em = require('./eventmask').eventMask;
var keysyms = require('./keysyms');
var server = require('./xserver'); var server = require('./xserver');
module.exports.createClient = core.createClient; module.exports.createClient = core.createClient;
module.exports.createServer = server.createServer; module.exports.createServer = server.createServer;
module.exports.eventMask = em; module.exports.eventMask = em;
module.exports.keySyms = keysyms;
Object.defineProperty(module.exports, 'keySyms', {
enumerable: true,
get: function() { return require('./keysyms'); }
});
Object.defineProperty(module.exports, 'gcFunction', {
enumerable: true,
get: function() { return require('./gcfunction'); }
});
//TODO: //TODO:
// keepe everything in namespace for consistensy (eventMask, keySyms, class, destination ... // keepe everything in namespace for consistensy (eventMask, keySyms, class, destination ...

File diff suppressed because it is too large Load diff

View file

@ -1,35 +0,0 @@
#!/bin/bash -e
keysymdef_url=http://cgit.freedesktop.org/xorg/proto/xproto/plain/keysymdef.h
keysymdef=$(mktemp)
wget $keysymdef_url -O $keysymdef
(
echo "
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\\
This file is automatically translated from X.Org's xproto/keysymdef.h
Please, do not update this file with your hands, run $(basename "$0").
\\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
module.exports = {
"
sed -r '
s/#ifdef\s+/\/\/ Group /
s/#endif.*//
s/#define\s+([^ ]+)(\s+)([^ ]+)\s*\/\*\s*([^\*]+[^ ])\s*\*\// \1:\2{ code: \3, description: "\4" },/
s/(\b)U\+([0-9A-F]+)(\b)/\1(\\u\2)\3/i
s/#define\s+([^ ]+)(\s+)([^ ]+)/ \1:\2{ code: \3, description: null },/
#s/#define\s+([^ ]+)(\s+[^ ]+)/ \1:\2,/
' $keysymdef
echo -n '
NoSymbol: 0
};'
) > "$(dirname "$0")/keysyms.js"
rm $keysymdef

View file

@ -23,7 +23,7 @@ function ReadFixedRequest(length, callback)
{ {
this.length = length; this.length = length;
this.callback = callback; this.callback = callback;
this.data = Buffer.alloc(length); this.data = new Buffer(length);
this.received_bytes = 0; this.received_bytes = 0;
} }
@ -201,7 +201,7 @@ UnpackStream.prototype.pstr = function(str)
var len = xutil.padded_length(str.length); var len = xutil.padded_length(str.length);
if (len == 0) if (len == 0)
return; // nothing to write return; // nothing to write
var buf = Buffer.alloc(len); var buf = new Buffer(len);
buf.write(str, 'binary'); buf.write(str, 'binary');
this.write_queue.push(buf); this.write_queue.push(buf);
} }
@ -231,7 +231,7 @@ UnpackStream.prototype.pack = function(format, args)
} }
} }
var buf = Buffer.alloc(packetlength); var buf = new Buffer(packetlength);
var offset = 0; var offset = 0;
var arg = 0; var arg = 0;
for (var i = 0; i < format.length; ++i) for (var i = 0; i < format.length; ++i)
@ -269,14 +269,12 @@ UnpackStream.prototype.pack = function(format, args)
buf[offset++] = (n >> 16) & 0xff; buf[offset++] = (n >> 16) & 0xff;
buf[offset++] = (n >> 24) & 0xff; buf[offset++] = (n >> 24) & 0xff;
break; break;
case 'a': // string, buffer, or array case 'a': // string or buffer
var str = args[arg++]; var str = args[arg++];
if (Buffer.isBuffer(str)) if (Buffer.isBuffer(str))
{ {
str.copy(buf, offset); str.copy(buf, offset);
offset += str.length; offset += str.length;
} else if(Array.isArray(str)) {
for(var item of str) buf[offset++] = item;
} else { } else {
// TODO: buffer.write could be faster // TODO: buffer.write could be faster
for (var c = 0; c < str.length; ++c) for (var c = 0; c < str.length; ++c)

View file

@ -6,6 +6,7 @@ var handshake = require('./handshake');
var EventEmitter = require('events').EventEmitter; var EventEmitter = require('events').EventEmitter;
var PackStream = require('./unpackstream'); var PackStream = require('./unpackstream');
var coreRequestsTemplate = require('./corereqs');
var hexy = require('./hexy').hexy; var hexy = require('./hexy').hexy;
var Buffer = require('buffer').Buffer; var Buffer = require('buffer').Buffer;
@ -19,28 +20,10 @@ var coreRequests = require('./corereqs');
var stdatoms = require('./stdatoms'); var stdatoms = require('./stdatoms');
var em = require('./eventmask').eventMask; var em = require('./eventmask').eventMask;
function stash () function XClient(stream, displayNum, screenNum, options)
{
require('./ext/apple-wm');
require('./ext/big-requests');
require('./ext/composite');
require('./ext/damage');
require('./ext/dpms');
require('./ext/fixes');
require('./ext/glxconstants');
require('./ext/glx');
require('./ext/glxrender');
require('./ext/randr');
require('./ext/render');
require('./ext/screen-saver');
require('./ext/shape');
require('./ext/xc-misc');
require('./ext/xtest');
}
function XClient(displayNum, screenNum, options)
{ {
EventEmitter.call(this); EventEmitter.call(this);
this.stream = stream;
this.options = options ? options : {}; this.options = options ? options : {};
// TODO: this is probably not used // TODO: this is probably not used
@ -49,20 +32,7 @@ function XClient(displayNum, screenNum, options)
this.displayNum = displayNum; this.displayNum = displayNum;
this.screenNum = screenNum; this.screenNum = screenNum;
} this.authHost = os.hostname();
util.inherits(XClient, EventEmitter);
XClient.prototype.init = function(stream)
{
this.stream = stream;
this.authHost = stream.remoteAddress;
// Node v0.10.x does not have stream.remoteFamily, so dig in to find it
this.authFamily = stream._getpeername ? stream._getpeername().family : stream.remoteFamily;
if (!this.authHost || this.authHost === '127.0.0.1' || this.authHost === '::1') {
this.authHost = os.hostname();
this.authFamily = null;
}
var pack_stream = new PackStream(); var pack_stream = new PackStream();
@ -132,14 +102,13 @@ XClient.prototype.init = function(stream)
this.event_consumers = {}; // maps window id to eventemitter TODO: bad name this.event_consumers = {}; // maps window id to eventemitter TODO: bad name
this.eventParsers = {}; this.eventParsers = {};
this.errorParsers = {}; this.errorParsers = {};
this._extensions = {};
this.importRequestsFromTemplates(this, coreRequests); this.importRequestsFromTemplates(this, coreRequests);
this.startHandshake(); this.startHandshake();
this._closing = false; this._closing = false;
this._unusedIds = [];
} }
util.inherits(XClient, EventEmitter);
// TODO: close() = set 'closing' flag, watch it in replies and writeQueue, terminate if empty // TODO: close() = set 'closing' flag, watch it in replies and writeQueue, terminate if empty
XClient.prototype.terminate = function() XClient.prototype.terminate = function()
@ -267,17 +236,12 @@ XClient.prototype.importRequestsFromTemplates = function(target, reqs)
XClient.prototype.AllocID = function() XClient.prototype.AllocID = function()
{ {
if (this._unusedIds.length > 0) { // TODO: handle overflow (XCMiscGetXIDRange from XC_MISC ext)
return this._unusedIds.pop(); // TODO: unused id buffer
} this.display.rsrc_id++;
// TODO: handle overflow (XCMiscGetXIDRange from XC_MISC ext) return (this.display.rsrc_id << this.display.rsrc_shift) + this.display.resource_base;
this.display.rsrc_id++; }
return (this.display.rsrc_id << this.display.rsrc_shift) + this.display.resource_base;
};
XClient.prototype.ReleaseID = function(id) {
this._unusedIds.push(id);
};
// TODO: move core events unpackers to corereqs.js // TODO: move core events unpackers to corereqs.js
XClient.prototype.unpackEvent = function(type, seq, extra, code, raw, headerBuf) XClient.prototype.unpackEvent = function(type, seq, extra, code, raw, headerBuf)
@ -311,8 +275,8 @@ XClient.prototype.unpackEvent = function(type, seq, extra, code, raw, headerBuf)
event.y = values[6]; event.y = values[6];
event.buttons = values[7]; event.buttons = values[7];
event.sameScreen = values[8]; event.sameScreen = values[8];
} else if (type == 7 || type == 8) { //EnterNotify || LeaveNotify } else if (type == 7) { //EnterNotify
event.name = type === 7 ? 'EnterNotify' : 'LeaveNotify'; event.name = 'EnterNotify'
var values = raw.unpack('LLLssssSC'); var values = raw.unpack('LLLssssSC');
event.root = values[0] event.root = values[0]
event.wid = values[1] event.wid = values[1]
@ -322,14 +286,7 @@ XClient.prototype.unpackEvent = function(type, seq, extra, code, raw, headerBuf)
event.x = values[5]; event.x = values[5];
event.y = values[6]; event.y = values[6];
event.values = values event.values = values
} else if (type == 9) { // FocusIn
event.name = "FocusIn";
event.mode = raw.unpack('C')[0];
event.wid = extra;
} else if (type == 10) { // FocusOut
event.name = "FocusOut";
event.mode = raw.unpack('C')[0];
event.wid = extra;
} else if (type == 12) { // Expose } else if (type == 12) { // Expose
var values = raw.unpack('SSSSS'); var values = raw.unpack('SSSSS');
event.name = 'Expose' event.name = 'Expose'
@ -340,36 +297,36 @@ XClient.prototype.unpackEvent = function(type, seq, extra, code, raw, headerBuf)
event.height = values[3]; event.height = values[3];
event.count = values[4]; // TODO: ??? event.count = values[4]; // TODO: ???
} else if (type == 16) { // CreateNotify } else if (type == 16) { // CreateNotify
var values = raw.unpack('LssSSSc'); var values = raw.unpack('LLssSSSc');
event.name = 'CreateNotify' event.name = 'CreateNotify'
event.parent = extra; event.parent = values[0];
event.wid = values[0]; event.wid = values[1];
event.x = values[1]; event.x = values[2];
event.y = values[2]; event.y = values[3];
event.width = values[3]; event.width = values[4];
event.height = values[4]; event.height = values[5];
event.borderWidth = values[5]; event.borderWidth = values[6];
event.overrideRedirect = values[6] ? true : false; event.overrideRedirect = values[7] ? true : false;
// x, y, width, height, border // x, y, width, height, border
} else if (type == 17) { // destroy notify } else if (type == 17) { // destroy notify
var values = raw.unpack('L'); var values = raw.unpack('LL');
event.name = 'DestroyNotify' event.name = 'DestroyNotify'
event.event = extra; event.event = extra;
event.wid = values[0]; event.wid = values[0];
} else if (type == 18) { // UnmapNotify } else if (type == 18) { // UnmapNotify
var values = raw.unpack('LC'); var values = raw.unpack('LLC');
event.name = 'UnmapNotify' event.name = 'UnmapNotify'
event.event = extra; event.event = extra;
event.wid = values[0]; event.wid = values[0];
event.fromConfigure = values[1] ? true : false; event.fromConfigure = values[1] ? true : false;
} else if (type == 19) { // MapNotify } else if (type == 19) { // MapNotify
var values = raw.unpack('LC'); var values = raw.unpack('LLC');
event.name = 'MapNotify' event.name = 'MapNotify'
event.event = extra; event.event = extra;
event.wid = values[0]; event.wid = values[0];
event.overrideRedirect = values[1] ? true : false; event.overrideRedirect = values[1] ? true : false;
} else if (type == 20) { } else if (type == 20) {
var values = raw.unpack('L'); var values = raw.unpack('LL');
event.name = 'MapRequest' event.name = 'MapRequest'
event.parent = extra; event.parent = extra;
event.wid = values[0]; event.wid = values[0];
@ -443,7 +400,7 @@ XClient.prototype.unpackEvent = function(type, seq, extra, code, raw, headerBuf)
event.name = 'ClientMessage'; event.name = 'ClientMessage';
event.format = code; event.format = code;
event.wid = extra; event.wid = extra;
event.message_type = raw.unpack('L')[0]; event.type = raw.readUInt32LE(0);
var format = (code === 32) ? 'LLLLL' : (code === 16) ? 'SSSSSSSSSS' : 'CCCCCCCCCCCCCCCCCCCC'; var format = (code === 32) ? 'LLLLL' : (code === 16) ? 'SSSSSSSSSS' : 'CCCCCCCCCCCCCCCCCCCC';
event.data = raw.unpack(format, 4); event.data = raw.unpack(format, 4);
} else if (type == 34) { } else if (type == 34) {
@ -451,6 +408,9 @@ XClient.prototype.unpackEvent = function(type, seq, extra, code, raw, headerBuf)
event.request = headerBuf[4]; event.request = headerBuf[4];
event.firstKeyCode = headerBuf[5]; event.firstKeyCode = headerBuf[5];
event.count = headerBuf[6]; event.count = headerBuf[6];
// TODO cleanup
console.log(values);
console.log(raw);
} }
return event; return event;
} }
@ -515,7 +475,7 @@ XClient.prototype.expectReplyHeader = function()
// raw event 32-bytes packet (primarily for use in SendEvent); // raw event 32-bytes packet (primarily for use in SendEvent);
// TODO: Event::pack based on event parameters, inverse to unpackEvent // TODO: Event::pack based on event parameters, inverse to unpackEvent
ev.rawData = Buffer.alloc(32); ev.rawData = new Buffer(32);
headerBuf.copy(ev.rawData); headerBuf.copy(ev.rawData);
buf.copy(ev.rawData, 8); buf.copy(ev.rawData, 8);
@ -560,16 +520,15 @@ XClient.prototype.expectReplyHeader = function()
); );
} }
XClient.prototype.startHandshake = function() { XClient.prototype.startHandshake = function()
{
var client = this; var client = this;
handshake.writeClientHello(this.pack_stream, this.displayNum, this.authHost, this.authFamily); handshake.writeClientHello(this.pack_stream, this.displayNum, this.authHost);
handshake.readServerHello(this.pack_stream, function(err, display) handshake.readServerHello(this.pack_stream, function(display)
{ {
if (err) { // TODO: readServerHello can set error state in display
client.emit('error', err); // emit error in that case
return;
}
client.expectReplyHeader(); client.expectReplyHeader();
client.display = display; client.display = display;
display.client = client; display.client = client;
@ -579,24 +538,9 @@ XClient.prototype.startHandshake = function() {
XClient.prototype.require = function(extName, callback) XClient.prototype.require = function(extName, callback)
{ {
var self = this; var ext = require('./ext/' + extName);
var ext = this._extensions[extName]; ext.requireExt(this.display, callback);
if (ext) { }
return process.nextTick(function() {
callback(null, ext);
});
}
ext = require('./ext/' + extName);
ext.requireExt(this.display, function(err, _ext) {
if (err) {
return callback(err);
}
self._extensions[extName] = _ext;
callback(null, _ext);
});
};
module.exports.createClient = function(options, initCb) module.exports.createClient = function(options, initCb)
{ {
@ -616,6 +560,8 @@ module.exports.createClient = function(options, initCb)
throw new Error("Cannot parse display"); throw new Error("Cannot parse display");
var host = displayMatch[1]; var host = displayMatch[1];
if (!host)
host = '127.0.0.1';
var displayNum = displayMatch[2]; var displayNum = displayMatch[2];
if (!displayNum) if (!displayNum)
@ -626,8 +572,6 @@ module.exports.createClient = function(options, initCb)
// open stream // open stream
var stream; var stream;
var connected = false;
var cbCalled = false;
var socketPath; var socketPath;
// try local socket on non-windows platforms // try local socket on non-windows platforms
@ -640,38 +584,22 @@ module.exports.createClient = function(options, initCb)
{ {
socketPath = display; socketPath = display;
} }
} else if(!host) } else if(host == '127.0.0.1') //TODO check if it's consistent with xlib (DISPLAY=127.0.0.1:0 -> local unix socket or port 6000?)
socketPath = '/tmp/.X11-unix/X' + displayNum; socketPath = '/tmp/.X11-unix/X' + displayNum;
} }
var client = new XClient(displayNum, screenNum, options); //socketPath = '/tmp/.X11-unix/X' + displayNum;
if(socketPath)
var connectStream = function() { {
if (socketPath) { stream = net.createConnection(socketPath);
stream = net.createConnection(socketPath); }
} else { else
stream = net.createConnection(6000 + parseInt(displayNum), host); {
} stream = net.createConnection(6000 + parseInt(displayNum), host);
stream.on('connect', function() { }
connected = true; var client = new XClient(stream, displayNum, screenNum, options);
client.init(stream);
});
stream.on('error', function(err) {
if (!connected && socketPath && err.code === 'ENOENT') {
// Retry connection with TCP on localhost
socketPath = null;
host = 'localhost';
connectStream();
} else if (initCb && !cbCalled) {
cbCalled = true;
initCb(err);
} else {
client.emit('error', err);
}
});
};
connectStream();
if (initCb) if (initCb)
{ {
var cbCalled = false;
client.on('connect', function(display) { client.on('connect', function(display) {
// opt-in BigReq // opt-in BigReq
if (!options.disableBigRequests) { if (!options.disableBigRequests) {
@ -689,6 +617,14 @@ module.exports.createClient = function(options, initCb)
initCb(undefined, display); initCb(undefined, display);
} }
}); });
stream.on('error', function(err) {
if (cbCalled)
client.emit('error', err);
else {
cbCalled = true;
initCb(err);
}
});
} }
return client; return client;
} }

View file

@ -12,7 +12,7 @@
"X" "X"
], ],
"homepage": "https://github.com/sidorares/node-x11", "homepage": "https://github.com/sidorares/node-x11",
"version": "2.3.0", "version": "1.0.2",
"maintainers": [ "maintainers": [
{ {
"name": "Andrey Sidorov", "name": "Andrey Sidorov",
@ -40,15 +40,14 @@
"node": "*" "node": "*"
}, },
"devDependencies": { "devDependencies": {
"async": "^3.0.1", "mocha": "*",
"mocha": "^7.1.2", "should": "*",
"sax": "^1.2.4", "sax": "*",
"should": "^13.2.1", "async": "*",
"sinon": "^7.2.5" "sinon": "*"
}, },
"scripts": { "scripts": {
"test": "node test-runner.js", "test": "node test-runner.js",
"prepublish": "npm prune" "prepublish": "npm prune"
}, }
"dependencies": {}
} }

View file

@ -1,103 +0,0 @@
var x11 = require('../lib');
var should = require('should');
var assert = require('assert');
// This test was ported from X Test Suite @ http://cgit.freedesktop.org/xorg/test/xts/
function warp_pointer(wid, x, y, cb) {
var self = this;
this.X.QueryPointer(wid, function(err, old_pointer) {
if (err) {
return cb(err);
}
self.X.WarpPointer(0,
wid,
0,
0,
0,
0,
x,
y);
self.X.QueryPointer(wid, function(err, new_pointer) {
if (err) {
return cb(err);
}
cb(undefined, {
old_x : old_pointer.childX,
old_y : old_pointer.childY,
new_x : new_pointer.childX,
new_y : new_pointer.childY
});
});
});
}
function is_pointer_frozen(cb) {
var self = this;
warp_pointer.call(this, this.wid, 0, 0, function(err) {
if (err) {
return cb(err);
}
warp_pointer.call(self, self.wid, 1, 1, function(err, data) {
if (err) {
return cb(err);
}
cb(undefined, data.old_x === data.new_x);
});
});
}
describe('AllowEvents', function() {
before(function(done) {
var self = this;
var client = x11.createClient(function(err, dpy) {
should.not.exist(err);
self.X = dpy.client;
self.screen = dpy.screen[0];
self.root = self.screen.root;
self.wid = self.X.AllocID();
self.X.CreateWindow(self.wid,
self.root,
0,
0,
self.screen.pixel_width,
self.screen.pixel_height);
self.X.MapWindow(self.wid);
done();
});
client.on('error', function (err) {
console.error('Error : ', err);
});
});
it('if pointer is frozen by the client calling AllowEvents with AsyncPointer should resume the processing', function(done) {
var self = this;
this.X.GrabPointer(
this.wid,
false,
x11.eventMask.PointerMotion,
0, // sync
1, // async
0, // None
0, // None
0
);
is_pointer_frozen.call(this, function(err, frozen) {
should.not.exist(err);
frozen.should.equal(true);
self.X.AllowEvents(0, 0);
is_pointer_frozen.call(self, function(err, frozen) {
should.not.exist(err);
frozen.should.equal(false);
done();
});
});
});
});

View file

@ -63,7 +63,7 @@ describe('Atoms and atom names cache', function() {
}); });
}); });
xit('should be used after the first request for non-std atom_names', function(done) { it('should be used after the first request for non-std atom_names', function(done) {
var self = this; var self = this;
var my_name; var my_name;
/* /*
@ -94,7 +94,7 @@ describe('Atoms and atom names cache', function() {
function(err) { function(err) {
should.not.exist(err); should.not.exist(err);
should.exist(my_name); should.exist(my_name);
self.spy.resetHistory(); self.spy.reset();
self.X.InternAtom(true, my_name, function(err, atom) { self.X.InternAtom(true, my_name, function(err, atom) {
should.not.exist(err); should.not.exist(err);
my_atom.should.equal(atom); my_atom.should.equal(atom);

View file

@ -1,34 +0,0 @@
var x11 = require('../lib');
var should = require('should');
describe('requiring an X11 extension on same connection', function() {
before(function(done) {
var self = this;
var client = x11.createClient(function(err, dpy) {
should.not.exist(err);
self.X = dpy.client;
done();
});
client.on('error', function (err) {
console.error('Error : ', err);
});
});
it('should be cached', function(done) {
var self = this;
this.X.require('xtest', function(err, randr) {
should.not.exist(err);
self.X.require('xtest', function(err, randr1) {
should.not.exist(err);
randr.should.equal(randr1);
done();
});
});
});
after(function(done) {
this.X.terminate();
this.X.on('end', done);
});
});

View file

@ -27,7 +27,7 @@ describe('ChangeProperty', function() {
var self = this; var self = this;
this.X.InternAtom(false, TEST_PROPERTY, function(err, atom) { this.X.InternAtom(false, TEST_PROPERTY, function(err, atom) {
should.not.exist(err); should.not.exist(err);
var raw = Buffer.alloc(4); var raw = new Buffer(4);
raw.writeUInt32LE(self.wid, 0); raw.writeUInt32LE(self.wid, 0);
self.X.ChangeProperty(0, self.wid, atom, self.X.atoms.WINDOW, 32, raw); self.X.ChangeProperty(0, self.wid, atom, self.X.atoms.WINDOW, 32, raw);
self.X.once('event', function(ev) { self.X.once('event', function(ev) {
@ -47,7 +47,7 @@ describe('ChangeProperty', function() {
var self = this; var self = this;
this.X.InternAtom(false, TEST_PROPERTY, function(err, atom) { this.X.InternAtom(false, TEST_PROPERTY, function(err, atom) {
should.not.exist(err); should.not.exist(err);
var raw = Buffer.from(new Array(8)); var raw = new Buffer(new Array(8));
raw.writeUInt32LE(self.wid, 0); raw.writeUInt32LE(self.wid, 0);
raw.writeUInt32LE(self.wid_helper, 4); raw.writeUInt32LE(self.wid_helper, 4);
self.X.ChangeProperty(0, self.wid, atom, self.X.atoms.ATOM, 32, raw); self.X.ChangeProperty(0, self.wid, atom, self.X.atoms.ATOM, 32, raw);
@ -69,7 +69,7 @@ describe('ChangeProperty', function() {
var self = this; var self = this;
this.X.InternAtom(false, TEST_PROPERTY, function(err, atom) { this.X.InternAtom(false, TEST_PROPERTY, function(err, atom) {
should.not.exist(err); should.not.exist(err);
var raw = Buffer.alloc(0); var raw = new Buffer(0);
self.X.ChangeProperty(0, self.wid, atom, self.X.atoms.WINDOW, 32, raw); self.X.ChangeProperty(0, self.wid, atom, self.X.atoms.WINDOW, 32, raw);
self.X.once('event', function(ev) { self.X.once('event', function(ev) {
ev.type.should.equal(28); ev.type.should.equal(28);

View file

@ -1,54 +0,0 @@
var x11 = require('../lib');
var should = require('should');
describe('CreateGC', function() {
before(function(done) {
var self = this;
this.client = x11.createClient(function(err, dpy) {
should.not.exist(err);
self.X = dpy.client;
self.root = dpy.screen[0].root;
self.white = dpy.screen[0].white_pixel;
self.black = dpy.screen[0].black_pixel;
self.wid = self.X.AllocID();
self.X.CreateWindow(self.wid, self.root, 0, 0, 1, 1); // 1x1 pixel window
self.X.MapWindow(self.wid);
self.X.QueryTree(self.root, function(err, list) {
should.not.exist(err);
list.children.indexOf(self.wid).should.not.equal(-1);
done();
});
});
});
it('should create a Graphic Context correctly', function() {
var self = this;
this.client.on('error', function(err) {
should.not.exist(err);
});
this.gc = this.X.AllocID();
this.X.CreateGC(this.gc,
this.wid,
{
foreground: this.black,
background: this.white,
lineStyle : 0
}
);
this.X.ChangeGC(this.gc,
{
foreground: 0xffff00,
background: 0x0000ff,
lineStyle : 2
}
);
});
after(function(done) {
this.X.DestroyWindow(this.wid);
this.X.on('end', done);
this.X.terminate();
});
});

View file

@ -1,114 +0,0 @@
var x11 = require('../lib');
var UnpackStream = require('../lib/unpackstream.js');
var should = require('should');
//Used Atoms
var ATOM = {};
describe('ClientMessage', function() {
before(function(done) {
var self = this;
var client = x11.createClient(function(err, dpy) {
should.not.exist(err);
self.X = dpy.client;
self.wid = self.X.AllocID();
self.X.CreateWindow(self.wid, dpy.screen[0].root, 0, 0, 1, 1); // 1x1 pixel window
self.X.InternAtom(false, 'TEST_ATOM_1', function(err, atom) {
should.not.exist(err);
ATOM['TEST_ATOM_1'] = atom;
done();
});
});
client.on('error', done);
});
it('should receive client message with format=8', function(done) {
var self = this;
var client = x11.createClient(function(err, dpy) {
should.not.exist(err);
self.X.once('event', function(ev) {
ev.name.should.equal('ClientMessage');
ev.wid.should.equal(self.wid);
ev.message_type.should.equal(ATOM.TEST_ATOM_1);
ev.data.should.be.an.Array();
ev.data.length.should.equal(20);
done();
});
var X = dpy.client;
var eventData = Buffer.alloc(32);
eventData.writeInt8(33, 0); //Event Type 33 = ClientMessage
eventData.writeInt8(8, 1); //Format
eventData.writeInt32LE(self.wid, 4); //Window ID
eventData.writeInt32LE(ATOM.TEST_ATOM_1, 8); //Message Type
X.SendEvent(self.wid, false, 0, eventData);
});
client.on('error', done);
});
it('should receive client message with format=16', function(done) {
var self = this;
var client = x11.createClient(function(err, dpy) {
should.not.exist(err);
self.X.once('event', function(ev) {
ev.name.should.equal('ClientMessage');
ev.wid.should.equal(self.wid);
ev.message_type.should.equal(ATOM.TEST_ATOM_1);
ev.data.should.be.an.Array();
ev.data.length.should.equal(10);
done();
});
var X = dpy.client;
var eventData = Buffer.alloc(32);
eventData.writeInt8(33, 0); //Event Type 33 = ClientMessage
eventData.writeInt8(16, 1); //Format
eventData.writeInt32LE(self.wid, 4); //Window ID
eventData.writeInt32LE(ATOM.TEST_ATOM_1, 8); //Message Type
X.SendEvent(self.wid, false, 0, eventData);
});
client.on('error', done);
});
it('should receive client message with format=32', function(done) {
var self = this;
var client = x11.createClient(function(err, dpy) {
should.not.exist(err);
self.X.once('event', function(ev) {
ev.name.should.equal('ClientMessage');
ev.wid.should.equal(self.wid);
ev.message_type.should.equal(ATOM.TEST_ATOM_1);
ev.data.should.be.an.Array();
ev.data.length.should.equal(5);
done();
});
var X = dpy.client;
var eventData = Buffer.alloc(32);
eventData.writeInt8(33, 0); //Event Type 33 = ClientMessage
eventData.writeInt8(32, 1); //Format
eventData.writeInt32LE(self.wid, 4); //Window ID
eventData.writeInt32LE(ATOM.TEST_ATOM_1, 8); //Message Type
X.SendEvent(self.wid, false, 0, eventData);
});
client.on('error', done);
});
after(function(done) {
this.X.DestroyWindow(this.wid);
this.X.on('end', done);
this.X.terminate();
});
});

View file

@ -72,29 +72,7 @@ describe('ConfigureWindow', function() {
this.X.RaiseWindow(this.wid); this.X.RaiseWindow(this.wid);
}); });
it('should LowerWindow correctly', function(done) {
var self = this;
this.X.once('event', function(ev) {
ev.type.should.equal(22); /* ConfigureNotify */
ev.aboveSibling.should.equal(0); /* 0 -> no window below this */
done();
});
this.X.LowerWindow(this.wid);
});
it('should ignore invalid mask values', function(done) {
this.X.once('event', function(ev) {
ev.x.should.equal(0);
done();
});
this.X.ConfigureWindow(this.wid, { foo : 3, x : 0 }, function(err) {
console.log(err);
});
});
after(function(done) { after(function(done) {
this.X.removeAllListeners('event');
this.X.DestroyWindow(this.wid); this.X.DestroyWindow(this.wid);
this.X.DestroyWindow(this.wid_helper); this.X.DestroyWindow(this.wid_helper);
this.X.on('end', done); this.X.on('end', done);

View file

@ -57,47 +57,4 @@ describe('CreateWindow request', function() {
done(); done();
}); });
}); });
it('should emit CreateNotify event when', function(done) {
var wid = X.AllocID();
var root = display.screen[0].root;
X.ChangeWindowAttributes(root, { eventMask: x11.eventMask.SubstructureNotify });
X.on('event', function(ev) {
switch (ev.name) {
case 'CreateNotify':
ev.parent.should.equal(root);
ev.wid.should.equal(wid);
ev.x.should.equal(0);
ev.y.should.equal(0);
ev.width.should.equal(1);
ev.height.should.equal(1);
ev.borderWidth.should.equal(0);
ev.overrideRedirect.should.equal(false);
break;
case 'MapNotify':
ev.event.should.equal(root);
ev.wid.should.equal(wid);
ev.overrideRedirect.should.equal(false);
X.UnmapWindow(wid);
break;
case 'UnmapNotify':
ev.event.should.equal(root);
ev.wid.should.equal(wid);
ev.fromConfigure.should.equal(false);
X.DestroyWindow(wid);
break;
case 'DestroyNotify':
ev.event.should.equal(root);
ev.wid.should.equal(wid);
done();
break;
}
});
X.CreateWindow(wid, root, 0, 0, 1, 1); // 1x1 pixel window
X.MapWindow(wid);
})
}); });

View file

@ -8,41 +8,43 @@ describe('KillKlient request', function() {
var X; var X;
beforeEach(function(done) { beforeEach(function(done) {
var client = x11.createClient(function(err, dpy) { var client = x11.createClient(function(err, dpy) {
should.not.exist(err); if (!err) {
display = dpy; display = dpy;
X = display.client; X = display.client;
var root = display.screen[0].root; }
var eventMask = x11.eventMask.SubstructureNotify;
X.ChangeWindowAttributes(root, { eventMask: eventMask });
done();
});
client.on('error', done); done(err);
});
client.on('error', function(err) {
done(err);
});
}); });
afterEach(function(done) { afterEach(function(done) {
X.on('end', done);
X.terminate(); X.terminate();
X.on('end', done);
X = null;
display = null;
}); });
it('should exist as client member', function() { it('should exist as client member', function(done) {
should.exist(X.KillKlient); should.exist(X.KillKlient);
assert.equal(typeof X.KillKlient, 'function'); assert.equal(typeof X.KillKlient, 'function');
done();
}); });
it('should terminate other client connection', function(done) { it('should terminate other client connection', function(done) {
x11.createClient(function(err, dpy) { x11.createClient(function(err, dpy) {
should.not.exist(err); if (!err) {
var otherclient = dpy.client; var otherclient = dpy.client;
var wnd = otherclient.AllocID(); var wnd = otherclient.AllocID();
X.once('event', function(ev) { otherclient.CreateWindow(wnd, dpy.screen[0].root, 0, 0, 1, 1);
ev.name.should.equal('CreateNotify'); otherclient.on('end', done);
ev.wid.should.equal(wnd); X.KillKlient(wnd);
X.KillKlient(wnd); } else {
}); done(err);
}
otherclient.CreateWindow(wnd, dpy.screen[0].root, 0, 0, 1, 1);
otherclient.on('end', done);
}); });
}); });
}); });

View file

@ -1,5 +1,4 @@
var x11 = require('../lib'); var x11 = require('../lib');
var async = require('async');
var should = require('should'); var should = require('should');
var assert = require('assert'); var assert = require('assert');
var util = require('util'); var util = require('util');
@ -13,7 +12,7 @@ describe('RANDR extension', function() {
self.screen = dpy.screen[0]; self.screen = dpy.screen[0];
self.root = self.screen.root; self.root = self.screen.root;
self.X.require('randr', function(err, ext) { self.X.require('randr', function(err, ext) {
should.not.exist(err); err.should.equal(null);
self.randr = ext; self.randr = ext;
/* We HAVE to QueryVersion before using it. Otherwise it does not work as expected */ /* We HAVE to QueryVersion before using it. Otherwise it does not work as expected */
self.randr.QueryVersion(1, 2, done); self.randr.QueryVersion(1, 2, done);
@ -36,26 +35,6 @@ describe('RANDR extension', function() {
}); });
}); });
it('GetScreenResources && GetOutputInfo', function(done) {
var self = this;
this.randr.GetScreenResources(this.root, function(err, resources) {
should.not.exist(err);
should.exist(resources);
async.each(
resources.outputs,
function(output, cb) {
self.randr.GetOutputInfo(output, 0, function(err, info) {
should.not.exist(err);
should.exist(info);
cb();
});
},
done
);
});
});
after(function(done) { after(function(done) {
this.X.terminate(); this.X.terminate();
this.X.on('end', done); this.X.on('end', done);

View file

@ -1,16 +0,0 @@
var fs = require('fs');
var assert = require('assert');
describe('all extension modules', function() {
it('should not throw when require\'d', function(done) {
var extFolder = __dirname + '/../lib/ext';
fs.readdir(extFolder, function(err, list) {
assert.ifError(err);
list.forEach(function(name) {
var m = require(extFolder + '/' + name);
});
done();
});
});
})