diff --git a/lib/x11/corereqs.js b/lib/x11/corereqs.js index e0a08a6..bcdae15 100644 --- a/lib/x11/corereqs.js +++ b/lib/x11/corereqs.js @@ -1,24 +1,82 @@ var valueMask = { - backgroundPixmap: 0x00000001, - backgroundPixel : 0x00000002, - borderPixmap : 0x00000004, - borderPixel : 0x00000008, - bitGrawity : 0x00000010, - winGravity : 0x00000020, - backingStore : 0x00000040, - backingPlanes : 0x00000080, - backingPixel : 0x00000100, - overrideRedirect: 0x00000200, - saveUnder : 0x00000400, - eventMask : 0x00000800, - doNotPropagateMask: 0x00001000, - colormap : 0x00002000, - cursor : 0x00004000 + CreateWindow: { + backgroundPixmap: 0x00000001, + backgroundPixel : 0x00000002, + borderPixmap : 0x00000004, + borderPixel : 0x00000008, + bitGrawity : 0x00000010, + winGravity : 0x00000020, + backingStore : 0x00000040, + backingPlanes : 0x00000080, + backingPixel : 0x00000100, + overrideRedirect: 0x00000200, + saveUnder : 0x00000400, + eventMask : 0x00000800, + doNotPropagateMask: 0x00001000, + colormap : 0x00002000, + cursor : 0x00004000 + }, + CreateGC: { + 'function' : 0x00000001, // TODO: alias? _function? + planeMask : 0x00000002, + foreground : 0x00000004, + background : 0x00000008, + lineWidth : 0x00000010, + lineStyle : 0x00000020, + capStyle : 0x00000040, + joinStyle : 0x00000080, + fillStyle : 0x00000100, + fillRule : 0x00000200, + tile : 0x00000400, + stipple : 0x00000800, + tileStippleXOrigin: 0x00001000, + tileStippleYOrigin: 0x00002000, + font : 0x00004000, + subwindowMode: 0x00008000, + graphicsExposures: 0x00010000, + clipXOrigin : 0x00020000, + clipYOrigin : 0x00040000, + clipMask : 0x00080000, + dashOffset : 0x00100000, + dashes : 0x00200000, + arcMode : 0x00400000 + } }; -var valueMaskNames = {}; -for (var m in valueMask) { - valueMaskNames[valueMask[m]] = m; +var valueMaskName = {}; +for (var req in valueMask) { + var masks = valueMask[req]; + var names = valueMaskName[req] = {}; + for (var m in masks) + names[masks[m]] = m; +} + +function packValueMask(reqname, values) +{ + var bitmask = 0; + var masksList = []; + var reqValueMask = valueMask[reqname]; + var reqValueMaskName = valueMaskName[reqname]; + + if (!reqValueMask) + throw new Error(reqname + ': no value mask description'); + + for (var v in values) + { + var valueBit = reqValueMask[v]; + if (!valueBit) + throw new Error('CreateWindow: incorrect value param ' + v); + masksList.push(valueBit); + bitmask |= valueBit; + } + masksList.sort(); + var args = []; + for (m in masksList) + { + valueName = reqValueMaskName[masksList[m]]; + args.push( values[valueName] ); + } + return [bitmask, args] } /* @@ -51,7 +109,7 @@ module.exports = { // TODO: ??? there is depth field in xproto, but xlib just sets it to zero var depth = 0; - var packetLength = 8 + Object.keys(values).length; + var packetLength = 8 + (values ? Object.keys(values).length : 0); // TODO: should be CCSLLssSSSSLL - x,y are signed var format = 'CCSLLSSSSSSLL'; @@ -65,10 +123,12 @@ module.exports = { // bitmask (bytes #24 to #31 in the packet) - 32 bit indicating what adittional arguments we supply // values list (bytes #32 .. #32+4*num_values) in order of corresponding bits + + // TODO: replace with packValueMask var masksList = []; for (var v in values) { - var valueBit = valueMask[v]; + var valueBit = valueMask['CreateWindow'][v]; if (!valueBit) { throw new Error('CreateWindow: incorrect value param ' + v); @@ -85,7 +145,7 @@ module.exports = { // TODO: maybe it's better just to scan all 32 bits anstead of sorting parameters we are actually have? for (m in masksList) { - valueName = valueMaskNames[masksList[m]]; + valueName = valueMaskName['CreateWindow'][masksList[m]]; args.push( values[valueName] ); } return [format, args]; @@ -100,5 +160,23 @@ module.exports = { UnmapWindow: [ [ 'CxSL', [10, 2] ] - ] + ], + + // opcode 55 + CreateGC: [ + function(cid, drawable, values) { + var format = 'CxSLL'; + var packetLength = 8 + (values ? Object.keys(values).length : 0); + var args = [55, packetLength, cid, drawable]; + var vals = packValueMask('CreateGC', values); + args.push(vals[0]); // values bitmask + var valArr = vals[1]; + for (v in valArr) + { + format += 'L'; // TODO: we know format string length in advance and += inefficient for string + args.push(valArr[v]); + } + return [format, args]; + } + ] } diff --git a/test/creategc.js b/test/creategc.js new file mode 100644 index 0000000..c807657 --- /dev/null +++ b/test/creategc.js @@ -0,0 +1,16 @@ +var x11 = require('../lib/x11'); + +var xclient = x11.createClient(); +var mapped = true; +xclient.on('connect', function(display) { + var X = this; + var root = display.screen[0].root; + var wid = X.AllocID(); + + X.CreateWindow(wid, root, 10, 10, 400, 300, 1, 1, 0, { backgroundPixel: 0, eventMask: 0x00000040 }); + X.MapWindow(wid); + + var cid = X.AllocID(); + X.CreateGC(cid, wid); + +}); \ No newline at end of file