Mon 21 Jul 22:43:21 CEST 2025
This commit is contained in:
parent
f6f81aceee
commit
93e74774fd
231
js/x11/core/handshake.js
Normal file
231
js/x11/core/handshake.js
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
var getAuthString = Require('x11/core/auth');
|
||||||
|
var xutil = Require('x11/core/xutil');
|
||||||
|
|
||||||
|
function readVisuals(bl, visuals, n_visuals, cb)
|
||||||
|
{
|
||||||
|
if (n_visuals == 0)
|
||||||
|
{
|
||||||
|
cb();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var visual = {};
|
||||||
|
bl.unpackTo( visual,
|
||||||
|
[
|
||||||
|
'L vid',
|
||||||
|
'C class',
|
||||||
|
'C bits_per_rgb',
|
||||||
|
'S map_ent',
|
||||||
|
'L red_mask',
|
||||||
|
'L green_mask',
|
||||||
|
'L blue_mask',
|
||||||
|
'xxxx'
|
||||||
|
],
|
||||||
|
function() {
|
||||||
|
var vid = visual.vid;
|
||||||
|
// delete visual.vid;
|
||||||
|
visuals[visual.vid] = visual;
|
||||||
|
if (Object.keys(visuals).length == n_visuals)
|
||||||
|
cb()
|
||||||
|
else
|
||||||
|
readVisuals(bl, visuals, n_visuals, cb);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
var scr = {};
|
||||||
|
bl.unpackTo( scr,
|
||||||
|
[
|
||||||
|
'L root',
|
||||||
|
'L default_colormap',
|
||||||
|
'L white_pixel',
|
||||||
|
'L black_pixel',
|
||||||
|
'L input_masks',
|
||||||
|
'S pixel_width',
|
||||||
|
'S pixel_height',
|
||||||
|
'S mm_width',
|
||||||
|
'S mm_height',
|
||||||
|
'S min_installed_maps',
|
||||||
|
'S max_installed_maps',
|
||||||
|
'L root_visual',
|
||||||
|
'C root_depth',
|
||||||
|
'C backing_stores',
|
||||||
|
'C root_depth',
|
||||||
|
'C num_depths'
|
||||||
|
],
|
||||||
|
function () {
|
||||||
|
var depths = {};
|
||||||
|
readDepths(bl, display, depths, scr.num_depths, function() {
|
||||||
|
|
||||||
|
scr.depths = depths;
|
||||||
|
delete scr.num_depths;
|
||||||
|
display.screen.push(scr);
|
||||||
|
|
||||||
|
if (display.screen.length == display.screen_num)
|
||||||
|
{
|
||||||
|
delete display.screen_num;
|
||||||
|
cbDisplayReady(null, display);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
readScreens(bl, display, cbDisplayReady);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function readServerHello(bl, cb)
|
||||||
|
{
|
||||||
|
|
||||||
|
bl.unpack('C', function(res) {
|
||||||
|
|
||||||
|
if (res[0] == 0)
|
||||||
|
{
|
||||||
|
// conection time error
|
||||||
|
// unpack error
|
||||||
|
bl.unpack('Cxxxxxx', function (rlen) {
|
||||||
|
bl.get(rlen[0], function (reason) {
|
||||||
|
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: api to close source stream via attached unpackstream
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var display = {};
|
||||||
|
bl.unpackTo(
|
||||||
|
display,
|
||||||
|
[
|
||||||
|
'x',
|
||||||
|
'S major',
|
||||||
|
'S minor',
|
||||||
|
'S xlen',
|
||||||
|
'L release',
|
||||||
|
'L resource_base',
|
||||||
|
'L resource_mask',
|
||||||
|
'L motion_buffer_size',
|
||||||
|
'S vlen',
|
||||||
|
'S max_request_length',
|
||||||
|
'C screen_num',
|
||||||
|
'C format_num',
|
||||||
|
'C image_byte_order',
|
||||||
|
'C bitmap_bit_order',
|
||||||
|
'C bitmap_scanline_unit',
|
||||||
|
'C bitmap_scanline_pad',
|
||||||
|
'C min_keycode',
|
||||||
|
'C max_keycode',
|
||||||
|
'xxxx'
|
||||||
|
],
|
||||||
|
|
||||||
|
function()
|
||||||
|
{
|
||||||
|
var pvlen = xutil.padded_length(display.vlen);
|
||||||
|
|
||||||
|
// setup data to generate resource id
|
||||||
|
// TODO: cleaunup code here
|
||||||
|
var mask = display.resource_mask;
|
||||||
|
display.rsrc_shift = 0;
|
||||||
|
while (!( (mask >> display.rsrc_shift) & 1) )
|
||||||
|
display.rsrc_shift++;
|
||||||
|
display.rsrc_id = 0;
|
||||||
|
|
||||||
|
bl.get(pvlen, function(vendor)
|
||||||
|
{
|
||||||
|
display.vendor = vendor.toString().substr(0, display.vlen); // utf8 by default?
|
||||||
|
|
||||||
|
display.format = {};
|
||||||
|
for (var i=0; i < display.format_num; ++i)
|
||||||
|
{
|
||||||
|
bl.unpack('CCCxxxxx', function(fmt) {
|
||||||
|
var depth = fmt[0];
|
||||||
|
display.format[depth] = {};
|
||||||
|
display.format[depth].bits_per_pixel = fmt[1];
|
||||||
|
display.format[depth].scanline_pad = fmt[2];
|
||||||
|
if (Object.keys(display.format).length == display.format_num)
|
||||||
|
{
|
||||||
|
delete display.format_num;
|
||||||
|
display.screen = [];
|
||||||
|
readScreens(bl, display, cb);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getByteOrder() {
|
||||||
|
var isLittleEndian = ((new Uint32Array((new Uint8Array([1,2,3,4])).buffer))[0] === 0x04030201);
|
||||||
|
if (isLittleEndian) {
|
||||||
|
return 'l'.charCodeAt(0);
|
||||||
|
} else {
|
||||||
|
return 'B'.charCodeAt(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeClientHello(stream, displayNum, authHost, authFamily)
|
||||||
|
{
|
||||||
|
getAuthString( displayNum, authHost, authFamily, function( err, cookie ) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
var byte_order = getByteOrder();
|
||||||
|
var protocol_major = 11; // TODO: config? env?
|
||||||
|
var protocol_minor = 0;
|
||||||
|
stream.pack(
|
||||||
|
'CxSSSSxxpp',
|
||||||
|
[
|
||||||
|
byte_order,
|
||||||
|
protocol_major,
|
||||||
|
protocol_minor,
|
||||||
|
cookie.authName.length,
|
||||||
|
cookie.authData.length,
|
||||||
|
cookie.authName,
|
||||||
|
cookie.authData
|
||||||
|
]
|
||||||
|
);
|
||||||
|
stream.flush();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.readServerHello = readServerHello;
|
||||||
|
module.exports.writeClientHello = writeClientHello;
|
Loading…
Reference in New Issue
Block a user