1
0
Fork 0
mirror of https://github.com/Ylianst/MeshCentral.git synced 2025-03-09 15:40:18 +00:00

New MeshAgent, new border blinking feature.

This commit is contained in:
Ylian Saint-Hilaire 2018-08-29 18:47:22 -07:00
parent c531b64643
commit 1b3255e844
35 changed files with 7423 additions and 177 deletions

View file

@ -0,0 +1,319 @@
var red = 0xFF;
var yellow = 0xFFFF;
var GXxor = 0x6; // src XOR dst
var GXclear = 0x0;
var ExposureMask = (1 << 15);
function windows_monitorborder()
{
this._ObjectID = 'monitor-info';
var info = require('monitor-info');
var gm = require('_GenericMarshal');
var user32 = gm.CreateNativeProxy('user32.dll');
info.monitors = [];
user32.CreateMethod('GetDC');
user32.CreateMethod('ReleaseDC');
user32.CreateMethod('FillRect');
user32.CreateMethod('InvalidateRect');
var gdi32 = gm.CreateNativeProxy('gdi32.dll');
gdi32.CreateMethod('CreateSolidBrush');
var redBrush = gdi32.CreateSolidBrush(red);
var yellowBrush = gdi32.CreateSolidBrush(yellow);
require('events').EventEmitter.call(this);
this.on('~', function () { this.Stop(); });
this.Stop = function Stop()
{
info.redInterval = null;
var drawRect = gm.CreateVariable(16);
var drawRectBuffer = drawRect.toBuffer();
for (var i in info.monitors)
{
// Top
drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left), 8);
drawRectBuffer.writeInt32LE(info.monitors[i].bottom - info.monitors[i].top, 12);
user32.InvalidateRect(0, drawRect, 0);
}
}
this.Start = function Start()
{
info.getInfo().then(function (mon)
{
var drawRect = gm.CreateVariable(16);
info.monitors = mon;
info.dc = user32.GetDC(0);
info.state = 0;
info.redInterval = setInterval(function ()
{
info.state = (info.state + 1) % 8;
var drawRectBuffer = drawRect.toBuffer();
for(var i in info.monitors)
{
drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left)/2, 8);
drawRectBuffer.writeInt32LE(5, 12);
user32.FillRect(info.dc, drawRect, (info.state == 0 || info.state == 4) ? yellowBrush : redBrush);
drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left) / 2, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
drawRectBuffer.writeInt32LE(5, 12);
user32.FillRect(info.dc, drawRect, (info.state == 1 || info.state == 5) ? yellowBrush : redBrush);
drawRectBuffer.writeInt32LE(info.monitors[i].right - 5, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top)/2, 12);
user32.FillRect(info.dc, drawRect, (info.state == 2 || info.state == 6) ? yellowBrush : redBrush);
drawRectBuffer.writeInt32LE(info.monitors[i].right - 5, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top) / 2, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
user32.FillRect(info.dc, drawRect, (info.state == 3 || info.state == 7) ? yellowBrush : redBrush);
drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left) / 2, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].bottom - 5, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
user32.FillRect(info.dc, drawRect, (info.state == 4 || info.state == 0) ? yellowBrush : redBrush);
drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].bottom - 5, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left) / 2, 8);
drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
user32.FillRect(info.dc, drawRect, (info.state == 5 || info.state == 1) ? yellowBrush : redBrush);
drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top) / 2, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].left + 5, 8);
drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
user32.FillRect(info.dc, drawRect, (info.state == 6 || info.state == 2) ? yellowBrush : redBrush);
drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
drawRectBuffer.writeInt32LE(info.monitors[i].left + 5, 8);
drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top) / 2, 12);
user32.FillRect(info.dc, drawRect, (info.state == 7 || info.state == 3) ? yellowBrush : redBrush);
}
}, 450);
});
}
}
function linux_monitorborder()
{
var self = this;
this.displays = [];
this._ObjectID = 'monitor-info';
this._info = require('monitor-info');
this._isUnity = this._info.isUnity();
console.log('isUnity = ' + this._isUnity);
require('events').EventEmitter.call(this);
this.on('~', function () { this.Stop(); });
this.Stop = function Stop()
{
this._timeout = null;
if(!this._isUnity)
{
for(var i=0; i < this.displays.length; ++i)
{
if(this.displays[i].GC1 && this.displays[i].rootWindow)
{
self._info._X11.XSetFunction(self.displays[i].display, self.displays[i].GC1, GXclear);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, self.displays[i].right, 0);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, self.displays[i].right, 0, self.displays[i].right, self.displays[i].bottom);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, self.displays[i].bottom, self.displays[i].right, self.displays[i].bottom);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, 0, self.displays[i].bottom);
this._info._X11.XFlush(this.displays[i].display);
}
}
}
}
this.Start = function Start()
{
this._info.getInfo().then(function (mon)
{
self.displays = mon;
console.log(mon.length + ' displays');
for(var i = 0; i<mon.length; ++i)
{
console.log('Width: ' + mon[i].right + ', Height: ' + mon[i].bottom);
mon[i].rootWindow = self._info._X11.XRootWindow(mon[i].display, mon[i].screenId);
if (self._isUnity)
{
// We are unity, so we have to fake the borders with borderless windows
var white = self._info._X11.XWhitePixel(mon[i].display, mon[i].screenId).Val;
// Top
mon[i].window_top = self._info._X11.XCreateSimpleWindow(mon[i].display, mon[i].rootWindow, 0, 0, mon[i].right, 5, 0, white, white);
mon[i].window_top.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_top, 0, 0);
self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_top.gc, 10, 0, 1, 1);
self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_top.gc, 1);
self._info.unDecorateWindow(mon[i].display, mon[i].window_top);
self._info.setWindowSizeHints(mon[i].display, mon[i].window_top, 0, 0, mon[i].right, 5);
// Right
mon[i].window_right = self._info._X11.XCreateSimpleWindow(mon[i].display, mon[i].rootWindow, mon[i].right - 5, 0, 5, mon[i].bottom, 0, white, white);
mon[i].window_right.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_right, 0, 0);
self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_right.gc, 10, 0, 1, 1);
self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_right.gc, 1);
self._info.unDecorateWindow(mon[i].display, mon[i].window_right);
self._info.setWindowSizeHints(mon[i].display, mon[i].window_right, mon[i].right - 5, 0, 5, mon[i].bottom);
// Left
mon[i].window_left = self._info._X11.XCreateSimpleWindow(mon[i].display, mon[i].rootWindow, 0, 0, 5, mon[i].bottom, 0, white, white);
mon[i].window_left.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_left, 0, 0);
self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_left.gc, 10, 0, 1, 1);
self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_left.gc, 1);
self._info.unDecorateWindow(mon[i].display, mon[i].window_left);
self._info.setWindowSizeHints(mon[i].display, mon[i].window_left, 0, 0, 5, mon[i].bottom);
// Bottom
mon[i].window_bottom = self._info._X11.XCreateSimpleWindow(mon[i].display, mon[i].rootWindow, 0, mon[i].bottom - 5, mon[i].right, 5, 0, white, white);
mon[i].window_bottom.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_bottom, 0, 0);
self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_bottom.gc, 10, 0, 1, 1);
self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_bottom.gc, 1);
self._info.unDecorateWindow(mon[i].display, mon[i].window_bottom);
self._info.setWindowSizeHints(mon[i].display, mon[i].window_bottom, 0, mon[i].bottom - 5, mon[i].right, 5);
self._info._X11.XMapWindow(mon[i].display, mon[i].window_top);
self._info._X11.XMapWindow(mon[i].display, mon[i].window_right);
self._info._X11.XMapWindow(mon[i].display, mon[i].window_left);
self._info._X11.XMapWindow(mon[i].display, mon[i].window_bottom);
self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_top);
self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_top);
self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_right);
self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_right);
self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_left);
self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_left);
self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_bottom);
self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_bottom);
self._info._X11.XFlush(mon[i].display);
mon[i].borderState = 0;
}
else
{
// If we aren't unity, then we can just draw
mon[i].GC1 = self._info._X11.XCreateGC(mon[i].display, mon[i].rootWindow, 0, 0);
mon[i].borderState = 0;
self._info._X11.XSetForeground(mon[i].display, mon[i].GC1, self._info._X11.XWhitePixel(mon[i].display, mon[i].screenId).Val); // White
self._info._X11.XSetLineAttributes(mon[i].display, mon[i].GC1, 10, 0, 1, 1);
self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].GC1, 1);
}
}
self._info._XEvent = self._info._gm.CreateVariable(192);
self._timeout = setTimeout(self._isUnity ? self.unity_drawBorder : self.timeoutHandler, 250);
});
}
this.timeoutHandler = function()
{
for (var i = 0; i < self.displays.length; ++i) {
self.displays[i].borderState = (self.displays[i].borderState + 1) % 8;
// Top
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 0 || self.displays[i].borderState == 4) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, self.displays[i].right / 2, 0);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 1 || self.displays[i].borderState == 5) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, self.displays[i].right / 2, 0, self.displays[i].right, 0);
// Right
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 2 || self.displays[i].borderState == 6) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, self.displays[i].right, 0, self.displays[i].right, self.displays[i].bottom / 2);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 3 || self.displays[i].borderState == 7) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, self.displays[i].right, self.displays[i].bottom / 2, self.displays[i].right, self.displays[i].bottom);
// Bottom
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 5 || self.displays[i].borderState == 1) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, self.displays[i].bottom, self.displays[i].right / 2, self.displays[i].bottom);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 4 || self.displays[i].borderState == 0) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, self.displays[i].right / 2, self.displays[i].bottom, self.displays[i].right, self.displays[i].bottom);
// Left
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 7 || self.displays[i].borderState == 3) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, 0, self.displays[i].bottom / 2);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 6 || self.displays[i].borderState == 2) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, self.displays[i].bottom / 2, 0, self.displays[i].bottom);
self._info._X11.XFlush(self.displays[i].display);
}
self._timeout = setTimeout(self._isUnity ? self.unity_drawBorder : self.timeoutHandler, 400);
}
this.unity_drawBorder = function unity_drawBorder()
{
for (var i = 0; i < self.displays.length; ++i)
{
self.displays[i].borderState = (self.displays[i].borderState + 1) % 8;
// Top
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_top.gc, (self.displays[i].borderState == 0 || self.displays[i].borderState == 4) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_top, self.displays[i].window_top.gc, 0, 0, self.displays[i].right / 2, 0);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_top.gc, (self.displays[i].borderState == 1 || self.displays[i].borderState == 5) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_top, self.displays[i].window_top.gc, self.displays[i].right / 2, 0, self.displays[i].right, 0);
self._info._X11.XFlush(self.displays[i].display);
// Right
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_right.gc, (self.displays[i].borderState == 2 || self.displays[i].borderState == 6) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_right, self.displays[i].window_right.gc, 0, 0, 0, self.displays[i].bottom / 2);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_right.gc, (self.displays[i].borderState == 3 || self.displays[i].borderState == 7) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_right, self.displays[i].window_right.gc, 0, self.displays[i].bottom / 2, 0, self.displays[i].bottom);
self._info._X11.XFlush(self.displays[i].display);
// Bottom
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_bottom.gc, (self.displays[i].borderState == 5 || self.displays[i].borderState == 1) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_bottom, self.displays[i].window_bottom.gc, 0, 0, self.displays[i].right / 2, 0);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_bottom.gc, (self.displays[i].borderState == 4 || self.displays[i].borderState == 0) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_bottom, self.displays[i].window_bottom.gc, self.displays[i].right / 2, 0, self.displays[i].right, 0);
self._info._X11.XFlush(self.displays[i].display);
// Left
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_left.gc, (self.displays[i].borderState == 7 || self.displays[i].borderState == 3) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_left, self.displays[i].window_left.gc, 0, 0, 0, self.displays[i].bottom / 2);
self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].window_left.gc, (self.displays[i].borderState == 6 || self.displays[i].borderState == 2) ? 0xffff00 : 0xff0000);
self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].window_left, self.displays[i].window_left.gc, 0, self.displays[i].bottom / 2, 0, self.displays[i].bottom);
self._info._X11.XFlush(self.displays[i].display);
}
self._timeout = setTimeout(self._isUnity ? self.unity_drawBorder : self.timeoutHandler, 400);
}
}
switch(process.platform)
{
case 'win32':
module.exports = new windows_monitorborder();
break;
case 'linux':
module.exports = new linux_monitorborder();
break;
default:
break;
}

