|
@@ -9,6 +9,7 @@
|
9
|
9
|
#import "AppDelegate.h"
|
10
|
10
|
#import "Serial.h"
|
11
|
11
|
#import "GPUStats.h"
|
|
12
|
+#import "Screenshot.h"
|
12
|
13
|
|
13
|
14
|
#import "SystemInfoKit/SystemInfoKit.h"
|
14
|
15
|
|
|
@@ -61,6 +62,7 @@
|
61
|
62
|
|
62
|
63
|
@synthesize statusMenu, application;
|
63
|
64
|
@synthesize menuColors, menuAnimations, menuVisualizations, menuPorts;
|
|
65
|
+@synthesize menuItemDisplays, menuDisplays;
|
64
|
66
|
@synthesize buttonOff, buttonLights;
|
65
|
67
|
@synthesize brightnessItem, brightnessSlider, brightnessLabel;
|
66
|
68
|
@synthesize statusItem, statusImage;
|
|
@@ -106,6 +108,7 @@
|
106
|
108
|
for (int i = 0; i < [ports count]; i++) {
|
107
|
109
|
// Add Menu Item for this port
|
108
|
110
|
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[ports objectAtIndex:i] action:@selector(selectedSerialPort:) keyEquivalent:@""];
|
|
111
|
+ [item setTag:-1];
|
109
|
112
|
[menuPorts addItem:item];
|
110
|
113
|
|
111
|
114
|
// Set Enabled if it was used the last time
|
|
@@ -140,6 +143,7 @@
|
140
|
143
|
nil];
|
141
|
144
|
for (NSString *key in [staticColors allKeys]) {
|
142
|
145
|
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:key action:@selector(selectedVisualization:) keyEquivalent:@""];
|
|
146
|
+ [item setTag:-1];
|
143
|
147
|
if ([key isEqualToString:lastMode]) {
|
144
|
148
|
[self selectedVisualization:item];
|
145
|
149
|
}
|
|
@@ -154,6 +158,7 @@
|
154
|
158
|
nil];
|
155
|
159
|
for (NSString *key in animationStrings) {
|
156
|
160
|
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:key action:@selector(selectedVisualization:) keyEquivalent:@""];
|
|
161
|
+ [item setTag:-1];
|
157
|
162
|
if ([key isEqualToString:lastMode]) {
|
158
|
163
|
[self selectedVisualization:item];
|
159
|
164
|
}
|
|
@@ -162,6 +167,7 @@
|
162
|
167
|
|
163
|
168
|
// Add CPU Usage menu item
|
164
|
169
|
NSMenuItem *cpuUsageItem = [[NSMenuItem alloc] initWithTitle:TEXT_CPU_USAGE action:@selector(selectedVisualization:) keyEquivalent:@""];
|
|
170
|
+ [cpuUsageItem setTag:-1];
|
165
|
171
|
if ([lastMode isEqualToString:TEXT_CPU_USAGE]) {
|
166
|
172
|
[self selectedVisualization:cpuUsageItem];
|
167
|
173
|
}
|
|
@@ -169,6 +175,7 @@
|
169
|
175
|
|
170
|
176
|
// Add Memory Usage item
|
171
|
177
|
NSMenuItem *memoryUsageItem = [[NSMenuItem alloc] initWithTitle:TEXT_RAM_USAGE action:@selector(selectedVisualization:) keyEquivalent:@""];
|
|
178
|
+ [memoryUsageItem setTag:-1];
|
172
|
179
|
if ([lastMode isEqualToString:TEXT_RAM_USAGE]) {
|
173
|
180
|
[self selectedVisualization:memoryUsageItem];
|
174
|
181
|
}
|
|
@@ -182,12 +189,14 @@
|
182
|
189
|
NSLog(@"Error reading GPU information\n");
|
183
|
190
|
} else {
|
184
|
191
|
NSMenuItem *itemUsage = [[NSMenuItem alloc] initWithTitle:TEXT_GPU_USAGE action:@selector(selectedVisualization:) keyEquivalent:@""];
|
|
192
|
+ [itemUsage setTag:-1];
|
185
|
193
|
if ([lastMode isEqualToString:TEXT_GPU_USAGE]) {
|
186
|
194
|
[self selectedVisualization:itemUsage];
|
187
|
195
|
}
|
188
|
196
|
[menuVisualizations addItem:itemUsage];
|
189
|
197
|
|
190
|
198
|
NSMenuItem *itemVRAM = [[NSMenuItem alloc] initWithTitle:TEXT_VRAM_USAGE action:@selector(selectedVisualization:) keyEquivalent:@""];
|
|
199
|
+ [itemVRAM setTag:-1];
|
191
|
200
|
if ([lastMode isEqualToString:TEXT_VRAM_USAGE]) {
|
192
|
201
|
[self selectedVisualization:itemVRAM];
|
193
|
202
|
}
|
|
@@ -206,6 +215,7 @@
|
206
|
215
|
|
207
|
216
|
if ([key isEqualToString:KEY_CPU_TEMPERATURE]) {
|
208
|
217
|
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:TEXT_CPU_TEMPERATURE action:@selector(selectedVisualization:) keyEquivalent:@""];
|
|
218
|
+ [item setTag:-1];
|
209
|
219
|
if ([lastMode isEqualToString:TEXT_CPU_TEMPERATURE]) {
|
210
|
220
|
[self selectedVisualization:item];
|
211
|
221
|
}
|
|
@@ -214,6 +224,7 @@
|
214
|
224
|
|
215
|
225
|
if ([key isEqualToString:KEY_GPU_TEMPERATURE]) {
|
216
|
226
|
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:TEXT_GPU_TEMPERATURE action:@selector(selectedVisualization:) keyEquivalent:@""];
|
|
227
|
+ [item setTag:-1];
|
217
|
228
|
if ([lastMode isEqualToString:TEXT_GPU_TEMPERATURE]) {
|
218
|
229
|
[self selectedVisualization:item];
|
219
|
230
|
}
|
|
@@ -235,9 +246,24 @@
|
235
|
246
|
[serial sendString:@"UV 0\n"];
|
236
|
247
|
}
|
237
|
248
|
}
|
|
249
|
+
|
|
250
|
+ // List available displays and add menu items
|
|
251
|
+ [Screenshot init:self];
|
|
252
|
+ NSArray *displayIDs = [Screenshot listDisplays];
|
|
253
|
+ [self updateDisplayUI:displayIDs];
|
238
|
254
|
}
|
239
|
255
|
|
240
|
256
|
- (void)applicationWillTerminate:(NSNotification *)aNotification {
|
|
257
|
+ // Stop previous timer setting
|
|
258
|
+ if (animation != nil) {
|
|
259
|
+ [animation invalidate];
|
|
260
|
+ animation = nil;
|
|
261
|
+ }
|
|
262
|
+
|
|
263
|
+ // Remove display callback
|
|
264
|
+ [Screenshot close:self];
|
|
265
|
+
|
|
266
|
+ // Turn off all lights if possible
|
241
|
267
|
if ([serial isOpen]) {
|
242
|
268
|
[serial sendString:@"RGB 0 0 0\n"];
|
243
|
269
|
[serial sendString:@"UV 0\n"];
|
|
@@ -245,6 +271,39 @@
|
245
|
271
|
}
|
246
|
272
|
}
|
247
|
273
|
|
|
274
|
+- (void)clearDisplayUI {
|
|
275
|
+ for (int i = 0; i < [menuDisplays numberOfItems]; i++) {
|
|
276
|
+ if ([[menuDisplays itemAtIndex:i] isEnabled] == YES) {
|
|
277
|
+ // A display configuration is currently selected. Disable the timer
|
|
278
|
+ if (animation != nil) {
|
|
279
|
+ [animation invalidate];
|
|
280
|
+ animation = nil;
|
|
281
|
+ }
|
|
282
|
+ }
|
|
283
|
+ }
|
|
284
|
+ [menuDisplays removeAllItems];
|
|
285
|
+ [menuItemDisplays setHidden:YES];
|
|
286
|
+}
|
|
287
|
+
|
|
288
|
+- (void)updateDisplayUI:(NSArray *)displayIDs {
|
|
289
|
+ if ([displayIDs count] > 0) {
|
|
290
|
+ NSUserDefaults *store = [NSUserDefaults standardUserDefaults];
|
|
291
|
+ NSString *lastMode = [store stringForKey:PREF_LED_MODE];
|
|
292
|
+ [menuItemDisplays setHidden:NO];
|
|
293
|
+ for (int i = 0; i < [displayIDs count]; i++) {
|
|
294
|
+ NSString *title = [Screenshot displayNameFromDisplayID:[displayIDs objectAtIndex:i]];
|
|
295
|
+ NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:title
|
|
296
|
+ action:@selector(selectedVisualization:)
|
|
297
|
+ keyEquivalent:@""];
|
|
298
|
+ [item setTag:[[displayIDs objectAtIndex:i] integerValue]];
|
|
299
|
+ if ([title isEqualToString:lastMode]) {
|
|
300
|
+ [self selectedVisualization:item];
|
|
301
|
+ }
|
|
302
|
+ [menuDisplays addItem:item];
|
|
303
|
+ }
|
|
304
|
+ }
|
|
305
|
+}
|
|
306
|
+
|
248
|
307
|
- (void)setLightsR:(unsigned char)r G:(unsigned char)g B:(unsigned char)b {
|
249
|
308
|
if ([serial isOpen]) {
|
250
|
309
|
unsigned char red = r * ([brightnessSlider floatValue] / 100.0);
|
|
@@ -265,6 +324,7 @@
|
265
|
324
|
for (int i = 0; i < [ports count]; i++) {
|
266
|
325
|
// Add Menu Item for this port
|
267
|
326
|
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[ports objectAtIndex:i] action:@selector(selectedSerialPort:) keyEquivalent:@""];
|
|
327
|
+ [item setTag:-1];
|
268
|
328
|
[menuPorts addItem:item];
|
269
|
329
|
|
270
|
330
|
// Mark it if it is currently open
|
|
@@ -321,6 +381,12 @@
|
321
|
381
|
}
|
322
|
382
|
[[menuVisualizations itemAtIndex:i] setState:NSOffState];
|
323
|
383
|
}
|
|
384
|
+ for (int i = 0; i < [menuDisplays numberOfItems]; i++) {
|
|
385
|
+ if ([[menuDisplays itemAtIndex:i] state] == NSOnState) {
|
|
386
|
+ lastLEDMode = [menuDisplays itemAtIndex:i];
|
|
387
|
+ }
|
|
388
|
+ [[menuDisplays itemAtIndex:i] setState:NSOffState];
|
|
389
|
+ }
|
324
|
390
|
|
325
|
391
|
// Turn on "off" menu item
|
326
|
392
|
[sender setState:NSOnState];
|
|
@@ -406,6 +472,20 @@
|
406
|
472
|
return YES;
|
407
|
473
|
}
|
408
|
474
|
|
|
475
|
+- (void)displayVisualization:(NSMenuItem *)sender {
|
|
476
|
+ // Stop previous timer setting
|
|
477
|
+ if (animation != nil) {
|
|
478
|
+ [animation invalidate];
|
|
479
|
+ animation = nil;
|
|
480
|
+ }
|
|
481
|
+
|
|
482
|
+ // Schedule next invocation for this animation...
|
|
483
|
+ animation = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(visualizeDisplay:) userInfo:[NSNumber numberWithInteger:[sender tag]] repeats:YES];
|
|
484
|
+
|
|
485
|
+ // ...and also execute it right now
|
|
486
|
+ [animation fire];
|
|
487
|
+}
|
|
488
|
+
|
409
|
489
|
- (void)selectedVisualization:(NSMenuItem *)sender {
|
410
|
490
|
// Turn off all other LED menu items
|
411
|
491
|
if (menuColors != nil) {
|
|
@@ -423,12 +503,23 @@
|
423
|
503
|
[[menuVisualizations itemAtIndex:i] setState:NSOffState];
|
424
|
504
|
}
|
425
|
505
|
}
|
|
506
|
+ if (menuDisplays != nil) {
|
|
507
|
+ for (int i = 0; i < [menuDisplays numberOfItems]; i++) {
|
|
508
|
+ [[menuDisplays itemAtIndex:i] setState:NSOffState];
|
|
509
|
+ }
|
|
510
|
+ }
|
426
|
511
|
[buttonOff setState:NSOffState];
|
427
|
512
|
[sender setState:NSOnState];
|
428
|
513
|
|
429
|
|
- // Check if a static color was selected
|
|
514
|
+ // Check if it is a display
|
430
|
515
|
BOOL found = NO;
|
431
|
|
- if (staticColors != nil) {
|
|
516
|
+ if ([sender tag] > -1) {
|
|
517
|
+ found = YES;
|
|
518
|
+ [self displayVisualization:sender];
|
|
519
|
+ }
|
|
520
|
+
|
|
521
|
+ // Check if a static color was selected
|
|
522
|
+ if ((found == NO) && (staticColors != nil)) {
|
432
|
523
|
for (NSString *key in [staticColors allKeys]) {
|
433
|
524
|
if ([sender.title isEqualToString:key]) {
|
434
|
525
|
found = YES;
|
|
@@ -450,7 +541,7 @@
|
450
|
541
|
}
|
451
|
542
|
}
|
452
|
543
|
|
453
|
|
- if (!found) {
|
|
544
|
+ if (found == NO) {
|
454
|
545
|
// Check if an animated visualization was selected
|
455
|
546
|
if ([self timedVisualization:[sender title]] == NO) {
|
456
|
547
|
NSLog(@"Unknown LED Visualization selected!\n");
|
|
@@ -529,6 +620,33 @@
|
529
|
620
|
// ------------------- Visualizations -------------------
|
530
|
621
|
// ------------------------------------------------------
|
531
|
622
|
|
|
623
|
+- (void)visualizeDisplay:(NSTimer *)timer {
|
|
624
|
+ NSBitmapImageRep *screen = [Screenshot screenshot:[timer userInfo]];
|
|
625
|
+
|
|
626
|
+ if ((([screen samplesPerPixel] != 3) && ([screen samplesPerPixel] != 4)) || ([screen isPlanar] == YES) || ([screen numberOfPlanes] != 1)) {
|
|
627
|
+ NSLog(@"Unknown image format (%ld, %c, %ld)!\n", (long)[screen samplesPerPixel], ([screen isPlanar] == YES) ? 'p' : 'n', (long)[screen numberOfPlanes]);
|
|
628
|
+ return;
|
|
629
|
+ }
|
|
630
|
+
|
|
631
|
+ int redC = 0, greenC = 1, blueC = 2;
|
|
632
|
+ if ([screen bitmapFormat] & NSAlphaFirstBitmapFormat) {
|
|
633
|
+ redC = 1; greenC = 2; blueC = 3;
|
|
634
|
+ }
|
|
635
|
+
|
|
636
|
+ unsigned char *data = [screen bitmapData];
|
|
637
|
+ unsigned long long width = [screen pixelsWide];
|
|
638
|
+ unsigned long long height = [screen pixelsHigh];
|
|
639
|
+ unsigned long long max = width * height;
|
|
640
|
+ unsigned long long red = 0, green = 0, blue = 0;
|
|
641
|
+ for (unsigned long long i = 0; i < max; i++) {
|
|
642
|
+ red += data[([screen samplesPerPixel] * i) + redC];
|
|
643
|
+ green += data[([screen samplesPerPixel] * i) + greenC];
|
|
644
|
+ blue += data[([screen samplesPerPixel] * i) + blueC];
|
|
645
|
+ }
|
|
646
|
+
|
|
647
|
+ [self setLightsR:(red / max) G:(green / max) B:(blue / max)];
|
|
648
|
+}
|
|
649
|
+
|
532
|
650
|
- (void)visualizeGPUUsage:(NSTimer *)timer {
|
533
|
651
|
NSNumber *usage;
|
534
|
652
|
NSNumber *freeVRAM;
|