EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
monitor-border.js
Go to the documentation of this file.
1/*
2Copyright 2018-2021 Intel Corporation
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17var red = 0xFF;
18var yellow = 0xFFFF;
19var GXxor = 0x6; // src XOR dst
20var GXclear = 0x0;
21var ExposureMask = (1 << 15);
22
23function windows_monitorborder()
24{
25 this._ObjectID = 'monitor-info';
26 var info = require('monitor-info');
27 var gm = require('_GenericMarshal');
28 var user32 = gm.CreateNativeProxy('user32.dll');
29
30 info.monitors = [];
31 user32.CreateMethod('GetDC');
32 user32.CreateMethod('ReleaseDC');
33 user32.CreateMethod('FillRect');
34 user32.CreateMethod('InvalidateRect');
35
36 var gdi32 = gm.CreateNativeProxy('gdi32.dll');
37 gdi32.CreateMethod('CreateSolidBrush');
38
39 var redBrush = gdi32.CreateSolidBrush(red);
40 var yellowBrush = gdi32.CreateSolidBrush(yellow);
41
42 require('events').EventEmitter.call(this);
43 this.on('~', function () { this.Stop(); });
44
45 this.Stop = function Stop()
46 {
47 info.redInterval = null;
48
49 var drawRect = gm.CreateVariable(16);
50 var drawRectBuffer = drawRect.toBuffer();
51
52 for (var i in info.monitors)
53 {
54 // Top
55 drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
56 drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
57 drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left), 8);
58 drawRectBuffer.writeInt32LE(info.monitors[i].bottom - info.monitors[i].top, 12);
59 user32.InvalidateRect(0, drawRect, 0);
60 }
61 }
62
63 this.Start = function Start()
64 {
65 info.getInfo().then(function (mon)
66 {
67 var drawRect = gm.CreateVariable(16);
68
69 info.monitors = mon;
70 info.dc = user32.GetDC(0);
71 info.state = 0;
72
73 info.redInterval = setInterval(function ()
74 {
75 info.state = (info.state + 1) % 8;
76
77 var drawRectBuffer = drawRect.toBuffer();
78 for(var i in info.monitors)
79 {
80 drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
81 drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
82 drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left)/2, 8);
83 drawRectBuffer.writeInt32LE(5, 12);
84 user32.FillRect(info.dc, drawRect, (info.state == 0 || info.state == 4) ? yellowBrush : redBrush);
85 drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left) / 2, 0);
86 drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
87 drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
88 drawRectBuffer.writeInt32LE(5, 12);
89 user32.FillRect(info.dc, drawRect, (info.state == 1 || info.state == 5) ? yellowBrush : redBrush);
90
91
92 drawRectBuffer.writeInt32LE(info.monitors[i].right - 5, 0);
93 drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
94 drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
95 drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top)/2, 12);
96 user32.FillRect(info.dc, drawRect, (info.state == 2 || info.state == 6) ? yellowBrush : redBrush);
97 drawRectBuffer.writeInt32LE(info.monitors[i].right - 5, 0);
98 drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top) / 2, 4);
99 drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
100 drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
101 user32.FillRect(info.dc, drawRect, (info.state == 3 || info.state == 7) ? yellowBrush : redBrush);
102
103
104 drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left) / 2, 0);
105 drawRectBuffer.writeInt32LE(info.monitors[i].bottom - 5, 4);
106 drawRectBuffer.writeInt32LE(info.monitors[i].right, 8);
107 drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
108 user32.FillRect(info.dc, drawRect, (info.state == 4 || info.state == 0) ? yellowBrush : redBrush);
109 drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
110 drawRectBuffer.writeInt32LE(info.monitors[i].bottom - 5, 4);
111 drawRectBuffer.writeInt32LE(info.monitors[i].left + (info.monitors[i].right - info.monitors[i].left) / 2, 8);
112 drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
113 user32.FillRect(info.dc, drawRect, (info.state == 5 || info.state == 1) ? yellowBrush : redBrush);
114
115
116 drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
117 drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top) / 2, 4);
118 drawRectBuffer.writeInt32LE(info.monitors[i].left + 5, 8);
119 drawRectBuffer.writeInt32LE(info.monitors[i].bottom, 12);
120 user32.FillRect(info.dc, drawRect, (info.state == 6 || info.state == 2) ? yellowBrush : redBrush);
121 drawRectBuffer.writeInt32LE(info.monitors[i].left, 0);
122 drawRectBuffer.writeInt32LE(info.monitors[i].top, 4);
123 drawRectBuffer.writeInt32LE(info.monitors[i].left + 5, 8);
124 drawRectBuffer.writeInt32LE(info.monitors[i].top + (info.monitors[i].bottom - info.monitors[i].top) / 2, 12);
125 user32.FillRect(info.dc, drawRect, (info.state == 7 || info.state == 3) ? yellowBrush : redBrush);
126 }
127 }, 450);
128 });
129 }
130}
131
132function linux_monitorborder()
133{
134 var self = this;
135 this.displays = [];
136 this._ObjectID = 'monitor-info';
137 this._info = require('monitor-info');
138 this._isUnity = this._info.isUnity();
139
140 console.log('isUnity = ' + this._isUnity);
141
142 require('events').EventEmitter.call(this);
143 this.on('~', function () { this.Stop(); });
144
145 this.Stop = function Stop()
146 {
147 this._timeout = null;
148 if(!this._isUnity)
149 {
150 for(var i=0; i < this.displays.length; ++i)
151 {
152 if(this.displays[i].GC1 && this.displays[i].rootWindow)
153 {
154 self._info._X11.XSetFunction(self.displays[i].display, self.displays[i].GC1, GXclear);
155 self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, self.displays[i].right, 0);
156 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);
157 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);
158 self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, 0, self.displays[i].bottom);
159
160 this._info._X11.XFlush(this.displays[i].display);
161 }
162 }
163 }
164 }
165 this.Start = function Start()
166 {
167 this._info.getInfo().then(function (mon)
168 {
169 self.displays = mon;
170 console.log(mon.length + ' displays');
171 for(var i = 0; i<mon.length; ++i)
172 {
173 console.log('Width: ' + mon[i].right + ', Height: ' + mon[i].bottom);
174 mon[i].rootWindow = self._info._X11.XRootWindow(mon[i].display, mon[i].screenId);
175
176 if (self._isUnity)
177 {
178 // We are unity, so we have to fake the borders with borderless windows
179 var white = self._info._X11.XWhitePixel(mon[i].display, mon[i].screenId).Val;
180
181 // Top
182 mon[i].window_top = self._info._X11.XCreateSimpleWindow(mon[i].display, mon[i].rootWindow, 0, 0, mon[i].right, 5, 0, white, white);
183 mon[i].window_top.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_top, 0, 0);
184 self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_top.gc, 10, 0, 1, 1);
185 self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_top.gc, 1);
186 self._info.unDecorateWindow(mon[i].display, mon[i].window_top);
187 self._info.setWindowSizeHints(mon[i].display, mon[i].window_top, 0, 0, mon[i].right, 5);
188
189 // Right
190 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);
191 mon[i].window_right.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_right, 0, 0);
192 self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_right.gc, 10, 0, 1, 1);
193 self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_right.gc, 1);
194 self._info.unDecorateWindow(mon[i].display, mon[i].window_right);
195 self._info.setWindowSizeHints(mon[i].display, mon[i].window_right, mon[i].right - 5, 0, 5, mon[i].bottom);
196
197 // Left
198 mon[i].window_left = self._info._X11.XCreateSimpleWindow(mon[i].display, mon[i].rootWindow, 0, 0, 5, mon[i].bottom, 0, white, white);
199 mon[i].window_left.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_left, 0, 0);
200 self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_left.gc, 10, 0, 1, 1);
201 self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_left.gc, 1);
202 self._info.unDecorateWindow(mon[i].display, mon[i].window_left);
203 self._info.setWindowSizeHints(mon[i].display, mon[i].window_left, 0, 0, 5, mon[i].bottom);
204
205 // Bottom
206 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);
207 mon[i].window_bottom.gc = self._info._X11.XCreateGC(mon[i].display, mon[i].window_bottom, 0, 0);
208 self._info._X11.XSetLineAttributes(mon[i].display, mon[i].window_bottom.gc, 10, 0, 1, 1);
209 self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].window_bottom.gc, 1);
210 self._info.unDecorateWindow(mon[i].display, mon[i].window_bottom);
211 self._info.setWindowSizeHints(mon[i].display, mon[i].window_bottom, 0, mon[i].bottom - 5, mon[i].right, 5);
212
213 self._info._X11.XMapWindow(mon[i].display, mon[i].window_top);
214 self._info._X11.XMapWindow(mon[i].display, mon[i].window_right);
215 self._info._X11.XMapWindow(mon[i].display, mon[i].window_left);
216 self._info._X11.XMapWindow(mon[i].display, mon[i].window_bottom);
217
218 self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_top);
219 self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_top);
220 self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_right);
221 self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_right);
222 self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_left);
223 self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_left);
224 self._info.setAlwaysOnTop(mon[i].display, mon[i].rootWindow, mon[i].window_bottom);
225 self._info.hideWindowIcon(mon[i].display, mon[i].rootWindow, mon[i].window_bottom);
226
227 self._info._X11.XFlush(mon[i].display);
228 mon[i].borderState = 0;
229 }
230 else
231 {
232 // If we aren't unity, then we can just draw
233 mon[i].GC1 = self._info._X11.XCreateGC(mon[i].display, mon[i].rootWindow, 0, 0);
234 mon[i].borderState = 0;
235
236 self._info._X11.XSetForeground(mon[i].display, mon[i].GC1, self._info._X11.XWhitePixel(mon[i].display, mon[i].screenId).Val); // White
237 self._info._X11.XSetLineAttributes(mon[i].display, mon[i].GC1, 10, 0, 1, 1);
238 self._info._X11.XSetSubwindowMode(mon[i].display, mon[i].GC1, 1);
239 }
240 }
241 self._info._XEvent = self._info._gm.CreateVariable(192);
242 self._timeout = setTimeout(self._isUnity ? self.unity_drawBorder : self.timeoutHandler, 250);
243 });
244 }
245
246 this.timeoutHandler = function()
247 {
248 for (var i = 0; i < self.displays.length; ++i) {
249 self.displays[i].borderState = (self.displays[i].borderState + 1) % 8;
250
251 // Top
252 self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 0 || self.displays[i].borderState == 4) ? 0xffff00 : 0xff0000);
253 self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, self.displays[i].right / 2, 0);
254 self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 1 || self.displays[i].borderState == 5) ? 0xffff00 : 0xff0000);
255 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);
256
257 // Right
258 self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 2 || self.displays[i].borderState == 6) ? 0xffff00 : 0xff0000);
259 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);
260 self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 3 || self.displays[i].borderState == 7) ? 0xffff00 : 0xff0000);
261 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);
262
263 // Bottom
264 self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 5 || self.displays[i].borderState == 1) ? 0xffff00 : 0xff0000);
265 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);
266 self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 4 || self.displays[i].borderState == 0) ? 0xffff00 : 0xff0000);
267 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);
268
269 // Left
270 self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 7 || self.displays[i].borderState == 3) ? 0xffff00 : 0xff0000);
271 self._info._X11.XDrawLine(self.displays[i].display, self.displays[i].rootWindow, self.displays[i].GC1, 0, 0, 0, self.displays[i].bottom / 2);
272 self._info._X11.XSetForeground(self.displays[i].display, self.displays[i].GC1, (self.displays[i].borderState == 6 || self.displays[i].borderState == 2) ? 0xffff00 : 0xff0000);
273 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);
274
275
276 self._info._X11.XFlush(self.displays[i].display);
277 }
278 self._timeout = setTimeout(self._isUnity ? self.unity_drawBorder : self.timeoutHandler, 400);
279 }
280 this.unity_drawBorder = function unity_drawBorder()
281 {
282 for (var i = 0; i < self.displays.length; ++i)
283 {
284 self.displays[i].borderState = (self.displays[i].borderState + 1) % 8;
285
286 // Top
287 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);
288 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);
289 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);
290 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);
291 self._info._X11.XFlush(self.displays[i].display);
292
293 // Right
294 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);
295 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);
296 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);
297 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);
298 self._info._X11.XFlush(self.displays[i].display);
299
300 // Bottom
301 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);
302 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);
303 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);
304 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);
305 self._info._X11.XFlush(self.displays[i].display);
306
307 // Left
308 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);
309 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);
310 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);
311 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);
312 self._info._X11.XFlush(self.displays[i].display);
313 }
314 self._timeout = setTimeout(self._isUnity ? self.unity_drawBorder : self.timeoutHandler, 400);
315 }
316}
317
318switch(process.platform)
319{
320 case 'win32':
321 module.exports = new windows_monitorborder();
322 break;
323 case 'linux':
324 module.exports = new linux_monitorborder();
325 break;
326 default:
327 break;
328}
329
330
331
332
333
334
335