View file

@ -0,0 +1,194 @@
var promise = require('promise');
var PPosition = 4;
var PSize = 8;
var _NET_WM_STATE_REMOVE = 0; // remove/unset property
var _NET_WM_STATE_ADD = 1; // add/set property
var _NET_WM_STATE_TOGGLE = 2; // toggle property
var SubstructureRedirectMask = (1 << 20);
var SubstructureNotifyMask = (1 << 19);
function monitorinfo()
{
this._ObjectID = 'monitor-info';
this._gm = require('_GenericMarshal');
if (process.platform == 'win32')
{
this._user32 = this._gm.CreateNativeProxy('user32.dll');
this._user32.CreateMethod('EnumDisplayMonitors');
this._kernel32 = this._gm.CreateNativeProxy('kernel32.dll');
this._kernel32.CreateMethod('GetLastError');
this.getInfo = function getInfo()
{
var info = this;
return (new promise(function (resolver, rejector) {
this._monitorinfo = { resolver: resolver, rejector: rejector, self: info, callback: info._gm.GetGenericGlobalCallback(4) };
this._monitorinfo.callback.info = this._monitorinfo;
this._monitorinfo.dwData = info._gm.ObjectToPtr(this._monitorinfo);
this._monitorinfo.callback.results = [];
this._monitorinfo.callback.on('GlobalCallback', function OnMonitorInfo(hmon, hdc, r, user) {
if (this.ObjectToPtr_Verify(this.info, user)) {
var rb = r.Deref(0, 16).toBuffer();
this.results.push({ left: rb.readInt32LE(0), top: rb.readInt32LE(4), right: rb.readInt32LE(8), bottom: rb.readInt32LE(12) });
var r = this.info.self._gm.CreateInteger();
r.Val = 1;
return (r);
}
});
if (info._user32.EnumDisplayMonitors(0, 0, this._monitorinfo.callback, this._monitorinfo.dwData).Val == 0) {
rejector('LastError=' + info._kernel32.GetLastError().Val);
return;
}
else {
resolver(this._monitorinfo.callback.results);
}
}));
}
}
else if(process.platform == 'linux')
{
this._X11 = this._gm.CreateNativeProxy('libX11.so');
this._X11.CreateMethod('XChangeProperty');
this._X11.CreateMethod('XCloseDisplay');
this._X11.CreateMethod('XCreateGC');
this._X11.CreateMethod('XCreateWindow');
this._X11.CreateMethod('XCreateSimpleWindow');
this._X11.CreateMethod('XDefaultColormap');
this._X11.CreateMethod('XDefaultScreen');
this._X11.CreateMethod('XDrawLine');
this._X11.CreateMethod('XDisplayHeight');
this._X11.CreateMethod('XDisplayWidth');
this._X11.CreateMethod('XFetchName');
this._X11.CreateMethod('XFlush');
this._X11.CreateMethod('XFree');
this._X11.CreateMethod('XCreateGC');
this._X11.CreateMethod('XGetWindowProperty');
this._X11.CreateMethod('XInternAtom');
this._X11.CreateMethod('XMapWindow');
this._X11.CreateMethod({ method: 'XNextEvent', threadDispatch: true });
this._X11.CreateMethod('XOpenDisplay');
this._X11.CreateMethod('XRootWindow');
this._X11.CreateMethod('XScreenCount');
this._X11.CreateMethod('XScreenOfDisplay');
this._X11.CreateMethod('XSelectInput');
this._X11.CreateMethod('XSendEvent');
this._X11.CreateMethod('XSetForeground');
this._X11.CreateMethod('XSetFunction');
this._X11.CreateMethod('XSetLineAttributes');
this._X11.CreateMethod('XSetNormalHints');
this._X11.CreateMethod('XSetSubwindowMode');
this._X11.CreateMethod('XBlackPixel');
this._X11.CreateMethod('XWhitePixel');
this.isUnity = function isUnity()
{
var ret = false;
var display = this._X11.XOpenDisplay(this._gm.CreateVariable(':0'));
var rootWindow = this._X11.XRootWindow(display, this._X11.XDefaultScreen(display));
var a = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_CLIENT_LIST'), 1);
var actualType = this._gm.CreateVariable(8);
var format = this._gm.CreateVariable(4);
var numItems = this._gm.CreateVariable(8);
var bytesAfter = this._gm.CreateVariable(8);
var data = this._gm.CreatePointer();
this._X11.XGetWindowProperty(display, rootWindow, a, 0, ~0, 0, 0, actualType, format, numItems, bytesAfter, data);
for (var i = 0; i < numItems.Deref(0, 4).toBuffer().readUInt32LE(0) ; ++i)
{
var w = data.Deref().Deref(i * 8, 8).Deref(8);
var name = this._gm.CreatePointer();
var ns = this._X11.XFetchName(display, w, name);
if (name.Deref().String == 'unity-launcher')
{
ret = true;
break;
}
}
this._X11.XCloseDisplay(display);
return (ret);
}
this.unDecorateWindow = function unDecorateWindow(display, window)
{
var MwmHints = this._gm.CreateVariable(40);
var mwmHintsProperty = this._X11.XInternAtom(display, this._gm.CreateVariable('_MOTIF_WM_HINTS'), 0);
MwmHints.Deref(0, 4).toBuffer().writeUInt32LE(1 << 1);
this._X11.XChangeProperty(display, window, mwmHintsProperty, mwmHintsProperty, 32, 0, MwmHints, 5);
}
this.setWindowSizeHints = function setWindowSizeHints(display, window, x, y, width, height)
{
var sizeHints = this._gm.CreateVariable(80);
sizeHints.Deref(0, 4).toBuffer().writeUInt32LE(PPosition | PSize);
sizeHints.Deref(8, 4).toBuffer().writeUInt32LE(x);
sizeHints.Deref(12, 4).toBuffer().writeUInt32LE(y);
sizeHints.Deref(16, 4).toBuffer().writeUInt32LE(width);
sizeHints.Deref(20, 4).toBuffer().writeUInt32LE(height);
this._X11.XSetNormalHints(display, window, sizeHints);
}
this.setAlwaysOnTop = function setAlwaysOnTop(display, rootWindow, window)
{
var wmNetWmState = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE'), 1);
var wmStateAbove = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE_ABOVE'), 1);
var xclient = this._gm.CreateVariable(96);
xclient.Deref(0, 4).toBuffer().writeUInt32LE(33); // ClientMessage type
xclient.Deref(48, 4).toBuffer().writeUInt32LE(32); // Format 32
wmNetWmState.pointerBuffer().copy(xclient.Deref(40, 8).toBuffer()); // message_type
xclient.Deref(56, 8).toBuffer().writeUInt32LE(_NET_WM_STATE_ADD); // data.l[0]
wmStateAbove.pointerBuffer().copy(xclient.Deref(64, 8).toBuffer()); // data.l[1]
window.pointerBuffer().copy(xclient.Deref(32, 8).toBuffer()); // window
this._X11.XSendEvent(display, rootWindow, 0, SubstructureRedirectMask | SubstructureNotifyMask, xclient);
}
this.hideWindowIcon = function hideWindowIcon(display, rootWindow, window)
{
var wmNetWmState = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE'), 1);
var wmStateSkip = this._X11.XInternAtom(display, this._gm.CreateVariable('_NET_WM_STATE_SKIP_TASKBAR'), 1);
var xclient = this._gm.CreateVariable(96);
xclient.Deref(0, 4).toBuffer().writeUInt32LE(33); // ClientMessage type
xclient.Deref(48, 4).toBuffer().writeUInt32LE(32); // Format 32
wmNetWmState.pointerBuffer().copy(xclient.Deref(40, 8).toBuffer()); // message_type
xclient.Deref(56, 8).toBuffer().writeUInt32LE(_NET_WM_STATE_ADD); // data.l[0]
wmStateSkip.pointerBuffer().copy(xclient.Deref(64, 8).toBuffer()); // data.l[1]
window.pointerBuffer().copy(xclient.Deref(32, 8).toBuffer()); // window
this._X11.XSendEvent(display, rootWindow, 0, SubstructureRedirectMask | SubstructureNotifyMask, xclient);
}
this.getInfo = function getInfo()
{
var info = this;
return (new promise(function (resolver, rejector)
{
var display = info._X11.XOpenDisplay(info._gm.CreateVariable(':0'));
var screenCount = info._X11.XScreenCount(display).Val;
var ret = [];
for(var i=0;i<screenCount;++i)
{
var screen = info._X11.XScreenOfDisplay(display, i);
ret.push({ left: 0, top: 0, right: info._X11.XDisplayWidth(display, i).Val, bottom: info._X11.XDisplayHeight(display, i).Val, screen: screen, screenId: i, display: display });
}
resolver(ret);
}));
}
}
else
{
throw (process.platform + ' not supported');
}
}
module.exports = new monitorinfo();

