diff --git a/js/x11/core/ext/shape.js b/js/x11/core/ext/shape.js new file mode 100644 index 0000000..17aefcc --- /dev/null +++ b/js/x11/core/ext/shape.js @@ -0,0 +1,142 @@ +// http://www.x.org/releases/X11R7.6/doc/xextproto/shape.pdf + +var x11 = Require('x11/core/x11'); +// TODO: move to templates + +exports.requireExt = function(display, callback) +{ + function captureStack() + { + var err = new Error; + //err.name = reqName; + Error.captureStackTrace(err, arguments.callee); + display.client.seq2stack[display.client.seq_num] = err.stack; + } + + var X = display.client; + X.QueryExtension('SHAPE', function(err, ext) { + + if (!ext.present) + return callback(new Error('extension not available')); + + ext.Kind = { + Bounding: 0, + Clip: 1, + Input: 2 + }; + + ext.Op = { + Set: 0, + Union: 1, + Intersect: 2, + Subtract: 3, + Invert: 4 + }; + + ext.Ordering = { + Unsorted: 0, + YSorted: 1, + YXSorted: 2, + YXBanded: 3 + }; + + ext.QueryVersion = function(cb) + { + X.seq_num++; +// captureStack(); + X.pack_stream.pack('CCSLL', [ext.majorOpcode, 0, 1]); + X.replies[X.seq_num] = [ + function(buf, opt) { + var res = buf.unpack('SS'); + return res; + }, + cb + ]; + X.pack_stream.flush(); + } + + // Accepts rectangles as [[x, y, width, height]] + ext.Rectangles = function( op, kind, window, x, y, rectangles, ordering /* = Ordering.Unsorted */ ) + { + if (ordering === undefined) + ordering = ext.Ordering.Unsorted; + + var length = 4 + rectangles.length * 2; + + X.seq_num++; +// captureStack(); + X.pack_stream.pack('CCSCCCxLss', [ext.majorOpcode, 1, length, op, kind, ordering, window, x, y]); + for (var i = 0; i < rectangles.length; ++i) { + var r = rectangles[i]; + X.pack_stream.pack('ssSS', r); + } + X.pack_stream.flush(); + } + + ext.Mask = function( op, kind, window, x, y, bitmap ) + { + X.seq_num++; +// captureStack(); + X.pack_stream.pack('CCSCCxxLssL', [ext.majorOpcode, 2, 5, op, kind, window, x, y, bitmap]); + X.pack_stream.flush(); + } + + ext.SelectInput = function( window, enable ) + { + X.seq_num++; +// captureStack(); + X.pack_stream.pack('CCSLCxxx', [ext.majorOpcode, 6, 3, window, enable ]); + X.pack_stream.flush(); + } + + ext.InputSelected = function( window, cb ) + { + X.seq_num++; +// captureStack(); + X.pack_stream.pack('CCSL', [ext.majorOpcode, 7, 2, window ]); + X.replies[X.seq_num] = [ + function(buf, opt) { + return opt; + }, + cb + ]; + X.pack_stream.flush(); + } + + callback(null, ext); + + /* + ext.QueryVersion(function(err, version) { + ext.major = version[0]; + ext.minor = version[1]; + callback(null, ext); + }); + */ + + ext.events = { + ShapeNotify: 0 + } + + X.eventParsers[ext.firstEvent + ext.events.ShapeNotify] = function(type, seq, extra, code, raw) + { + var event = {}; + event.type = type; + event.kind = code; + event.seq = seq; + + event.window = extra; + + var values = raw.unpack('ssSSLC'); + + event.x = values[0]; + event.y = values[1]; + event.width = values[2]; + event.height = values[3]; + event.time = values[4]; + event.shaped = values[5]; + event.name = 'ShapeNotify'; + + return event; + }; + }); +}