123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779 |
- 'use strict';
- // @ts-check
- // ==================================================================================
- // graphics.js
- // ----------------------------------------------------------------------------------
- // Description: System Information - library
- // for Node.js
- // Copyright: (c) 2014 - 2020
- // Author: Sebastian Hildebrandt
- // ----------------------------------------------------------------------------------
- // License: MIT
- // ==================================================================================
- // 7. Graphics (controller, display)
- // ----------------------------------------------------------------------------------
-
- const os = require('os');
- const exec = require('child_process').exec;
- const execSync = require('child_process').execSync;
- const util = require('./util');
-
- let _platform = process.platform;
-
- const _linux = (_platform === 'linux');
- const _darwin = (_platform === 'darwin');
- const _windows = (_platform === 'win32');
- const _freebsd = (_platform === 'freebsd');
- const _openbsd = (_platform === 'openbsd');
- const _netbsd = (_platform === 'netbsd');
- const _sunos = (_platform === 'sunos');
-
- let _resolutionx = 0;
- let _resolutiony = 0;
- let _pixeldepth = 0;
- let _refreshrate = 0;
-
- const videoTypes = {
- '-2': 'UNINITIALIZED',
- '-1': 'OTHER',
- '0': 'HD15',
- '1': 'SVIDEO',
- '2': 'Composite video',
- '3': 'Component video',
- '4': 'DVI',
- '5': 'HDMI',
- '6': 'LVDS',
- '8': 'D_JPN',
- '9': 'SDI',
- '10': 'DP',
- '11': 'DP embedded',
- '12': 'UDI',
- '13': 'UDI embedded',
- '14': 'SDTVDONGLE',
- '15': 'MIRACAST',
- '2147483648': 'INTERNAL'
- };
-
- function graphics(callback) {
-
- function parseLinesDarwin(lines) {
- let starts = [];
- let level = -1;
- let lastlevel = -1;
- let controllers = [];
- let displays = [];
- let currentController = {
- vendor: '',
- model: '',
- bus: '',
- vram: -1,
- vramDynamic: false
- };
- let currentDisplay = {
- vendor: '',
- model: '',
- main: false,
- builtin: false,
- connection: '',
- sizex: -1,
- sizey: -1,
- pixeldepth: -1,
- resolutionx: -1,
- resolutiony: -1,
- currentResX: -1,
- currentResY: -1,
- positionX: 0,
- positionY: 0,
- currentRefreshRate: -1
- };
- for (let i = 0; i < lines.length; i++) {
- if ('' !== lines[i].trim()) {
- let start = lines[i].search(/\S|$/);
- if (-1 === starts.indexOf(start)) {
- starts.push(start);
- }
- level = starts.indexOf(start);
- if (level < lastlevel) {
- if (Object.keys(currentController).length > 0) {// just changed to Displays
- controllers.push(currentController);
- currentController = {
- vendor: '',
- model: '',
- bus: '',
- vram: -1,
- vramDynamic: false
- };
- }
- if (Object.keys(currentDisplay).length > 0) {// just changed to Displays
- displays.push(currentDisplay);
- currentDisplay = {
- vendor: '',
- model: '',
- main: false,
- builtin: false,
- connection: '',
- sizex: -1,
- sizey: -1,
- pixeldepth: -1,
- resolutionx: -1,
- resolutiony: -1,
- currentResX: -1,
- currentResY: -1,
- positionX: 0,
- positionY: 0,
- currentRefreshRate: -1
- };
- }
- }
- lastlevel = level;
- let parts = lines[i].split(':');
- if (2 === level) { // grafics controller level
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('chipsetmodel') !== -1) currentController.model = parts[1].trim();
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('bus') !== -1) currentController.bus = parts[1].trim();
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('vendor') !== -1) currentController.vendor = parts[1].split('(')[0].trim();
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('vram(total)') !== -1) {
- currentController.vram = parseInt(parts[1]); // in MB
- if (parts[1].toLowerCase().indexOf('gb') !== -1) {
- currentController.vram = currentController.vram * 1024;
- }
- currentController.vramDynamic = false;
- }
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('vram(dynamic,max)') !== -1) {
- currentController.vram = parseInt(parts[1]); // in MB
- if (parts[1].toLowerCase().indexOf('gb') !== -1) {
- currentController.vram = currentController.vram * 1024;
- }
- currentController.vramDynamic = true;
- }
- }
- if (3 === level) { // display controller level
- if (parts.length > 1 && '' === parts[1]) {
- currentDisplay.vendor = '';
- currentDisplay.model = parts[0].trim();
- currentDisplay.main = false;
- currentDisplay.builtin = false;
- currentDisplay.connection = '';
- currentDisplay.sizex = -1;
- currentDisplay.sizey = -1;
- currentDisplay.positionX = 0;
- currentDisplay.positionY = 0;
- currentDisplay.pixeldepth = -1;
- }
- }
- if (4 === level) { // display controller details level
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('resolution') !== -1) {
- let resolution = parts[1].split('x');
- currentDisplay.resolutionx = (resolution.length > 1 ? parseInt(resolution[0]) : 0);
- currentDisplay.resolutiony = (resolution.length > 1 ? parseInt(resolution[1]) : 0);
- currentDisplay.currentResX = currentDisplay.resolutionx;
- currentDisplay.currentResY = currentDisplay.resolutiony;
- }
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('pixeldepth') !== -1) currentDisplay.pixeldepth = parseInt(parts[1]); // in BIT
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('framebufferdepth') !== -1) currentDisplay.pixeldepth = parseInt(parts[1]); // in BIT
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('maindisplay') !== -1 && parts[1].replace(/ +/g, '').toLowerCase() === 'yes') currentDisplay.main = true;
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('built-in') !== -1 && parts[1].replace(/ +/g, '').toLowerCase() === 'yes') {
- currentDisplay.builtin = true;
- currentDisplay.connection = '';
- }
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('connectiontype') !== -1) {
- currentDisplay.builtin = false;
- currentDisplay.connection = parts[1].trim();
- }
- }
- }
- }
- if (Object.keys(currentController).length > 0) {// just changed to Displays
- controllers.push(currentController);
- }
- if (Object.keys(currentDisplay).length > 0) {// just changed to Displays
- displays.push(currentDisplay);
- }
- return ({
- controllers: controllers,
- displays: displays
- });
- }
-
- function parseLinesLinuxControllers(lines) {
- let controllers = [];
- let currentController = {
- vendor: '',
- model: '',
- bus: '',
- vram: -1,
- vramDynamic: false
- };
- let isGraphicsController = false;
- // PCI bus IDs
- let pciIDs = [];
- try {
- pciIDs = execSync('export LC_ALL=C; dmidecode -t 9 2>/dev/null; unset LC_ALL | grep "Bus Address: "').toString().split('\n');
- for (let i = 0; i < pciIDs.length; i++) {
- pciIDs[i] = pciIDs[i].replace('Bus Address:', '').replace('0000:', '').trim();
- }
- pciIDs = pciIDs.filter(function (el) {
- return el != null && el;
- });
- } catch (e) {
- util.noop();
- }
- for (let i = 0; i < lines.length; i++) {
- if ('' !== lines[i].trim()) {
- if (' ' !== lines[i][0] && '\t' !== lines[i][0]) { // first line of new entry
- let isExternal = (pciIDs.indexOf(lines[i].split(' ')[0]) >= 0);
- let vgapos = lines[i].toLowerCase().indexOf(' vga ');
- let _3dcontrollerpos = lines[i].toLowerCase().indexOf('3d controller');
- if (vgapos !== -1 || _3dcontrollerpos !== -1) { // VGA
- if (_3dcontrollerpos !== -1 && vgapos === -1) {
- vgapos = _3dcontrollerpos;
- }
- if (currentController.vendor || currentController.model || currentController.bus || currentController.vram !== -1 || currentController.vramDynamic) { // already a controller found
- controllers.push(currentController);
- currentController = {
- vendor: '',
- model: '',
- bus: '',
- vram: -1,
- vramDynamic: false
- };
- }
- isGraphicsController = true;
- let endpos = lines[i].search(/\[[0-9a-f]{4}:[0-9a-f]{4}]|$/);
- let parts = lines[i].substr(vgapos, endpos - vgapos).split(':');
- if (parts.length > 1) {
- parts[1] = parts[1].trim();
- if (parts[1].toLowerCase().indexOf('corporation') >= 0) {
- currentController.vendor = parts[1].substr(0, parts[1].toLowerCase().indexOf('corporation') + 11).trim();
- currentController.model = parts[1].substr(parts[1].toLowerCase().indexOf('corporation') + 11, 200).trim().split('(')[0];
- currentController.bus = (pciIDs.length > 0 && isExternal) ? 'PCIe' : 'Onboard';
- currentController.vram = -1;
- currentController.vramDynamic = false;
- } else if (parts[1].toLowerCase().indexOf(' inc.') >= 0) {
- if ((parts[1].match(new RegExp(']', 'g')) || []).length > 1) {
- currentController.vendor = parts[1].substr(0, parts[1].toLowerCase().indexOf(']') + 1).trim();
- currentController.model = parts[1].substr(parts[1].toLowerCase().indexOf(']') + 1, 200).trim().split('(')[0].trim();
- } else {
- currentController.vendor = parts[1].substr(0, parts[1].toLowerCase().indexOf(' inc.') + 5).trim();
- currentController.model = parts[1].substr(parts[1].toLowerCase().indexOf(' inc.') + 5, 200).trim().split('(')[0].trim();
- }
- currentController.bus = (pciIDs.length > 0 && isExternal) ? 'PCIe' : 'Onboard';
- currentController.vram = -1;
- currentController.vramDynamic = false;
- } else if (parts[1].toLowerCase().indexOf(' ltd.') >= 0) {
- if ((parts[1].match(new RegExp(']', 'g')) || []).length > 1) {
- currentController.vendor = parts[1].substr(0, parts[1].toLowerCase().indexOf(']') + 1).trim();
- currentController.model = parts[1].substr(parts[1].toLowerCase().indexOf(']') + 1, 200).trim().split('(')[0].trim();
- } else {
- currentController.vendor = parts[1].substr(0, parts[1].toLowerCase().indexOf(' ltd.') + 5).trim();
- currentController.model = parts[1].substr(parts[1].toLowerCase().indexOf(' ltd.') + 5, 200).trim().split('(')[0].trim();
- }
- }
- }
-
- } else {
- isGraphicsController = false;
- }
- }
- if (isGraphicsController) { // within VGA details
- let parts = lines[i].split(':');
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('devicename') !== -1 && parts[1].toLowerCase().indexOf('onboard') !== -1) currentController.bus = 'Onboard';
- if (parts.length > 1 && parts[0].replace(/ +/g, '').toLowerCase().indexOf('region') !== -1 && parts[1].toLowerCase().indexOf('memory') !== -1) {
- let memparts = parts[1].split('=');
- if (memparts.length > 1) {
- currentController.vram = parseInt(memparts[1]);
- }
- }
- }
- }
- }
- if (currentController.vendor || currentController.model || currentController.bus || currentController.vram !== -1 || currentController.vramDynamic) { // already a controller found
- controllers.push(currentController);
- }
- return (controllers);
- }
-
- function parseLinesLinuxEdid(edid) {
- // parsen EDID
- // --> model
- // --> resolutionx
- // --> resolutiony
- // --> builtin = false
- // --> pixeldepth (?)
- // --> sizex
- // --> sizey
- let result = {
- vendor: '',
- model: '',
- main: false,
- builtin: false,
- connection: '',
- sizex: -1,
- sizey: -1,
- pixeldepth: -1,
- resolutionx: -1,
- resolutiony: -1,
- currentResX: -1,
- currentResY: -1,
- positionX: 0,
- positionY: 0,
- currentRefreshRate: -1
- };
- // find first "Detailed Timing Description"
- let start = 108;
- if (edid.substr(start, 6) === '000000') {
- start += 36;
- }
- if (edid.substr(start, 6) === '000000') {
- start += 36;
- }
- if (edid.substr(start, 6) === '000000') {
- start += 36;
- }
- if (edid.substr(start, 6) === '000000') {
- start += 36;
- }
- result.resolutionx = parseInt('0x0' + edid.substr(start + 8, 1) + edid.substr(start + 4, 2));
- result.resolutiony = parseInt('0x0' + edid.substr(start + 14, 1) + edid.substr(start + 10, 2));
- result.sizex = parseInt('0x0' + edid.substr(start + 28, 1) + edid.substr(start + 24, 2));
- result.sizey = parseInt('0x0' + edid.substr(start + 29, 1) + edid.substr(start + 26, 2));
- // monitor name
- start = edid.indexOf('000000fc00'); // find first "Monitor Description Data"
- if (start >= 0) {
- let model_raw = edid.substr(start + 10, 26);
- if (model_raw.indexOf('0a') !== -1) {
- model_raw = model_raw.substr(0, model_raw.indexOf('0a'));
- }
- try {
- if (model_raw.length > 2) {
- result.model = model_raw.match(/.{1,2}/g).map(function (v) {
- return String.fromCharCode(parseInt(v, 16));
- }).join('');
- }
- } catch (e) {
- util.noop();
- }
- } else {
- result.model = '';
- }
- return result;
- }
-
- function parseLinesLinuxDisplays(lines, depth) {
- let displays = [];
- let currentDisplay = {
- vendor: '',
- model: '',
- main: false,
- builtin: false,
- connection: '',
- sizex: -1,
- sizey: -1,
- pixeldepth: -1,
- resolutionx: -1,
- resolutiony: -1,
- currentResX: -1,
- currentResY: -1,
- positionX: 0,
- positionY: 0,
- currentRefreshRate: -1
- };
- let is_edid = false;
- let is_current = false;
- let edid_raw = '';
- let start = 0;
- for (let i = 1; i < lines.length; i++) { // start with second line
- if ('' !== lines[i].trim()) {
- if (' ' !== lines[i][0] && '\t' !== lines[i][0] && lines[i].toLowerCase().indexOf(' connected ') !== -1) { // first line of new entry
- if (currentDisplay.model || currentDisplay.main || currentDisplay.builtin || currentDisplay.connection || currentDisplay.sizex !== -1 || currentDisplay.pixeldepth !== -1 || currentDisplay.resolutionx !== -1) { // push last display to array
- displays.push(currentDisplay);
- currentDisplay = {
- vendor: '',
- model: '',
- main: false,
- builtin: false,
- connection: '',
- sizex: -1,
- sizey: -1,
- pixeldepth: -1,
- resolutionx: -1,
- resolutiony: -1,
- currentResX: -1,
- currentResY: -1,
- positionX: 0,
- positionY: 0,
- currentRefreshRate: -1
- };
- }
- let parts = lines[i].split(' ');
- currentDisplay.connection = parts[0];
- currentDisplay.main = lines[i].toLowerCase().indexOf(' primary ') >= 0;
- currentDisplay.builtin = (parts[0].toLowerCase().indexOf('edp') >= 0);
- }
-
- // try to read EDID information
- if (is_edid) {
- if (lines[i].search(/\S|$/) > start) {
- edid_raw += lines[i].toLowerCase().trim();
- } else {
- // parsen EDID
- let edid_decoded = parseLinesLinuxEdid(edid_raw);
- currentDisplay.vendor = edid_decoded.vendor;
- currentDisplay.model = edid_decoded.model;
- currentDisplay.resolutionx = edid_decoded.resolutionx;
- currentDisplay.resolutiony = edid_decoded.resolutiony;
- currentDisplay.sizex = edid_decoded.sizex;
- currentDisplay.sizey = edid_decoded.sizey;
- currentDisplay.pixeldepth = depth;
- is_edid = false;
- }
- }
- if (lines[i].toLowerCase().indexOf('edid:') >= 0) {
- is_edid = true;
- start = lines[i].search(/\S|$/);
- }
- if (lines[i].toLowerCase().indexOf('*current') >= 0) {
- const parts1 = lines[i].split('(');
- if (parts1 && parts1.length > 1 && parts1[0].indexOf('x') >= 0) {
- const resParts = parts1[0].trim().split('x');
- currentDisplay.currentResX = util.toInt(resParts[0]);
- currentDisplay.currentResY = util.toInt(resParts[1]);
- }
- is_current = true;
- }
- if (is_current && lines[i].toLowerCase().indexOf('clock') >= 0 && lines[i].toLowerCase().indexOf('hz') >= 0 && lines[i].toLowerCase().indexOf('v: height') >= 0) {
- const parts1 = lines[i].split('clock');
- if (parts1 && parts1.length > 1 && parts1[1].toLowerCase().indexOf('hz') >= 0) {
- currentDisplay.currentRefreshRate = util.toInt(parts1[1]);
- }
- is_current = false;
- }
- }
- }
-
- // pushen displays
- if (currentDisplay.model || currentDisplay.main || currentDisplay.builtin || currentDisplay.connection || currentDisplay.sizex !== -1 || currentDisplay.pixeldepth !== -1 || currentDisplay.resolutionx !== -1) { // still information there
- displays.push(currentDisplay);
- }
- return displays;
- }
-
- // function starts here
- return new Promise((resolve) => {
- process.nextTick(() => {
- let result = {
- controllers: [],
- displays: []
- };
- if (_darwin) {
- let cmd = 'system_profiler SPDisplaysDataType';
- exec(cmd, function (error, stdout) {
- if (!error) {
- let lines = stdout.toString().split('\n');
- result = parseLinesDarwin(lines);
- }
- if (callback) {
- callback(result);
- }
- resolve(result);
- });
- }
- if (_linux) {
- // Raspberry: https://elinux.org/RPI_vcgencmd_usage
- if (util.isRaspberry() && util.isRaspbian()) {
- let cmd = 'fbset -s | grep \'mode "\'; vcgencmd get_mem gpu; tvservice -s; tvservice -n;';
- exec(cmd, function (error, stdout) {
- let lines = stdout.toString().split('\n');
- if (lines.length > 3 && lines[0].indexOf('mode "') >= -1 && lines[2].indexOf('0x12000a') > -1) {
- const parts = lines[0].replace('mode', '').replace(/"/g, '').trim().split('x');
- if (parts.length === 2) {
- result.displays.push({
- vendor: '',
- model: util.getValue(lines, 'device_name', '='),
- main: true,
- builtin: false,
- connection: 'HDMI',
- sizex: -1,
- sizey: -1,
- pixeldepth: -1,
- resolutionx: parseInt(parts[0], 10),
- resolutiony: parseInt(parts[1], 10),
- currentResX: -1,
- currentResY: -1,
- positionX: 0,
- positionY: 0,
- currentRefreshRate: -1
- });
- }
- }
- if (lines.length > 1 && lines[1].indexOf('gpu=') >= -1) {
- result.controllers.push({
- vendor: 'Broadcom',
- model: 'VideoCore IV',
- bus: '',
- vram: lines[1].replace('gpu=', ''),
- vramDynamic: true
- });
- }
- if (callback) {
- callback(result);
- }
- resolve(result);
- });
- } else {
- let cmd = 'lspci -vvv 2>/dev/null';
- exec(cmd, function (error, stdout) {
- if (!error) {
- let lines = stdout.toString().split('\n');
- result.controllers = parseLinesLinuxControllers(lines);
- }
- let cmd = 'xdpyinfo 2>/dev/null | grep \'depth of root window\' | awk \'{ print $5 }\'';
- exec(cmd, function (error, stdout) {
- let depth = 0;
- if (!error) {
- let lines = stdout.toString().split('\n');
- depth = parseInt(lines[0]) || 0;
- }
- let cmd = 'xrandr --verbose 2>/dev/null';
- exec(cmd, function (error, stdout) {
- if (!error) {
- let lines = stdout.toString().split('\n');
- result.displays = parseLinesLinuxDisplays(lines, depth);
- }
- if (callback) {
- callback(result);
- }
- resolve(result);
- });
- });
- });
- }
- }
- if (_freebsd || _openbsd || _netbsd) {
- if (callback) { callback(result); }
- resolve(result);
- }
- if (_sunos) {
- if (callback) { callback(result); }
- resolve(result);
- }
- if (_windows) {
-
- // https://blogs.technet.microsoft.com/heyscriptingguy/2013/10/03/use-powershell-to-discover-multi-monitor-information/
- // https://devblogs.microsoft.com/scripting/use-powershell-to-discover-multi-monitor-information/
- try {
- const workload = [];
- workload.push(util.wmic('path win32_VideoController get /value'));
- workload.push(util.wmic('path win32_desktopmonitor get /value'));
- workload.push(util.powerShell('Get-CimInstance -Namespace root\\wmi -ClassName WmiMonitorBasicDisplayParams | fl'));
- workload.push(util.powerShell('Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.Screen]::AllScreens'));
- workload.push(util.powerShell('Get-CimInstance -Namespace root\\wmi -ClassName WmiMonitorConnectionParams | fl'));
- workload.push(util.powerShell('gwmi WmiMonitorID -Namespace root\\wmi | ForEach-Object {(($_.ManufacturerName -notmatch 0 | foreach {[char]$_}) -join "") + "|" + (($_.ProductCodeID -notmatch 0 | foreach {[char]$_}) -join "") + "|" + (($_.UserFriendlyName -notmatch 0 | foreach {[char]$_}) -join "") + "|" + (($_.SerialNumberID -notmatch 0 | foreach {[char]$_}) -join "") + "|" + $_.InstanceName}'));
-
- Promise.all(
- workload
- ).then(data => {
- // controller
- let csections = data[0].split(/\n\s*\n/);
- result.controllers = parseLinesWindowsControllers(csections);
-
- // displays
- let dsections = data[1].split(/\n\s*\n/);
- // result.displays = parseLinesWindowsDisplays(dsections);
- dsections.shift();
- dsections.pop();
-
- // monitor (powershell)
- let msections = data[2].split('Active ');
- msections.shift();
-
- // forms.screens (powershell)
- let ssections = data[3].split('BitsPerPixel ');
- ssections.shift();
-
- // connection params (powershell) - video type
- let tsections = data[4].split(/\n\s*\n/);
- tsections.shift();
-
- // monitor ID (powershell) - model / vendor
- const res = data[5].split(/\r\n/);
- let isections = [];
- res.forEach(element => {
- const parts = element.split('|');
- if (parts.length === 5) {
- isections.push({
- vendor: parts[0],
- code: parts[1],
- model: parts[2],
- serial: parts[3],
- instanceId: parts[4]
- });
- }
- });
- result.displays = parseLinesWindowsDisplaysPowershell(ssections, msections, dsections, tsections, isections);
-
- if (result.displays.length === 1) {
- if (_resolutionx) {
- result.displays[0].resolutionx = _resolutionx;
- if (!result.displays[0].currentResX) {
- result.displays[0].currentResX = _resolutionx;
- }
- }
- if (_resolutiony) {
- result.displays[0].resolutiony = _resolutiony;
- if (result.displays[0].currentResY === 0) {
- result.displays[0].currentResY = _resolutiony;
- }
- }
- if (_pixeldepth) {
- result.displays[0].pixeldepth = _pixeldepth;
- }
- if (_refreshrate && !result.displays[0].refreshrate) {
- result.displays[0].currentRefreshRate = _refreshrate;
- }
- }
-
- if (callback) {
- callback(result);
- }
- resolve(result);
- })
- .catch(() => {
- if (callback) {
- callback(result);
- }
- resolve(result);
- });
- } catch (e) {
- if (callback) { callback(result); }
- resolve(result);
- }
- }
- });
- });
-
- function parseLinesWindowsControllers(sections) {
- let controllers = [];
- for (let i in sections) {
- if ({}.hasOwnProperty.call(sections, i)) {
- if (sections[i].trim() !== '') {
-
- let lines = sections[i].trim().split('\r\n');
- controllers.push({
- vendor: util.getValue(lines, 'AdapterCompatibility', '='),
- model: util.getValue(lines, 'name', '='),
- bus: util.getValue(lines, 'PNPDeviceID', '=').startsWith('PCI') ? 'PCI' : '',
- vram: parseInt(util.getValue(lines, 'AdapterRAM', '='), 10) / 1024 / 1024,
- vramDynamic: (util.getValue(lines, 'VideoMemoryType', '=') === '2')
- });
- _resolutionx = util.toInt(util.getValue(lines, 'CurrentHorizontalResolution', '=')) || _resolutionx;
- _resolutiony = util.toInt(util.getValue(lines, 'CurrentVerticalResolution', '=')) || _resolutiony;
- _refreshrate = util.toInt(util.getValue(lines, 'CurrentRefreshRate', '=')) || _refreshrate;
- _pixeldepth = util.toInt(util.getValue(lines, 'CurrentBitsPerPixel', '=')) || _pixeldepth;
- }
- }
- }
- return controllers;
- }
-
- // function parseLinesWindowsDisplays(sections) {
- // let displays = [];
- // for (let i in sections) {
- // if (sections.hasOwnProperty(i)) {
- // if (sections[i].trim() !== '') {
- // let lines = sections[i].trim().split('\r\n');
- // displays.push({
- // vendor: util.getValue(lines, 'MonitorManufacturer', '='),
- // model: util.getValue(lines, 'Name', '='),
- // main: false,
- // builtin: false,
- // connection: '',
- // sizex: -1,
- // sizey: -1,
- // pixeldepth: -1,
- // resolutionx: util.toInt(util.getValue(lines, 'ScreenWidth', '=')),
- // resolutiony: util.toInt(util.getValue(lines, 'ScreenHeight', '=')),
- // });
- // }
- // }
- // }
- // return displays;
- // }
-
- function parseLinesWindowsDisplaysPowershell(ssections, msections, dsections, tsections, isections) {
- let displays = [];
- let vendor = '';
- let model = '';
- let deviceID = '';
- let resolutionx = 0;
- let resolutiony = 0;
- if (dsections && dsections.length) {
- let linesDisplay = dsections[0].split(os.EOL);
- vendor = util.getValue(linesDisplay, 'MonitorManufacturer', '=');
- model = util.getValue(linesDisplay, 'Name', '=');
- deviceID = util.getValue(linesDisplay, 'PNPDeviceID', '=').replace(/&/g, '&').toLowerCase();
- resolutionx = util.toInt(util.getValue(linesDisplay, 'ScreenWidth', '='));
- resolutiony = util.toInt(util.getValue(linesDisplay, 'ScreenHeight', '='));
- }
- for (let i = 0; i < ssections.length; i++) {
- if (ssections[i].trim() !== '') {
- ssections[i] = 'BitsPerPixel ' + ssections[i];
- msections[i] = 'Active ' + msections[i];
-
- let linesScreen = ssections[i].split(os.EOL);
- let linesMonitor = msections[i].split(os.EOL);
- let linesConnection = tsections[i].split(os.EOL);
- const bitsPerPixel = util.getValue(linesScreen, 'BitsPerPixel');
- const bounds = util.getValue(linesScreen, 'Bounds').replace('{', '').replace('}', '').split(',');
- const primary = util.getValue(linesScreen, 'Primary');
- const sizex = util.getValue(linesMonitor, 'MaxHorizontalImageSize');
- const sizey = util.getValue(linesMonitor, 'MaxVerticalImageSize');
- const instanceName = util.getValue(linesMonitor, 'InstanceName').toLowerCase();
- const videoOutputTechnology = util.getValue(linesConnection, 'VideoOutputTechnology');
- let displayVendor = '';
- let displayModel = '';
- isections.forEach(element => {
- if (element.instanceId.toLowerCase().startsWith(instanceName) && vendor.startsWith('(') && model.startsWith('PnP')) {
- displayVendor = element.vendor;
- displayModel = element.model;
- }
- });
- displays.push({
- vendor: instanceName.startsWith(deviceID) && displayVendor === '' ? vendor : displayVendor,
- model: instanceName.startsWith(deviceID) && displayModel === '' ? model : displayModel,
- main: primary.toLowerCase() === 'true',
- builtin: videoOutputTechnology === '2147483648',
- connection: videoOutputTechnology && videoTypes[videoOutputTechnology] ? videoTypes[videoOutputTechnology] : '',
- resolutionx: util.toInt(util.getValue(bounds, 'Width', '=')),
- resolutiony: util.toInt(util.getValue(bounds, 'Height', '=')),
- sizex: sizex ? parseInt(sizex, 10) : -1,
- sizey: sizey ? parseInt(sizey, 10) : -1,
- pixeldepth: bitsPerPixel,
- currentResX: util.toInt(util.getValue(bounds, 'Width', '=')),
- currentResY: util.toInt(util.getValue(bounds, 'Height', '=')),
- positionX: util.toInt(util.getValue(bounds, 'X', '=')),
- positionY: util.toInt(util.getValue(bounds, 'Y', '=')),
- });
- }
- }
- if (ssections.length === 0) {
- displays.push({
- vendor,
- model,
- main: true,
- resolutionx,
- resolutiony,
- sizex: -1,
- sizey: -1,
- pixeldepth: -1,
- currentResX: resolutionx,
- currentResY: resolutiony,
- positionX: 0,
- positionY: 0
- });
- }
- return displays;
- }
-
- }
-
- exports.graphics = graphics;
|