201 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
var x11 = require('../../lib');
 | 
						|
var Exposure = x11.eventMask.Exposure;
 | 
						|
var PointerMotion = x11.eventMask.PointerMotion;
 | 
						|
var ButtonPress = x11.eventMask.ButtonPress;
 | 
						|
var ButtonRelease = x11.eventMask.ButtonRelease;
 | 
						|
var SubstructureNotify = x11.eventMask.SubstructureNotify;
 | 
						|
var StructureNotify = x11.eventMask.StructureNotify;
 | 
						|
 | 
						|
var EventEmitter = require('events').EventEmitter;
 | 
						|
var util = require('util'); // util.inherits
 | 
						|
 | 
						|
function GraphicContext(win)
 | 
						|
{
 | 
						|
    this.win = win;
 | 
						|
    this.xclient = win.xclient;
 | 
						|
    this.id = this.xclient.AllocID();
 | 
						|
    var screen = this.xclient.display.screen[0];
 | 
						|
    //win.xclient.CreateGC(this.id, win.id, { foreground: screen.black_pixel, background: screen.white_pixel});
 | 
						|
    this.xclient.CreateGC(this.id, win.id, { foreground: screen.white_pixel, background: screen.black_pixel});
 | 
						|
}
 | 
						|
 | 
						|
GraphicContext.prototype.polyLine = function(points)
 | 
						|
{
 | 
						|
    this.xclient.PolyLine(0, this.win.id, this.id, points);    
 | 
						|
}
 | 
						|
 | 
						|
GraphicContext.prototype.noop = function()
 | 
						|
{
 | 
						|
    //testing triggering gc creation
 | 
						|
}
 | 
						|
 | 
						|
GraphicContext.prototype.rectangles = function(x, y, xyWHpoints)
 | 
						|
{
 | 
						|
    this.xclient.PolyFillRectangle(this.win.id, this.id, xyWHpoints);
 | 
						|
}
 | 
						|
 | 
						|
GraphicContext.prototype.text = function(x, y, text)
 | 
						|
{
 | 
						|
    this.xclient.PolyText8(this.win.id, this.id, x, y, [text]);    
 | 
						|
}
 | 
						|
 | 
						|
GraphicContext.prototype.polyLine = function(points, opts)
 | 
						|
{
 | 
						|
    var coordinateMode = 0;
 | 
						|
    if (opts && opts.coordinateMode === 'previous')
 | 
						|
        coordinateMode = 1;                         
 | 
						|
    this.xclient.PolyLine(coordinateMode, this.win.id, this.id, points);
 | 
						|
}
 | 
						|
 | 
						|
GraphicContext.prototype.points = function(points, opts)
 | 
						|
{
 | 
						|
    var coordinateMode = 0;
 | 
						|
    if (opts && opts.coordinateMode === 'previous')
 | 
						|
        coordinateMode = 1;                         
 | 
						|
    this.xclient.PolyPoint(coordinateMode, this.win.id, this.id, points);
 | 
						|
}
 | 
						|
 | 
						|
