"use strict"; var util = Require('util'); var net = Require('net'); var PackStream = Require('x11/core/unpackstream'); var EventEmitter = Require('events').EventEmitter; function XServer(servsock, params) { var server = this; EventEmitter.call(this); servsock.on('connection', function(stream) { var cli = new XServerClientConnection(stream, params); server.emit('connection', cli); }); } util.inherits(XServer, EventEmitter); function XServerClientConnection(stream, params) { EventEmitter.call(this); this.params = params; var serv = this; serv.stream = stream; serv.pack_stream = new PackStream(); serv.pack_stream.on('data', function( data ) { serv.stream.write(data); }); stream.on('data', function( data ) { serv.pack_stream.write(data); }); serv.sequence = 0; serv.readClientHandshake(); } util.inherits(XServerClientConnection, EventEmitter); XServerClientConnection.prototype.readClientHandshake = function() { var serv = this; var hello = {}; serv.pack_stream.unpackTo(hello, [ 'C byteOrder', 'x', 'S protocolMajor', 'S protocolMinor', 'S authTypeLength', 'S authDataLength', 'x', 'x' ], function() { console.log(hello); serv.pack_stream.get(hello.authTypeLength, function(authType) { serv.pack_stream.get(hello.authDataLength, function(authData) { serv.byteOrder = hello.byteOrder; serv.protocolMajor = hello.protocolMajor; serv.protocolMinor = hello.protocolMinor; serv.checkAuth(authType.toString('ascii'), authData); }); }); } ); } XServerClientConnection.prototype.checkAuth = function(authType, authData) { var serv = this; // ignore check for now; // protocol page 140: add code for reject & ask additional info console.log('check auth'); console.log([authType, authData.toString()]); // auth ok: reply with list of screens, visuals, root window info etc var stream = serv.pack_stream; /* xquartz exemple reply { major: 11, minor: 0, xlen: 537, (bytes in whole header) release: 11300000, resource_base: 6291456, resource_mask: 2097151, motion_buffer_size: 256, vlen: 20, max_request_length: 65535, screen_num: 1, format_num: 7, image_byte_order: 0, bitmap_bit_order: 0, bitmap_scanline_unit: 32, bitmap_scanline_pad: 32, min_keycode: 8, max_keycode: 255 } per screen: screen: { root: 226, default_colormap: 33, white_pixel: 16777215, black_pixel: 0, input_masks: 1703936, pixel_width: 3286, pixel_height: 1058, mm_width: 866, mm_height: 277, min_installed_maps: 1, max_installed_maps: 1, root_visual: 34, root_depth: 24, backing_stores: 0, num_depths: 7 } 17 'L root',¬ 18 'L default_colormap',¬ 19 'L white_pixel',¬ 20 'L black_pixel',¬ 21 'L input_masks',¬ 22 'S pixel_width',¬ 23 'S pixel_height',¬ 24 'S mm_width',¬ 25 'S mm_height',¬ 26 'S min_installed_maps',¬ 27 'S max_installed_maps',¬ 28 'L root_visual',¬ 29 'C root_depth',¬ 30 'C backing_stores',¬ 31 'C root_depth',¬ 32 'C num_depths'¬ per depth: depth: [ 24, 80 ] (depth, num visuals) per visual: visual { vid: 146, class: 4, bits_per_rgb: 8, map_ent: 256, red_mask: 16711680, green_mask: 65280, blue_mask: 255 } */ //stream.pack('') // [2, reason, //serv.pack_stream.unpack('C', function(isShared) { // console.log([isShared]); // serv.writeServerInit(); //}); // var hello = Require('fs').readFileSync('hello1.bin'); stream.pack('CxSSSa', [1, 11, 0, hello.length/4, hello]); stream.flush(); serv.expectMessage(); } XServerClientConnection.prototype.expectMessage = function() { var serv = this; console.log('expecting messages'); serv.pack_stream.unpack('CCS', function(header) { serv.sequence++; console.log('Request:', header[0]); console.log('Extra:', header[1]); console.log('length:', header[2]); serv.pack_stream.get((header[2]-1)*4, function(reqBody) { console.log('BODY:', reqBody, reqBody.toString()); if (header[0] == 98) { serv.pack_stream.pack('CCSLCCCCLLLLL', [1, 0, serv.sequence, 0, 1, 134, 0, 0, 0, 0, 0, 0, 0, 0]); serv.pack_stream.flush(); } else if (header[0] == 134) { console.log('ENABLE BIG REQ'); serv.pack_stream.pack('CCSLLLLLLLL', [1, 0, serv.sequence, 0, 10000000, 0, 0, 0, 0, 0, 0 ]); serv.pack_stream.flush(); } serv.expectMessage(); }); }); } module.exports.createServer = function(options, onconnect) { if (typeof(options) === 'function') { onconnect = options; options = {}; } var s = net.createServer(); var serv = new XServer(s, options); serv.on('connect', onconnect); return s; } //module.exports.createServer(6002) ; //function(client) { //});