View file

@ -14,12 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// JavaScript source code
var GM = require('_GenericMarshal');
function processManager() {
this._ObjectID = 'processManager';
switch (process.platform) {
function processManager()
{
this._ObjectID = 'process-manager';
switch(process.platform)
{
case 'win32':
this._kernel32 = GM.CreateNativeProxy('kernel32.dll');
this._kernel32.CreateMethod('GetLastError');
@ -32,19 +34,24 @@ function processManager() {
break;
default:
throw (process.platform + ' not supported');
break;
}
this.getProcesses = function getProcesses(callback) {
switch (process.platform) {
this.getProcesses = function getProcesses(callback)
{
switch(process.platform)
{
default:
throw ('Enumerating processes on ' + process.platform + ' not supported');
break;
case 'win32':
var retVal = {};
var retVal = [];
var h = this._kernel32.CreateToolhelp32Snapshot(2, 0);
var info = GM.CreateVariable(304);
info.toBuffer().writeUInt32LE(304, 0);
var nextProcess = this._kernel32.Process32First(h, info);
while (nextProcess.Val) {
retVal[info.Deref(8, 4).toBuffer().readUInt32LE(0)] = { cmd: info.Deref(GM.PointerSize == 4 ? 36 : 44, 260).String };
while (nextProcess.Val)
{
retVal.push({ pid: info.Deref(8, 4).toBuffer().readUInt32LE(0), command: info.Deref(GM.PointerSize == 4 ? 36 : 44, 260).String });
nextProcess = this._kernel32.Process32Next(h, info);
}
if (callback) { callback.apply(this, [retVal]); }
@ -58,21 +65,32 @@ function processManager() {
p.callback = callback;
p.args = [];
for (var i = 1; i < arguments.length; ++i) { p.args.push(arguments[i]); }
p.on('exit', function onGetProcesses() {
delete this.Parent._psp[this.pid];
var retVal = {}, lines = this.ps.split('\x0D\x0A'), key = {}, keyi = 0;
for (var i in lines) {
p.on('exit', function onGetProcesses()
{
delete this.Parent._psp[this.pid];
var retVal = [];
var lines = this.ps.split('\x0D\x0A');
var key = {};
var keyi = 0;
for (var i in lines)
{
var tokens = lines[i].split(' ');
var tokenList = [];
for (var x in tokens) {
for(var x in tokens)
{
if (i == 0 && tokens[x]) { key[tokens[x]] = keyi++; }
if (i > 0 && tokens[x]) { tokenList.push(tokens[x]); }
if (i > 0 && tokens[x]) { tokenList.push(tokens[x]);}
}
if ((i > 0) && (tokenList[key.PID])) {
retVal[tokenList[key.PID]] = { user: tokenList[key.USER], cmd: tokenList[key.COMMAND] };
if(i>0)
{
if (tokenList[key.PID])
{
retVal.push({ pid: tokenList[key.PID], user: tokenList[key.USER], command: tokenList[key.COMMAND] });
}
}
}
if (this.callback) {
if (this.callback)
{
this.args.unshift(retVal);
this.callback.apply(this.parent, this.args);
}
@ -81,18 +99,25 @@ function processManager() {
break;
}
};
this.getProcessInfo = function getProcessInfo(pid) {
switch (process.platform) {
this.getProcessInfo = function getProcessInfo(pid)
{
switch(process.platform)
{
default:
throw ('getProcessInfo() not supported for ' + process.platform);
break;
case 'linux':
var status = require('fs').readFileSync('/proc/' + pid + '/status'), info = {}, lines = status.toString().split('\n');
for (var i in lines) {
var status = require('fs').readFileSync('/proc/' + pid + '/status');
var info = {};
var lines = status.toString().split('\n');
for(var i in lines)
{
var tokens = lines[i].split(':');
if (tokens.length > 1) { tokens[1] = tokens[1].trim(); }
info[tokens[0]] = tokens[1];
}
return (info);
break;
}
};
}

View file

@ -0,0 +1,185 @@
/*
Copyright 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var refTable = {};
function Promise(promiseFunc)
{
this._ObjectID = 'promise';
this._internal = { promise: this, func: promiseFunc, completed: false, errors: false, completedArgs: [] };
require('events').EventEmitter.call(this._internal);
this._internal.on('_eventHook', function (eventName, eventCallback)
{
//console.log('hook', eventName, 'errors/' + this.errors + ' completed/' + this.completed);
var r = null;
if (eventName == 'resolved' && !this.errors && this.completed)
{
r = eventCallback.apply(this, this.completedArgs);
if(r!=null)
{
this.emit_returnValue('resolved', r);
}
}
if (eventName == 'rejected' && this.errors && this.completed)
{
eventCallback.apply(this, this.completedArgs);
}
if (eventName == 'settled' && this.completed)
{
eventCallback.apply(this, []);
}
});
this._internal.resolver = function _resolver()
{
_resolver._self.errors = false;
_resolver._self.completed = true;
_resolver._self.completedArgs = [];
var args = ['resolved'];
if (this.emit_returnValue && this.emit_returnValue('resolved') != null)
{
_resolver._self.completedArgs.push(this.emit_returnValue('resolved'));
args.push(this.emit_returnValue('resolved'));
}
else
{
for (var a in arguments)
{
_resolver._self.completedArgs.push(arguments[a]);
args.push(arguments[a]);
}
}
_resolver._self.emit.apply(_resolver._self, args);
_resolver._self.emit('settled');
};
this._internal.rejector = function _rejector()
{
_rejector._self.errors = true;
_rejector._self.completed = true;
_rejector._self.completedArgs = [];
var args = ['rejected'];
for (var a in arguments)
{
_rejector._self.completedArgs.push(arguments[a]);
args.push(arguments[a]);
}
_rejector._self.emit.apply(_rejector._self, args);
_rejector._self.emit('settled');
};
this.catch = function(func)
{
this._internal.once('settled', func);
}
this.finally = function (func)
{
this._internal.once('settled', func);
};
this.then = function (resolved, rejected)
{
if (resolved) { this._internal.once('resolved', resolved); }
if (rejected) { this._internal.once('rejected', rejected); }
var retVal = new Promise(function (r, j) { });
this._internal.once('resolved', retVal._internal.resolver);
this._internal.once('rejected', retVal._internal.rejector);
return (retVal);
};
this._internal.resolver._self = this._internal;
this._internal.rejector._self = this._internal;;
try
{
promiseFunc.call(this, this._internal.resolver, this._internal.rejector);
}
catch(e)
{
this._internal.errors = true;
this._internal.completed = true;
this._internal.completedArgs = [e];
this._internal.emit('rejected', e);
this._internal.emit('settled');
}
if(!this._internal.completed)
{
// Save reference of this object
refTable[this._internal._hashCode()] = this._internal;
this._internal.once('settled', function () { refTable[this._hashCode()] = null; });
}
}
Promise.resolve = function resolve()
{
var retVal = new Promise(function (r, j) { });
var args = [];
for (var i in arguments)
{
args.push(arguments[i]);
}
retVal._internal.resolver.apply(retVal._internal, args);
return (retVal);
};
Promise.reject = function reject() {
var retVal = new Promise(function (r, j) { });
var args = [];
for (var i in arguments) {
args.push(arguments[i]);
}
retVal._internal.rejector.apply(retVal._internal, args);
return (retVal);
};
Promise.all = function all(promiseList)
{
var ret = new Promise(function (res, rej)
{
this.__rejector = rej;
this.__resolver = res;
this.__promiseList = promiseList;
this.__done = false;
this.__count = 0;
});
for (var i in promiseList)
{
promiseList[i].then(function ()
{
// Success
if(++ret.__count == ret.__promiseList.length)
{
ret.__done = true;
ret.__resolver(ret.__promiseList);
}
}, function (arg)
{
// Failure
if(!ret.__done)
{
ret.__done = true;
ret.__rejector(arg);
}
});
}
if (promiseList.length == 0)
{
ret.__resolver(promiseList);
}
return (ret);
};
module.exports = Promise;

View file

@ -16,9 +16,27 @@ limitations under the License.
function UserSessions()
{
this._ObjectID = 'UserSessions';
this._ObjectID = 'user-sessions';
require('events').EventEmitter.call(this, true).createEvent('changed');
if (process.platform == 'win32') {
this.enumerateUsers = function enumerateUsers()
{
var promise = require('promise');
var p = new promise(function (res, rej)
{
this.__resolver = res;
this.__rejector = rej;
});
p.__handler = function __handler(users)
{
p.__resolver(users);
};
this.Current(p.__handler);
return (p);
}
if (process.platform == 'win32')
{
this._marshal = require('_GenericMarshal');
this._kernel32 = this._marshal.CreateNativeProxy('Kernel32.dll');
this._kernel32.CreateMethod('GetLastError');
@ -77,7 +95,7 @@ function UserSessions()
return (retVal);
};
this.Current = function Current()
this.Current = function Current(cb)
{
var retVal = {};
var pinfo = this._marshal.CreatePointer();
@ -102,36 +120,152 @@ function UserSessions()
this._wts.WTSFreeMemory(pinfo.Deref());
Object.defineProperty(retVal, 'connected', { value: showActiveOnly(retVal) });
Object.defineProperty(retVal, 'Active', { value: showActiveOnly(retVal) });
if (cb) { cb(retVal); }
return (retVal);
};
}
else
{
this.Current = function Current()
this.Self = function Self()
{
var promise = require('promise');
var p = new promise(function (res, rej)
{
this.__resolver = res; this.__rejector = rej;
this.__child = require('child_process').execFile('/usr/bin/id', ['id', '-u']);
this.__child.promise = this;
this.__child.stdout._txt = '';
this.__child.stdout.on('data', function (chunk) { this._txt += chunk.toString(); });
this.__child.on('exit', function (code)
{
try
{
parseInt(this.stdout._txt);
}
catch (e)
{
this.promise.__rejector('invalid uid');
return;
}
var id = parseInt(this.stdout._txt);
this.promise.__resolver(id);
});
});
return (p);
};
this.Current = function Current(cb)
{
var retVal = {};
var emitterUtils = require('events').inherits(retVal);
emitterUtils.createEvent('logon');
retVal._ObjectID = 'UserSession'
Object.defineProperty(retVal, '_callback', { value: cb });
Object.defineProperty(retVal, '_child', { value: require('child_process').execFile('/usr/bin/last', ['last', '-f', '/var/run/utmp']) });
retVal._child = require('child_process').execFile('/usr/bin/last', ['last', '-f', '/var/run/utmp']);
retVal._child.Parent = retVal;
retVal._child._txt = '';
retVal._child.on('exit', function (code)
{
var lines = this._txt.split('\n');
var sessions = [];
var users = {};
for(var i in lines)
{
if (lines[i])
{
console.log(getTokens(lines[i]));
var user = lines[i].substring(0, lines[i].indexOf(' '));
sessions.push(user);
var tokens = getTokens(lines[i]);
var s = { Username: tokens[0], SessionId: tokens[1] }
if (tokens[3].includes('still logged in'))
{
s.State = 'Active';
}
else
{
s.LastActive = tokens[3];
}
sessions.push(s);
}
}
sessions.pop();
console.log(sessions);
var usernames = {};
var promises = [];
for (var i in sessions)
{
if (sessions[i].Username != 'reboot')
{
users[sessions[i].SessionId] = sessions[i];
if(usernames[sessions[i].Username] == null)
{
usernames[sessions[i].Username] = -1;
}
}
}
try
{
require('promise');
}
catch(e)
{
Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
if (this.Parent._callback) { this.Parent._callback.call(this.Parent, users); }
return;
}
var promise = require('promise');
for (var n in usernames)
{
var p = new promise(function (res, rej)
{
this.__username = n;
this.__resolver = res; this.__rejector = rej;
this.__child = require('child_process').execFile('/usr/bin/id', ['id', '-u', n]);
this.__child.promise = this;
this.__child.stdout._txt = '';
this.__child.stdout.on('data', function (chunk) { this._txt += chunk.toString(); });
this.__child.on('exit', function (code)
{
try
{
parseInt(this.stdout._txt);
}
catch(e)
{
this.promise.__rejector('invalid uid');
return;
}
var id = parseInt(this.stdout._txt);
this.promise.__resolver(id);
});
});
promises.push(p);
}
promise.all(promises).then(function (plist)
{
// Done
var table = {};
for(var i in plist)
{
table[plist[i].__username] = plist[i]._internal.completedArgs[0];
}
for(var i in users)
{
users[i].uid = table[users[i].Username];
}
Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
if (retVal._callback) { retVal._callback.call(retVal, users); }
}, function (reason)
{
// Failed
Object.defineProperty(users, 'Active', { value: showActiveOnly(users) });
if (retVal._callback) { retVal._callback.call(retVal, users); }
});
});
retVal._child.stdout.Parent = retVal._child;
retVal._child.stdout.on('data', function (chunk) { this.Parent._txt += chunk.toString(); });
@ -145,7 +279,7 @@ function showActiveOnly(source)
var retVal = [];
for (var i in source)
{
if (source[i].State == 'Active' || source[i].State == 'Connected')
if (source[i].State == 'Active')
{
retVal.push(source[i]);
}
@ -159,8 +293,13 @@ function getTokens(str)
columns.push(str.substring(0, (i=str.indexOf(' '))));
while (str[++i] == ' ');
columns.push(str.substring(i, str.substring(i).indexOf(' ') + i));
columns.push(str.substring(i, (i=str.substring(i).indexOf(' ') + i)));
while (str[++i] == ' ');
columns.push(str.substring(i, (i=str.substring(i).indexOf(' ') + i)));
while (str[++i] == ' ');
var status = str.substring(i).trim();
columns.push(status);
return (columns);
}