GraphicContext.prototype.copy = function(srcDrawable, srcX, srcY, dstX, dstY, width, height)
 | 
						|
{
 | 
						|
    // CopyArea: srcDrawable, dstDrawable, gc, srcX, srcY, dstX, dstY, width, height
 | 
						|
    this.xclient.CopyArea(srcDrawable.id, this.win.id, this.id, srcX, srcY, dstX, dstY, width, height);
 | 
						|
}
 | 
						|
 | 
						|
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.black = this.xclient.display.screen[0].black_pixel;
 | 
						|
    this.white = this.xclient.display.screen[0].white_pixel;
 | 
						|
    this.id = this.xclient.AllocID();
 | 
						|
 | 
						|
    if (!bg)
 | 
						|
       bg = this.white;
 | 
						|
 | 
						|
    var borderWidth = 1;
 | 
						|
    var _class = 1; // InputOutput
 | 
						|
    var visual = 0; // CopyFromParent
 | 
						|
    var depth = 0;
 | 
						|
    this.xclient.CreateWindow(
 | 
						|
        this.id, this.parent.id, this.x, this.y, this.w, this.h, 
 | 
						|
        borderWidth, depth, _class, visual, 
 | 
						|
        { 
 | 
						|
            backgroundPixel: bg, 
 | 
						|
            eventMask: Exposure|PointerMotion|ButtonPress|ButtonRelease|SubstructureNotify|StructureNotify
 | 
						|
        }
 | 
						|
    );
 | 
						|
 | 
						|
    //this.map();
 | 
						|
    var wnd = this;
 | 
						|
    eventType2eventName = {
 | 
						|
        4: 'mousedown',
 | 
						|
        5: 'mouseup',
 | 
						|
        6: 'mousemove',        
 | 
						|
       12: 'expose',       
 | 
						|
       16: 'create',
 | 
						|
       19: 'map'
 | 
						|
    };
 | 
						|
 | 
						|
    var ee = new EventEmitter();
 | 
						|
    this.xclient.event_consumers[wnd.id] = ee;
 | 
						|
    // TODO: do we need to have wnd as EventEmitter AND EventEmitter stored in event_consumers ?
 | 
						|
    ee.on('event', function( ev )
 | 
						|
    {
 | 
						|
        if (ev.type == 12) //Expose
 | 
						|
            ev.gc = wnd.gc;
 | 
						|
        wnd.emit(eventType2eventName[ev.type], ev); // convert to mousemove? (ev is already event-spacific)               
 | 
						|
    });    
 | 
						|
    // TODO: track delete events and remove wmd from consumers list
 | 
						|
 | 
						|
    this.__defineSetter__('title', function(title) {
 | 
						|
        this._title = title;
 | 
						|
        this.xclient.ChangeProperty(0, this.id, this.xclient.atoms.WM_NAME, this.xclient.atoms.STRING, 8, title);
 | 
						|
    });
 | 
						|
 | 
						|
    this.__defineGetter__('title', function() {
 | 
						|
        return this._title;
 | 
						|
    });
 | 
						|
   
 | 
						|
    this.__defineGetter__('gc', function()
 | 
						|
    {
 | 
						|
       if (!this._gc)
 | 
						|
       {
 | 
						|
           this._gc = new GraphicContext(this);
 | 
						|
       } 
 | 
						|
       return this._gc;
 | 
						|
    });
 | 
						|
 | 
						|
}
 | 
						|
util.inherits(Window, EventEmitter);
 | 
						|
 | 
						|
Window.prototype.map = function() {
 | 
						|
    this.xclient.MapWindow(this.id);
 | 
						|
    return this;
 | 
						|
}
 | 
						|
 | 
						|
Window.prototype.unmap = function() {
 | 
						|
    this.xclient.UnmapWindow(this.id);
 | 
						|
    return this;
 | 
						|
}
 | 
						|
 | 
						|
Window.prototype.handle = function(handlers) {
 | 
						|
    // TODO: compare event mask with events names and issue 
 | 
						|
    // one ChangeWindowAttributes request adding missing events
 | 
						|
    for (var eventName in handlers) {
 | 
						|
        this.on(eventName, handlers[eventName]);
 | 
						|
    }
 | 
						|
    return this;
 | 
						|
}
 | 
						|
 | 
						|
Window.prototype.getProperty = function(name, cb) {
 | 
						|
    this.xclient.InternAtom(true, nam, function(nameAtom) {
 | 
						|
        this.xclient.GetProperty(0, this.id, nameAtom, 0, 1000000000, function(prop) {
 | 
						|
            cb(prop);
 | 
						|
        });
 | 
						|
    });
 | 
						|
    return this;
 | 
						|
}
 | 
						|
 | 
						|
Window.prototype.createPixmap = function(width, height)
 | 
						|
{
 | 
						|
    var pid = this.xclient.AllocID();
 | 
						|
    //  function(depth, pid, drawable, width, height) {
 | 
						|
    this.xclient.CreatePixmap( this.xclient.display.screen[0].root_depth, pid, this.id, width, height);
 | 
						|
    var pixmap = {};
 | 
						|
    pixmap.id = pid;
 | 
						|
    pixmap.__defineGetter__('gc', function()
 | 
						|
    {
 | 
						|
       if (!this._gc)
 | 
						|
       {
 | 
						|
           this._gc = new GraphicContext(this);
 | 
						|
       } 
 | 
						|
       return this._gc;
 | 
						|
    });
 | 
						|
    pixmap.xclient = this.xclient;
 | 
						|
    return pixmap;
 | 
						|
}
 | 
						|
 | 
						|
module.exports = Window;
 |