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;
							 |