1
// Berkeley Open Infrastructure for Network Computing
1
// This file is part of BOINC.
2
2
// http://boinc.berkeley.edu
3
// Copyright (C) 2005 University of California
5
// This is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation;
8
// either version 2.1 of the License, or (at your option) any later version.
10
// This software is distributed in the hope that it will be useful,
3
// Copyright (C) 2008 University of California
5
// BOINC is free software; you can redistribute it and/or modify it
6
// under the terms of the GNU Lesser General Public License
7
// as published by the Free Software Foundation,
8
// either version 3 of the License, or (at your option) any later version.
10
// BOINC is distributed in the hope that it will be useful,
11
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
13
// See the GNU Lesser General Public License for more details.
15
// To view the GNU Lesser General Public License visit
16
// http://www.gnu.org/copyleft/lesser.html
17
// or write to the Free Software Foundation, Inc.,
18
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
// You should have received a copy of the GNU Lesser General Public License
16
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
21
19
// Mac_Saver_ModuleView.m
102
105
mVersion = [defaults floatForKey:@"version"];
104
107
// no previous settings so define our defaults
107
109
gBlankingTime = 1;
109
111
// write out the defaults
110
[ defaults setInteger:mVersion forKey:@"version" ];
111
112
[ defaults setInteger:gGoToBlank forKey:@"GoToBlank" ];
112
113
[ defaults setInteger:gBlankingTime forKey:@"BlankingTime" ];
119
[ defaults setInteger:mVersion forKey:@"version" ];
120
period = getGFXDefaultPeriod() / 60;
121
[ defaults setInteger:period forKey:@"DefaultPeriod" ];
122
period = getGFXSciencePeriod() / 60;
123
[ defaults setInteger:period forKey:@"SciencePeriod" ];
124
period = getGGFXChangePeriod() / 60;
125
[ defaults setInteger:period forKey:@"ChangePeriod" ];
115
128
[defaults synchronize];
119
132
gGoToBlank = [ defaults integerForKey:@"GoToBlank" ];
120
133
gBlankingTime = [ defaults integerForKey:@"BlankingTime" ];
134
period = [ defaults integerForKey:@"DefaultPeriod" ];
135
setGFXDefaultPeriod((double)(period * 60));
136
period = [ defaults integerForKey:@"SciencePeriod" ];
137
setGFXSciencePeriod((double)(period * 60));
138
period = [ defaults integerForKey:@"ChangePeriod" ];
139
setGGFXChangePeriod((double)(period * 60));
122
141
[ self setAutoresizesSubviews:YES ]; // make sure the subview resizes.
288
296
if (coveredFreq) {
289
myWindowNumber = [ myWindow windowNumber ];
297
if ( (msg != NULL) && (msg[0] != '\0') ) {
298
myWindowNumber = [ myWindow windowNumber ];
292
NSWindowList(20, windowList);
294
if (gTopWindowListIndex < n) {
295
if (windowList[gTopWindowListIndex] != myWindowNumber) {
296
// Project graphics application has a window open above ours
297
// Don't waste CPU cycles since our window is obscured by application graphics
298
newFrequency = coveredFreq;
301
NSWindowList(20, windowList);
303
if (gTopWindowListIndex < n) {
304
if (windowList[gTopWindowListIndex] != myWindowNumber) {
305
// Project graphics application has a window open above ours
306
// Don't waste CPU cycles since our window is obscured by application graphics
307
newFrequency = coveredFreq;
313
newFrequency = coveredFreq;
333
346
gCurrentDelta.y = 0;
337
[[NSColor blackColor] set];
339
// Erasing only 2 small rectangles reduces screensaver's CPU usage by about 25%
340
imagePosition.x = (float) ((int)gCurrentPosition.x + gImageXIndent);
341
imagePosition.y = (float) (int)gCurrentPosition.y;
342
eraseRect.origin.y = imagePosition.y;
343
eraseRect.size.height = currentDrawingRect.size.height - gTextBoxHeight;
345
if (gCurrentDelta.x > 0) {
346
eraseRect.origin.x = imagePosition.x - 1;
347
eraseRect.size.width = gCurrentDelta.x + 1;
349
eraseRect.origin.x = currentDrawingRect.origin.x + currentDrawingRect.size.width - gImageXIndent + gCurrentDelta.x - 1;
350
eraseRect.size.width = -gCurrentDelta.x + 1;
353
eraseRect = NSInsetRect(eraseRect, -1, -1);
354
NSRectFill(eraseRect);
356
eraseRect.origin.x = imagePosition.x;
357
eraseRect.size.width = currentDrawingRect.size.width - gImageXIndent - gImageXIndent;
359
if (gCurrentDelta.y > 0) {
350
[[NSColor blackColor] set];
352
// Erasing only 2 small rectangles reduces screensaver's CPU usage by about 25%
353
imagePosition.x = (float) ((int)gCurrentPosition.x + gImageXIndent);
354
imagePosition.y = (float) (int)gCurrentPosition.y;
360
355
eraseRect.origin.y = imagePosition.y;
361
eraseRect.size.height = gCurrentDelta.y + 1;
363
eraseRect.origin.y = imagePosition.y + currentDrawingRect.size.height - gTextBoxHeight - 1;
364
eraseRect.size.height = -gCurrentDelta.y + 1;
356
eraseRect.size.height = currentDrawingRect.size.height - gTextBoxHeight;
358
if (gCurrentDelta.x > 0) {
359
eraseRect.origin.x = imagePosition.x - 1;
360
eraseRect.size.width = gCurrentDelta.x + 1;
362
eraseRect.origin.x = currentDrawingRect.origin.x + currentDrawingRect.size.width - gImageXIndent + gCurrentDelta.x - 1;
363
eraseRect.size.width = -gCurrentDelta.x + 1;
366
eraseRect = NSInsetRect(eraseRect, -1, -1);
367
NSRectFill(eraseRect);
369
eraseRect.origin.x = imagePosition.x;
370
eraseRect.size.width = currentDrawingRect.size.width - gImageXIndent - gImageXIndent;
372
if (gCurrentDelta.y > 0) {
373
eraseRect.origin.y = imagePosition.y;
374
eraseRect.size.height = gCurrentDelta.y + 1;
376
eraseRect.origin.y = imagePosition.y + currentDrawingRect.size.height - gTextBoxHeight - 1;
377
eraseRect.size.height = -gCurrentDelta.y + 1;
379
eraseRect = NSInsetRect(eraseRect, -1, -1);
380
NSRectFill(eraseRect);
382
eraseRect = currentDrawingRect;
383
eraseRect.size.height = gTextBoxHeight;
384
eraseRect = NSInsetRect(eraseRect, -1, -1);
385
NSRectFill(eraseRect);
366
eraseRect = NSInsetRect(eraseRect, -1, -1);
367
NSRectFill(eraseRect);
369
eraseRect = currentDrawingRect;
370
eraseRect.size.height = gTextBoxHeight;
371
eraseRect = NSInsetRect(eraseRect, -1, -1);
372
NSRectFill(eraseRect);
377
390
// Get the new drawing area
378
391
gCurrentPosition.x += gCurrentDelta.x;
381
394
imagePosition.x = (float) ((int)gCurrentPosition.x + gImageXIndent);
382
395
imagePosition.y = (float) (int)gCurrentPosition.y;
384
// Calculate QuickDraw Rect for current text box
385
r.left = (float) ((int)gCurrentPosition.x);
386
r.right = r.left + gMovingRect.size.width;
387
r.top = viewBounds.size.height - imagePosition.y;
388
r.bottom = r.top + (int)MAXTEXTBOXHEIGHT;
389
r.top += TEXTBOXTOPBORDER; // Add a few pixels space below image
391
TXNTextBoxOptionsData theOptions = {kTXNUseCGContextRefMask | kTXNSetFlushnessMask,
392
kATSUCenterAlignment, kATSUNoJustification, 0, myContext };
394
cf_msg = CFStringCreateWithCString(NULL, msg, kCFStringEncodingMacRoman);
396
[[NSColor whiteColor] set];
398
397
[ gBOINC_Logo compositeToPoint:imagePosition operation:NSCompositeCopy ];
400
err = TXNDrawCFStringTextBox ( cf_msg, &r, theStyle, &theOptions);
401
gTextBoxHeight = r.bottom - r.top + TEXTBOXTOPBORDER;
399
if ( (msg != NULL) && (msg[0] != '\0') ) {
400
cf_msg = CFStringCreateWithCString(NULL, msg, kCFStringEncodingMacRoman);
402
CGRect bounds = CGRectMake((float) ((int)gCurrentPosition.x),
403
viewBounds.size.height - imagePosition.y + TEXTBOXTOPBORDER,
404
bounds.origin.x + gMovingRect.size.width,
405
bounds.origin.y + (int)MAXTEXTBOXHEIGHT
408
CGContextSaveGState (myContext);
409
CGContextTranslateCTM (myContext, 0, viewBounds.origin.y + viewBounds.size.height);
410
CGContextScaleCTM (myContext, 1.0f, -1.0f);
414
CTFontRef myFont = CTFontCreateWithName(CFSTR("Helvetica"), 20, NULL);
416
HIThemeTextInfo textInfo = {kHIThemeTextInfoVersionOne, kThemeStateActive, kThemeSpecifiedFont,
417
kHIThemeTextHorizontalFlushLeft, kHIThemeTextVerticalFlushTop,
418
kHIThemeTextBoxOptionNone, kHIThemeTextTruncationNone, 0, false,
425
SetPortTextFont(port, kFontIDHelvetica);
426
SetPortTextSize(port, 20);
428
HIThemeTextInfo textInfo = {0, kThemeStateActive, kThemeCurrentPortFont, //kThemeMenuItemCmdKeyFont, //kThemePushButtonFont,
429
kHIThemeTextHorizontalFlushLeft, kHIThemeTextVerticalFlushTop,
430
kHIThemeTextBoxOptionNone, kHIThemeTextTruncationNone, 0, false
434
// Use only APIs available in Mac OS 10.3.9
435
// HIThemeSetTextFill(kThemeTextColorWhite, NULL, myContext, kHIThemeOrientationNormal);
436
// SetThemeTextColor(kThemeTextColorWhite, 32, true);
438
CGFloat myWhiteComponents[] = {1.0, 1.0, 1.0, 1.0};
439
CGColorSpaceRef myColorSpace = CGColorSpaceCreateDeviceRGB ();
440
CGColorRef myTextColor = CGColorCreate(myColorSpace, myWhiteComponents);
442
CGContextSetFillColorWithColor(myContext, myTextColor);
444
HIThemeDrawTextBox(cf_msg, &bounds, &textInfo, myContext, kHIThemeOrientationNormal);
446
CGColorRelease(myTextColor);
447
CGColorSpaceRelease(myColorSpace);
448
CGContextRestoreGState (myContext);
452
gTextBoxHeight = MAXTEXTBOXHEIGHT + TEXTBOXTOPBORDER;
402
453
gMovingRect.size.height = [gBOINC_Logo size].height + gTextBoxHeight;
405
455
isErased = false;
407
457
} else { // Empty or NULL message
430
480
// Display the configuration sheet for the user to choose their settings
431
481
- (NSWindow*)configureSheet
433
485
// if we haven't loaded our configure sheet, load the nib named MyScreenSaver.nib
434
486
if (!mConfigureSheet)
435
[ NSBundle loadNibNamed:@"BOINCSaver" owner:self ];
487
[ NSBundle loadNibNamed:@"BOINCSaver" owner:self ];
436
488
// set the UI state
437
489
[ mGoToBlankCheckbox setState:gGoToBlank ];
438
mBlankingTimeString = [[ NSString alloc ] initWithFormat:@"%d", gBlankingTime ];
491
mBlankingTimeString = [[ NSString alloc ] initWithFormat:@"%d", gBlankingTime ];
439
492
[ mBlankingTimeTextField setStringValue:mBlankingTimeString ];
494
period = getGFXDefaultPeriod() / 60;
495
mDefaultPeriodString = [[ NSString alloc ] initWithFormat:@"%d", period ];
496
[ mDefaultPeriodTextField setStringValue:mDefaultPeriodString ];
498
period = getGFXSciencePeriod() / 60;
499
mSciencePeriodString = [[ NSString alloc ] initWithFormat:@"%d", period ];
500
[ mSciencePeriodTextField setStringValue:mSciencePeriodString ];
502
period = getGGFXChangePeriod() / 60;
503
mChangePeriodString = [[ NSString alloc ] initWithFormat:@"%d", period ];
504
[ mChangePeriodTextField setStringValue:mChangePeriodString ];
441
506
return mConfigureSheet;
444
509
// Called when the user clicked the SAVE button
445
510
- (IBAction) closeSheetSave:(id) sender
447
514
// get the defaults
448
515
ScreenSaverDefaults *defaults = [ ScreenSaverDefaults defaultsForModuleWithName:mBundleID ];
450
517
// save the UI state
451
518
gGoToBlank = [ mGoToBlankCheckbox state ];
452
519
mBlankingTimeString = [ mBlankingTimeTextField stringValue ];
453
gBlankingTime = [ mBlankingTimeString intValue ];
520
gBlankingTime = [ mBlankingTimeString intValue ];
521
if ((gBlankingTime < 0) || (gBlankingTime > 999)) goto Bad;
523
mDefaultPeriodString = [ mDefaultPeriodTextField stringValue ];
524
period = [ mDefaultPeriodString intValue ];
525
if (!validateNumericString((CFStringRef)mDefaultPeriodString)) goto Bad;
526
if ((period < 0) || (period > 999)) goto Bad;
527
setGFXDefaultPeriod((double)(period * 60));
529
mSciencePeriodString = [ mSciencePeriodTextField stringValue ];
530
period = [ mSciencePeriodString intValue ];
531
if (!validateNumericString((CFStringRef)mSciencePeriodString)) goto Bad;
532
if ((period < 0) || (period > 999)) goto Bad;
533
setGFXSciencePeriod((double)(period * 60));
535
mChangePeriodString = [ mChangePeriodTextField stringValue ];
536
period = [ mChangePeriodString intValue ];
537
if (!validateNumericString((CFStringRef)mChangePeriodString)) goto Bad;
538
if ((period < 0) || (period > 999)) goto Bad;
539
setGGFXChangePeriod((double)(period * 60));
455
541
// write the defaults
456
542
[ defaults setInteger:gGoToBlank forKey:@"GoToBlank" ];
457
543
[ defaults setInteger:gBlankingTime forKey:@"BlankingTime" ];
544
period = getGFXDefaultPeriod() / 60;
545
[ defaults setInteger:period forKey:@"DefaultPeriod" ];
546
period = getGFXSciencePeriod() / 60;
547
[ defaults setInteger:period forKey:@"SciencePeriod" ];
548
period = getGGFXChangePeriod() / 60;
549
[ defaults setInteger:period forKey:@"ChangePeriod" ];
460
552
[ defaults synchronize ];
463
555
[ NSApp endSheet:mConfigureSheet ];
558
; // Empty statement is needed to prevent compiler error
559
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
560
[alert addButtonWithTitle:@"OK"];
561
[alert setMessageText:@"Please enter a number between 0 and 999."];
562
[alert setAlertStyle:NSCriticalAlertStyle];
563
[alert beginSheetModalForWindow:mConfigureSheet modalDelegate:self didEndSelector:nil contextInfo:nil];
466
566
// Called when the user clicked the CANCEL button