Conflicts:
	lib/x11/corereqs.js
This commit is contained in:
sidorares 2011-07-18 10:54:28 +10:00
commit bf81e3170e
11 changed files with 147 additions and 103 deletions

View file

@ -1,3 +1,5 @@
var xutil = require('./xutil');
var valueMask = { var valueMask = {
CreateWindow: { CreateWindow: {
backgroundPixmap: 0x00000001, backgroundPixmap: 0x00000001,
@ -65,7 +67,7 @@ function packValueMask(reqname, values)
{ {
var valueBit = reqValueMask[v]; var valueBit = reqValueMask[v];
if (!valueBit) if (!valueBit)
throw new Error('CreateWindow: incorrect value param ' + v); throw new Error(reqname + ': incorrect value param ' + v);
masksList.push(valueBit); masksList.push(valueBit);
bitmask |= valueBit; bitmask |= valueBit;
} }
@ -105,7 +107,10 @@ module.exports = {
CreateWindow: [ CreateWindow: [
// create request packet - function OR format string // create request packet - function OR format string
function(id, parentId, x, y, width, height, borderWidth, _class, visual, values) { function(id, parentId, x, y, width, height, borderWidth, _class, visual, values) {
<<<<<<< HEAD
console.log('CreateWindow called', id); console.log('CreateWindow called', id);
=======
>>>>>>> 3d3658d0b81642440a915e706d2c28b412c1a383
// TODO: ??? there is depth field in xproto, but xlib just sets it to zero // TODO: ??? there is depth field in xproto, but xlib just sets it to zero
var depth = 0; var depth = 0;
@ -179,5 +184,25 @@ module.exports = {
} }
return [format, args]; return [format, args];
} }
],
// opcode 16
InternAtom: [
function (returnOnlyIfExist, value)
{
var padded = xutil.padded_string(value);
return ['CCSSa', [16, returnOnlyIfExist ? 1 : 0, 2+padded.length/4, value.length, value] ];
},
function(stream, buf) {
console.error('Intern Atom reply !!!!');
}
],
GetAtomName: [
[ 'CxSL', [17, 2] ],
function(stream, buf) {
console.error('Intern GetAtomName reply !!!!');
}
] ]
} }

View file

@ -7,7 +7,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 coreRequestsTemplate = require('./corereqs');
//var hexy = require('./hexy').hexy; var hexy = require('./hexy').hexy;
var Buffer = require('buffer').Buffer; var Buffer = require('buffer').Buffer;
// add 'unpack' method for buffer // add 'unpack' method for buffer
@ -57,6 +57,8 @@ function XClient(stream)
this.importRequestsFromTemplates(this, coreRequests); this.importRequestsFromTemplates(this, coreRequests);
this.startHandshake(); this.startHandshake();
this.event_consumers = {}; // maps window id to eventemitter
// import available extentions // import available extentions
// TODO: lazy import on first call? // TODO: lazy import on first call?
/* /*
@ -82,7 +84,11 @@ XClient.prototype.importRequestsFromTemplates = function(target, reqs)
// r is request name // r is request name
target[r] = (function(reqName) { target[r] = (function(reqName) {
var reqFunc = function req_proxy() { var reqFunc = function req_proxy() {
client.seq_num++; // TODO: handle overflow (seq should be last 15 (?) bits of the number
// is it fast?
var args = Array.prototype.slice.call(req_proxy.arguments); var args = Array.prototype.slice.call(req_proxy.arguments);
// TODO: setup last argument to be reply/error callback // TODO: setup last argument to be reply/error callback
// var callback = args.length > 0 ? null : args[args.length - 1]; // var callback = args.length > 0 ? null : args[args.length - 1];
@ -101,6 +107,7 @@ XClient.prototype.importRequestsFromTemplates = function(target, reqs)
reqPack = reqTemplate.apply(this, req_proxy.arguments); reqPack = reqTemplate.apply(this, req_proxy.arguments);
var format = reqPack[0]; var format = reqPack[0];
var requestArguments = reqPack[1]; var requestArguments = reqPack[1];
console.error([format, requestArguments]);
client.pack_stream.pack(format, requestArguments); client.pack_stream.pack(format, requestArguments);
client.pack_stream.flush(); client.pack_stream.flush();
} else if (templateType == 'Array'){ } else if (templateType == 'Array'){
@ -108,6 +115,7 @@ XClient.prototype.importRequestsFromTemplates = function(target, reqs)
var requestArguments = reqTemplate[1]; var requestArguments = reqTemplate[1];
for (a in args) for (a in args)
requestArguments.push(args[a]); requestArguments.push(args[a]);
console.error([format, requestArguments]);
client.pack_stream.pack(format, requestArguments); client.pack_stream.pack(format, requestArguments);
client.pack_stream.flush(); client.pack_stream.flush();
} else { } else {
@ -127,6 +135,30 @@ XClient.prototype.AllocID = function()
return (this.display.rsrc_id << this.display.rsrc_shift) + this.display.resource_base; return (this.display.rsrc_id << this.display.rsrc_shift) + this.display.resource_base;
} }
XClient.prototype.unpackEvent = function(type, seq, extra, raw)
{
var event = {}; // TODO: constructor & base functions
event.type = type;
event.seq = seq;
if (type == 6) { // motion event
var values = raw.unpack('LLLSSSSSC'); //TODO: should be LLLLsssssSC
//event.raw = values;
// TODO: use unpackTo???
event.time = extra;
event.root = values[0];
event.wid = values[1];
event.child = values[2];
event.rootx = values[3];
event.rooty = values[4];
event.x = values[5];
event.y = values[6];
event.buttons = values[7];
event.sameScreen = values[8];
}
return event;
}
XClient.prototype.expectReplyHeader = function() XClient.prototype.expectReplyHeader = function()
{ {
var client = this; var client = this;
@ -147,18 +179,30 @@ XClient.prototype.expectReplyHeader = function()
} else if (type > 1) } else if (type > 1)
{ {
client.pack_stream.get(24, function(buf) { client.pack_stream.get(24, function(buf) {
// TODO: dispatch, use sequence number var extra = res[3];
console.error('event!!!! ' + type); var ev = client.unpackEvent(type, seq_num, extra, buf);
client.emit('event', ev);
var ee = client.event_consumers[ev.wid];
if (ee) {
ee.emit('event', ev);
}
client.expectReplyHeader(); client.expectReplyHeader();
} ); } );
return; return;
} }
var opt_data = res[1]; var opt_data = res[1];
var length_total = res[3]; // in 4-bytes units, _including_ this header var length_total = res[3]; // in 4-bytes units, _including_ this header
var bodylength = (length_total-2)*4; // length of the data in bytes var bodylength = 24 + length_total*4; // 24 is rest if 32-bytes header
console.log(res);
console.log('reply of length ' + bodylength + ' should follow');
client.pack_stream.get( bodylength, function( data ) { client.pack_stream.get( bodylength, function( data ) {
var handler = this.replyHandlers[seq_num];
// TODO: decode and dispatch, use sequence number // TODO: decode and dispatch, use sequence number
console.error('reply data!!!'); console.error('reply data!!!!!!!!!!');
console.error(hexy(data, { prefix: 'InternAtom reply' }));
// wait for new packet from server // wait for new packet from server
client.expectReplyHeader(); client.expectReplyHeader();

View file

@ -7,15 +7,19 @@ function padded_length(len)
return padded_length; return padded_length;
} }
// TODO: make it return buffer?
// str += is slow
function padded_string(str) function padded_string(str)
{ {
if (str.length == 0); if (str.length == 0)
return ''; return '';
var len = padded_length(str.len); var pad = padded_length(str.length) - str.length;
var res = str; var res = str;
for (var i=0; i < len; ++i) for (var i=0; i < pad; ++i)
res += String.fromCharCode(0); res += String.fromCharCode(0);
return res;
} }
module.exports.padded_length = padded_length; module.exports.padded_length = padded_length;

14
test/atoms.js Normal file
View file

@ -0,0 +1,14 @@
var x11 = require('../lib/x11');
var xclient = x11.createClient();
xclient.on('connect', function(display) {
var X = this;
var hello = 'Hello, node.js';
X.InternAtom(false, hello, function(atomId) {
console.log(atomId);
});
X.InternAtom(true, 'test', function(atomId) {
console.log(atomId);
});
});

3
test/c-tests/Makefile Normal file
View file

@ -0,0 +1,3 @@
LDFLAGS=-lX11
simplewin: simplewin.o

BIN
test/c-tests/simplewin Executable file

Binary file not shown.

42
test/c-tests/simplewin.c Normal file
View file

@ -0,0 +1,42 @@
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
Display *d;
Window w, w1;
XEvent e;
char *msg = "Hello, world!";
int s;
d = XOpenDisplay(NULL);
if (d == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
s = DefaultScreen(d);
w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 100, 100, 1,
BlackPixel(d, s), WhitePixel(d, s));
w1 = XCreateSimpleWindow(d, RootWindow(d, s), 50, 50, 50, 50, 1,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w, ExposureMask | KeyPressMask);
XSelectInput(d, w1, ExposureMask);
XMapWindow(d, w);
XMapWindow(d, w1);
while (1) {
XNextEvent(d, &e);
if (e.type == Expose) {
XFillRectangle(e.xany.display, e.xany.window, DefaultGC(d, s), 20, 20, 10, 10);
XDrawString(e.xany.display, e.xany.window, DefaultGC(d, s), 10, 50, msg, strlen(msg));
}
if (e.type == KeyPress)
break;
}
XCloseDisplay(d);
return 0;
}

BIN
test/c-tests/simplewin.o Normal file

Binary file not shown.

View file

@ -9,4 +9,9 @@ xclient.on('connect', function(display) {
X.CreateWindow(wid, root, 10, 10, 400, 300, 1, 1, 0, { backgroundPixel: 0, eventMask: 0x00000040 }); X.CreateWindow(wid, root, 10, 10, 400, 300, 1, 1, 0, { backgroundPixel: 0, eventMask: 0x00000040 });
X.MapWindow(wid); X.MapWindow(wid);
var wid1 = X.AllocID();
X.CreateWindow(wid1, root, 10, 10, 40, 30, 1, 1, 0, { backgroundPixel: xclient.display.screen[0].white_pixel, eventMask: 0x00000040 });
X.MapWindow(wid1);
}); });

View file

@ -1,23 +0,0 @@
var x11 = require('../lib/x11');
var Window = require('./wndwrap');
var width = 700;
var height = 500;
var xclient = x11.createClient();
xclient.on('connect', function(display) {
var white = xclient.display.screen[0].white_pixel;
var black = xclient.display.screen[0].black_pixel;
var mainwnd = new Window(xclient, 0, 0, width, height, black);
for (var x = 0; x < width; x += 20) {
for (var y = 0; y < width; y += 20) {
// TODO: wnd.createChild() ?
var ch = new Window(xclient, x + 1, y + 1, 18, 18, 0, white);
ch.on('mousemove', function(ev) {
ch.unmap();
setTimeout( function() { ch.map() }, 500);
});
}
}
});

View file

@ -1,70 +0,0 @@
var EventEmitter = require('events').EventEmitter;
var util = require('util'); // util.inherits
function Window(parent, x, y, w, h, bg)
{
if (parent.constructor && parent.constructor.name == 'XClient')
{
this.xclient = parent;
if (!this.xclient.rootWindow)
{
// quick hack
var rootWnd = {
id: this.xclient.display.screen[0].root,
xclient: this.xclient
};
rootWnd.parent = null;
this.parent = this.xclient.rootWnd;
this.xclient.rootWindow = rootWnd;
}
this.parent = this.xclient.rootWindow;
} else {
this.parent = parent;
this.xclient = parent.xclient;
}
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.bg = bg;
this.id = this.xclient.AllocID();
this.xclient.CreateWindow(
this.id, this.parent.id, this.x, this.y, this.w, this.h, 1, 1, 0, { backgroundPixel: this.bg, eventMask: 0x00000040 }
);
this.map();
// very ineffitient this way!!!
var wnd = this;
this.xclient.on('event', function(ev)
{
if (ev.type == 6 && ev.wid == wnd.id)
{
wnd.emit('mousemove', ev);
}
});
/*
// TODO: right way to handle events
// need to modify xcore to dispatch events to event_consumers
//
eventType2eventName = {
6: 'mousemove'
};
this.xclient.event_consumers[wnd.id] = function( ev )
{
wnd.emit(eventType2eventName, ev); // convert to mousemove? (ev already event-spacific)
};
*/
}
util.inherits(Window, EventEmitter);
Window.prototype.map = function() {
this.xclient.MapWindow(this.id);
}
Window.prototype.unmap = function() {
this.xclient.UnapWindow(this.id);
}
module.exports = Window;