UNPKG

@ross-technologies/xlib

Version:
295 lines (248 loc) 10.5 kB
/* Required modules */ const assert = require("assert").ok; const os = require("os"); const {buff2arr} = require("./utils.js"); /* Symbols */ const SYMS = { "xdisplay": Symbol("xdisplay") }; /* Structures */ /* Main Xlib class */ class Xlib { constructor(xdisplay) { assert(typeof(xdisplay) == "object","xdisplay must be an object"); assert(typeof(xdisplay.client) == "object","xdisplay.client must be an object"); assert(typeof(xdisplay.screen) == "object","xdisplay.screen must be an object"); this[SYMS["xdisplay"]] = xdisplay; this.atoms = { "WM_COMMAND": 34, "WM_HINTS": 35, "WM_CLIENT_MACHINE": 36, "WM_ICON_NAME": 37, "WM_ICON_SIZE": 38, "WM_NAME": 39, "WM_NORMAL_HINTS": 40, "WM_SIZE_HINTS": 41, "WM_ZOOM_HINTS": 42 }; this.flags = { /* xPropSizeHints */ "USPosition": (1 << 0), "USSize": (1 << 1), "PPosition": (1 << 2), "PSize": (1 << 3), "PMinSize": (1 << 4), "PMaxSize": (1 << 5), "PResizeInc": (1 << 6), "PAspect": (1 << 7), "PBaseSize": (1 << 8), "PWinGravity": (1 << 9), /* xPropWMHints */ "InputHint": (1 << 0), "StateHint": (1 << 1), "IconPixmapHint": (1 << 2), "IconWindowHint": (1 << 3), "IconPositionHint": (1 << 4), "IconMaskHint": (1 << 5), "WindowGroupHint": (1 << 6) }; } SetClassHint(win,wmhints) { assert(typeof(win) == "number","win must be a number"); assert(Array.isArray(wmhints),"wmhints must be an array"); this[SYMS["xdisplay"]].client.ChangeProperty(0,win,this.atoms.WM_CLASS,this[SYMS["xdisplay"]].client.atoms.STRING,8,wmhints); } SetCommand(win) { assert(typeof(win) == "number","win must be a number"); this.SetTextProperty(win,this.atoms.WM_COMMAND,process.argv); } SetTextProperty(win,property,data) { assert(typeof(win) == "number","win must be a number"); assert(typeof(property) == "number","property must be a number"); assert(typeof(data) == "string" || Array.isArray(data),"data must be a string or array"); if(typeof(data) == "string") return this.SetTextProperty(win,property,[data]); this[SYMS["xdisplay"]].client.ChangeProperty(0,win,property,this[SYMS["xdisplay"]].client.atoms.STRING,8,data); } SetWMClientMachine(win) { assert(typeof(win) == "number","win must be a number"); this.SetTextProperty(win,this.atoms.WM_CLIENT_MACHINE,os.hostname()); } SetWMHints(win,wmhints) { assert(typeof(win) == "number","win must be a number"); assert(typeof(wmhints) == "object","wmhints must be an object"); assert(typeof(wmhints.flags) == "number","wmhints.flags must be a number"); var prop = { flags: 0, input: 0, initialState: 0, iconPixmap: 0, iconWindow: 0, icon: [0,0], iconMask: 0, windowGroup: 0 }; prop.flags = wmhints.flags; if(wmhints.flags & this.flags.InputHint) { assert(typeof(wmhints.input) == "boolean","wmhints.input must be a boolean"); prop.input = (wmhints.input == true ? 1 : 0); } if(wmhints.flags & this.flags.StateHint) { assert(typeof(wmhints.initial_state) == "number","wmhints.initial_state must be a number"); prop.initialState = wmhints.initial_state; } if(wmhints.flags & this.flags.IconPixmapHint) { assert(typeof(wmhints.icon_pixmap) == "number","wmhints.icon_pixmap must be a number"); prop.iconPixmap = wmhints.icon_pixmap; } if(wmhints.flags & this.flags.IconWindowHint) { assert(typeof(wmhints.icon_window) == "number","wmhints.icon_window must be a number"); prop.iconWindow = wmhints.icon_window; } if(wmhints.flags & this.flags.IconPositionHint) { assert(typeof(wmhints.icon) == "object" && Array.isArray(wmhints.icon),"wmhints.icon must be an array"); prop.icon[0] = wmhints.icon[0]; prop.icon[1] = wmhints.icon[1]; } if(wmhints.flags & this.flags.IconMaskHint) { assert(typeof(wmhints.icon_mask) == "number","wmhints.icon_mask must be a number"); prop.iconMask = wmhints.icon_mask; } if(wmhints.flags & this.flags.WindowGroupHint) { assert(typeof(wmhints.window_group) == "number","wmhints.window_group must be a number"); prop.windowGroup = wmhints.window_group; } var buff = Buffer.alloc(36); buff.writeUInt32LE(prop.flags,0); buff.writeUInt32LE(prop.input,4); buff.writeUInt32LE(prop.initialState,8); buff.writeUInt32LE(prop.iconPixmap,12); buff.writeUInt32LE(prop.iconWindow,16); buff.writeUInt32LE(prop.icon[0],20); buff.writeUInt32LE(prop.icon[1],24); buff.writeUInt32LE(prop.iconMask,28); buff.writeUInt32LE(prop.windowGroup,32); this[SYMS["xdisplay"]].client.ChangeProperty(0,win,this.atoms.WM_HINTS,this.atoms.WM_HINTS,32,buff); } SetWMIconName(win,data) { assert(typeof(win) == "number","win must be a number"); assert(typeof(data) == "string","data must be a string"); this.SetTextProperty(win,this.atoms.WM_ICON_NAME,data); } SetWMName(win,data) { assert(typeof(win) == "number","win must be a number"); assert(typeof(data) == "string","data must be a string"); this.SetTextProperty(win,this.atoms.WM_NAME,data); } SetWMNormalHints(win,hints) { assert(typeof(win) == "number","win must be a number"); assert(typeof(hints) == "object","hints must be an object"); assert(typeof(hints.flags) == "number","hints.flags must be a number"); this.SetWMSizeHints(win,hints,this.atoms.WM_NORMAL_HINTS); } SetWMProperties(win,window_name,icon_name,normal_hints,wm_hints,class_hints) { assert(typeof(win) == "number","win must be a number"); if(window_name != null) this.SetWMName(win,window_name); if(icon_name != null) this.SetWMIconName(win,icon_name); this.SetCommand(win); if(normal_hints != null) this.SetWMNormalHints(win,normal_hints); if(wm_hints != null) this.SetWMHints(win,wm_hints); if(class_hints != null) this.SetClassHint(win,class_hints); } SetWMProtocols(win,protocols) { assert(typeof(win) == "number","win must be a number"); assert(typeof(protocols) == "object" && Array.isArray(protocols),"protocols must be an array"); this[SYMS["xdisplay"]].client.InternAtom(false,"WM_PROTOCOLS",(err,WM_PROTOCOLS) => { if(err) throw err; this[SYMS["xdisplay"]].client.ChangeProperty(0,win,WM_PROTOCOLS,this[SYMS["xdisplay"]].client.atoms.ATOM,32,protocols); }); } SetWMSizeHints(win,hints,property) { assert(typeof(win) == "number","win must be a number"); assert(typeof(hints) == "object","hints must be an object"); assert(typeof(hints.flags) == "number","hints.flags must be a number"); assert(typeof(property) == "number","property must be a number"); var data = { x: 0, y: 0, width: 0, height: 0, minWidth: 0, minHeight: 0, maxWidth: 0, maxHeight: 0, widthInc: 0, heightInc: 0, minAspectX: 0, minAspectY: 0, maxAspectX: 0, maxAspectY: 0, baseWidth: 0, baseHeight: 0, winGravity: 0 }; data.flags = (hints.flags & (this.flags.USPosition | this.flags.USSize | this.flags.PPosition | this.flags.PSize | this.flags.PMinSize | this.flags.PMaxSize | this.flags.PResizeInc | this.flags.PAspect | this.flags.PBaseSize | this.flags.PWinGravity)); if(hints.flags & (this.flags.USPosition | this.flags.PPosition)) { assert(typeof(hints.x) == "number","hints.x must be a number"); assert(typeof(hints.y) == "number","hints.y must be a number"); data.x = hints.x; data.y = hints.y; } if(hints.flags & (this.flags.USSize | this.flags.PSize)) { assert(typeof(hints.width) == "number","hints.width must be a number"); assert(typeof(hints.height) == "number","hints.height must be a number"); data.width = hints.width; data.height = hints.height; } if(hints.flags & this.flags.PMinSize) { assert(typeof(hints.min_width) == "number","hints.min_width must be a number"); assert(typeof(hints.min_height) == "number","hints.min_height must be a number"); data.minWidth = hints.min_width; data.minHeight = hints.min_height; } if(hints.flags & this.flags.PMaxSize) { assert(typeof(hints.max_width) == "number","hints.max_width must be a number"); assert(typeof(hints.max_height) == "number","hints.max_height must be a number"); data.maxWidth = hints.max_width; data.maxHeight = hints.max_height; } if(hints.flags & this.flags.PResizeInc) { assert(typeof(hints.width_inc) == "number","hints.width_inc must be a number"); assert(typeof(hints.height_inc) == "number","hints.height_inc must be a number"); data.widthInc = hints.width_inc; data.heightInc = hints.height_inc; } if(hints.flags & this.flags.PAspect) { assert(typeof(hints.min_aspect) == "object" && Array.isArray(hints.min_aspect),"hints.min_aspect must be an array"); assert(typeof(hints.max_aspect) == "object" && Array.isArray(hints.max_aspect),"hints.max_aspect must be an array"); data.minAspectX = hints.min_aspect[0]; data.minAspectY = hints.min_aspect[1]; data.maxAspectX = hints.max_aspect[0]; data.maxAspectY = hints.max_aspect[1]; } if(hints.flags & this.flags.PBaseSize) { assert(typeof(hints.base_width) == "number","hints.base_width must be a number"); assert(typeof(hints.base_height) == "number","hints.base_height must be a number"); data.baseWidth = hints.base_width; data.baseHeight = hints.base_height; } if(hints.flags & this.flags.PWinGravity) { assert(typeof(hints.win_gravity) == "number","hints.win_gravity must be a number"); data.winGravity = hints.win_gravity; } var buff = Buffer.alloc(72); buff.writeUInt32LE(data.flags,0); buff.writeUInt32LE(data.x,4); buff.writeUInt32LE(data.y,8); buff.writeUInt32LE(data.width,12); buff.writeUInt32LE(data.height,16); buff.writeUInt32LE(data.minWidth,20); buff.writeUInt32LE(data.minHeight,24); buff.writeUInt32LE(data.maxWidth,28); buff.writeUInt32LE(data.maxHeight,32); buff.writeUInt32LE(data.widthInc,36); buff.writeUInt32LE(data.heightInc,40); buff.writeUInt32LE(data.minAspectX,44); buff.writeUInt32LE(data.minAspectY,48); buff.writeUInt32LE(data.maxAspectX,52); buff.writeUInt32LE(data.maxAspectY,56); buff.writeUInt32LE(data.baseWidth,60); buff.writeUInt32LE(data.baseHeight,64); buff.writeUInt32LE(data.winGravity,68); this[SYMS["xdisplay"]].client.ChangeProperty(0,win,property,this.atoms.WM_SIZE_HINTS,32,buff); } } module.exports = Xlib;