~ubuntu-branches/ubuntu/precise/boinc/precise

« back to all changes in this revision

Viewing changes to clientscr/Mac_Saver_ModuleView.m

Tags: 6.12.8+dfsg-1
* New upstream release.
* Simplified debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
4
 
//
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.
9
 
//
10
 
// This software is distributed in the hope that it will be useful,
 
3
// Copyright (C) 2008 University of California
 
4
//
 
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.
 
9
//
 
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.
14
14
//
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/>.
19
17
 
20
18
//
21
19
//  Mac_Saver_ModuleView.m
25
23
#import "Mac_Saver_ModuleView.h"
26
24
#include <Carbon/Carbon.h>
27
25
#include <AppKit/AppKit.h>
 
26
#include <QTKit/QTKitDefines.h> // For NSInteger
 
27
 
 
28
#ifndef NSInteger
 
29
#if __LP64__ || NS_BUILD_32_LIKE_64
 
30
typedef long NSInteger;
 
31
#else
 
32
typedef int NSInteger;
 
33
#endif
 
34
#endif
 
35
 
 
36
#ifndef CGFLOAT_DEFINED
 
37
typedef float CGFloat;
 
38
#endif
28
39
 
29
40
void print_to_log_file(const char *format, ...);
30
41
void strip_cr(char *buf);
43
54
NSPoint gCurrentPosition;
44
55
NSPoint gCurrentDelta;
45
56
 
46
 
ATSUStyle  theStyle = NULL;
47
 
ATSUFontID theFontID;
48
 
Fixed   atsuSize;
49
 
char myFontName[] = "Helvetica";
50
 
//char myFontName[] = "Lucida Blackletter";
51
 
    
52
 
ATSUAttributeTag  theTags[] =  { kATSUFontTag, kATSUSizeTag };
53
 
ByteCount        theSizes[] = { sizeof (ATSUFontID), sizeof(Fixed) };
54
 
ATSUAttributeValuePtr theValues[] = { &theFontID, &atsuSize };
55
 
 
56
57
CGContextRef myContext;
57
58
bool isErased;
58
59
 
80
81
// against any problems that may cause.
81
82
- (void)startAnimation {
82
83
    NSBundle * myBundle;
83
 
    OSStatus err;
84
84
    int newFrequency;
 
85
    int period;
 
86
    
 
87
    initBOINCSaver();  
85
88
 
86
89
    if (gBOINC_Logo == NULL) {
87
90
        if (self) {
102
105
            mVersion = [defaults floatForKey:@"version"];
103
106
            if (!mVersion) {
104
107
                // no previous settings so define our defaults
105
 
                mVersion = 1;
106
108
                gGoToBlank = NO;
107
109
                gBlankingTime = 1;
108
110
                
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" ];
 
114
            }
 
115
            
 
116
            if (mVersion < 2) {
 
117
                mVersion = 2;
 
118
            
 
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" ];
113
126
                
114
127
                // synchronize
115
128
                [defaults synchronize];
116
129
            }
117
130
 
118
 
            // set defaults...
 
131
            // get defaults...
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));
121
140
 
122
141
           [ self setAutoresizesSubviews:YES ]; // make sure the subview resizes.
123
142
 
146
165
            gCurrentDelta.y = 1.0;
147
166
            
148
167
            [ self setAnimationTimeInterval:1/8.0 ];
149
 
 
150
 
            ATSUFindFontFromName(myFontName, strlen(myFontName), kFontFamilyName, kFontMacintoshPlatform, 
151
 
                                    kFontNoScriptCode, kFontNoLanguageCode, &theFontID);
152
 
                                
153
 
            err = ATSUCreateStyle(&theStyle);
154
 
            atsuSize = Long2Fix (20);
155
 
            err = ATSUSetAttributes(theStyle, 2, theTags, theSizes, theValues);
156
168
        }
157
169
    }
158
170
    
163
175
        return;
164
176
    }
165
177
    
166
 
    newFrequency = initBOINCSaver();        
 
178
    newFrequency = startBOINCSaver();  
167
179
    if (newFrequency)
168
180
        [ self setAnimationTimeInterval:1.0/newFrequency ];
169
181
}
185
197
    }
186
198
    gBOINC_Logo = NULL;
187
199
    
188
 
    if (theStyle) {
189
 
        ATSUDisposeStyle(theStyle);
190
 
    }
191
 
    theStyle = NULL;
192
200
}
193
201
 
194
202
// If there are multiple displays, this may get called 
207
215
    int newFrequency = 0;
208
216
    int coveredFreq = 0;
209
217
    NSRect theFrame = [ self frame ];
210
 
    int myWindowNumber;
211
 
    int windowList[20];
212
 
    int i, n;
 
218
    NSInteger myWindowNumber;
 
219
    NSInteger windowList[20];
 
220
    NSInteger i, n;
213
221
    NSRect currentDrawingRect, eraseRect;
214
222
    NSPoint imagePosition;
215
 
    Rect r;
216
223
    char *msg;
217
224
    CFStringRef cf_msg;
218
225
    AbsoluteTime timeToUnblock, frameStartTime = UpTime();
219
 
    OSStatus err;
220
226
 
221
227
   if ([ self isPreview ]) {
222
228
#if 1   // Currently drawRect just draws our logo in the preview window
239
245
 
240
246
   myContext = [[NSGraphicsContext currentContext] graphicsPort];
241
247
//    [myContext retain];
242
 
 
 
248
    
243
249
    NSWindow *myWindow = [ self window ];
244
250
    NSRect windowFrame = [ myWindow frame ];
245
251
    if ( (windowFrame.origin.x != 0) || (windowFrame.origin.y != 0) ) {
246
252
        // Hide window on second display to aid in debugging
247
253
#ifdef _DEBUG
248
254
        [ myWindow setLevel:kCGMinimumWindowLevel ];
 
255
        NSInteger alpha = 0;
 
256
        [ myWindow setAlphaValue:alpha ];   // For OS 10.6
249
257
#endif
250
258
        return;         // We draw only to main screen
251
259
    }
286
294
    }
287
295
 
288
296
    if (coveredFreq) {
289
 
        myWindowNumber = [ myWindow windowNumber ];
 
297
        if ( (msg != NULL) && (msg[0] != '\0') ) {
 
298
            myWindowNumber = [ myWindow windowNumber ];
290
299
 
291
 
        windowList[0] = 0;
292
 
        NSWindowList(20, windowList);
293
 
        NSCountWindows(&n);
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;
299
 
                msg = NULL;
 
300
            windowList[0] = 0;
 
301
            NSWindowList(20, windowList);
 
302
            NSCountWindows(&n);
 
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;
 
308
                    msg = NULL;
 
309
                    windowIsCovered();
 
310
                }
300
311
            }
 
312
        } else {
 
313
            newFrequency = coveredFreq;
301
314
        }
302
315
    }
303
316
    
333
346
        gCurrentDelta.y = 0;
334
347
#endif
335
348
 
336
 
    if (!isErased) {
337
 
        [[NSColor blackColor] set];
338
 
        
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;
344
 
        
345
 
        if (gCurrentDelta.x > 0) {
346
 
            eraseRect.origin.x = imagePosition.x - 1;
347
 
            eraseRect.size.width = gCurrentDelta.x + 1;
348
 
        } else {
349
 
            eraseRect.origin.x = currentDrawingRect.origin.x + currentDrawingRect.size.width - gImageXIndent + gCurrentDelta.x - 1;
350
 
            eraseRect.size.width = -gCurrentDelta.x + 1;
351
 
        }
352
 
        
353
 
        eraseRect = NSInsetRect(eraseRect, -1, -1);
354
 
        NSRectFill(eraseRect);
355
 
        
356
 
        eraseRect.origin.x = imagePosition.x;
357
 
        eraseRect.size.width = currentDrawingRect.size.width - gImageXIndent - gImageXIndent;
358
 
 
359
 
        if (gCurrentDelta.y > 0) {
 
349
        if (!isErased) {
 
350
            [[NSColor blackColor] set];
 
351
            
 
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;
362
 
        } else {
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;
 
357
            
 
358
            if (gCurrentDelta.x > 0) {
 
359
                eraseRect.origin.x = imagePosition.x - 1;
 
360
                eraseRect.size.width = gCurrentDelta.x + 1;
 
361
            } else {
 
362
                eraseRect.origin.x = currentDrawingRect.origin.x + currentDrawingRect.size.width - gImageXIndent + gCurrentDelta.x - 1;
 
363
                eraseRect.size.width = -gCurrentDelta.x + 1;
 
364
            }
 
365
            
 
366
            eraseRect = NSInsetRect(eraseRect, -1, -1);
 
367
            NSRectFill(eraseRect);
 
368
            
 
369
            eraseRect.origin.x = imagePosition.x;
 
370
            eraseRect.size.width = currentDrawingRect.size.width - gImageXIndent - gImageXIndent;
 
371
 
 
372
            if (gCurrentDelta.y > 0) {
 
373
                eraseRect.origin.y = imagePosition.y;
 
374
                eraseRect.size.height = gCurrentDelta.y + 1;
 
375
            } else {
 
376
                eraseRect.origin.y = imagePosition.y + currentDrawingRect.size.height - gTextBoxHeight - 1;
 
377
                eraseRect.size.height = -gCurrentDelta.y + 1;
 
378
            }
 
379
            eraseRect = NSInsetRect(eraseRect, -1, -1);
 
380
            NSRectFill(eraseRect);
 
381
            
 
382
            eraseRect = currentDrawingRect;
 
383
            eraseRect.size.height = gTextBoxHeight;
 
384
            eraseRect = NSInsetRect(eraseRect, -1, -1);
 
385
            NSRectFill(eraseRect);
 
386
 
 
387
            isErased  = true;
365
388
        }
366
 
        eraseRect = NSInsetRect(eraseRect, -1, -1);
367
 
        NSRectFill(eraseRect);
368
 
        
369
 
        eraseRect = currentDrawingRect;
370
 
        eraseRect.size.height = gTextBoxHeight;
371
 
        eraseRect = NSInsetRect(eraseRect, -1, -1);
372
 
        NSRectFill(eraseRect);
373
 
 
374
 
        isErased  = true;
375
 
    }
376
389
 
377
390
        // Get the new drawing area
378
391
        gCurrentPosition.x += gCurrentDelta.x;
380
393
        
381
394
        imagePosition.x = (float) ((int)gCurrentPosition.x + gImageXIndent);
382
395
        imagePosition.y = (float) (int)gCurrentPosition.y;
383
 
    
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
390
 
        
391
 
        TXNTextBoxOptionsData theOptions = {kTXNUseCGContextRefMask | kTXNSetFlushnessMask, 
392
 
                                            kATSUCenterAlignment, kATSUNoJustification, 0, myContext };
393
 
 
394
 
        cf_msg = CFStringCreateWithCString(NULL, msg, kCFStringEncodingMacRoman);
395
 
 
396
 
        [[NSColor whiteColor] set];
397
396
 
398
397
        [ gBOINC_Logo compositeToPoint:imagePosition operation:NSCompositeCopy ];
399
398
 
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);
 
401
 
 
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
 
406
                            );
 
407
 
 
408
            CGContextSaveGState (myContext);
 
409
            CGContextTranslateCTM (myContext, 0, viewBounds.origin.y + viewBounds.size.height);
 
410
            CGContextScaleCTM (myContext, 1.0f, -1.0f);
 
411
 
 
412
 
 
413
#ifdef __x86_64__
 
414
            CTFontRef myFont = CTFontCreateWithName(CFSTR("Helvetica"), 20, NULL);
 
415
 
 
416
            HIThemeTextInfo textInfo = {kHIThemeTextInfoVersionOne, kThemeStateActive, kThemeSpecifiedFont, 
 
417
                                        kHIThemeTextHorizontalFlushLeft, kHIThemeTextVerticalFlushTop, 
 
418
                                        kHIThemeTextBoxOptionNone, kHIThemeTextTruncationNone, 0, false,
 
419
                                        0, myFont
 
420
                                        };
 
421
 
 
422
#else
 
423
            GrafPtr port;
 
424
            GetPort(&port);
 
425
            SetPortTextFont(port, kFontIDHelvetica);
 
426
            SetPortTextSize(port, 20);
 
427
            
 
428
            HIThemeTextInfo textInfo = {0, kThemeStateActive, kThemeCurrentPortFont, //kThemeMenuItemCmdKeyFont, //kThemePushButtonFont, 
 
429
                                        kHIThemeTextHorizontalFlushLeft, kHIThemeTextVerticalFlushTop, 
 
430
                                        kHIThemeTextBoxOptionNone, kHIThemeTextTruncationNone, 0, false 
 
431
                                        };
 
432
#endif
 
433
 
 
434
            // Use only APIs available in Mac OS 10.3.9
 
435
//            HIThemeSetTextFill(kThemeTextColorWhite, NULL, myContext, kHIThemeOrientationNormal);
 
436
//            SetThemeTextColor(kThemeTextColorWhite, 32, true);
 
437
 
 
438
            CGFloat myWhiteComponents[] = {1.0, 1.0, 1.0, 1.0};
 
439
            CGColorSpaceRef myColorSpace = CGColorSpaceCreateDeviceRGB ();
 
440
            CGColorRef myTextColor = CGColorCreate(myColorSpace, myWhiteComponents);
 
441
 
 
442
            CGContextSetFillColorWithColor(myContext, myTextColor);
 
443
 
 
444
            HIThemeDrawTextBox(cf_msg, &bounds, &textInfo, myContext, kHIThemeOrientationNormal);
 
445
 
 
446
            CGColorRelease(myTextColor);
 
447
            CGColorSpaceRelease(myColorSpace);
 
448
            CGContextRestoreGState (myContext);
 
449
            CFRelease(cf_msg);
 
450
        }
 
451
        
 
452
        gTextBoxHeight = MAXTEXTBOXHEIGHT + TEXTBOXTOPBORDER;
402
453
        gMovingRect.size.height = [gBOINC_Logo size].height + gTextBoxHeight;
403
454
        
404
 
        CFRelease(cf_msg);
405
455
        isErased  = false;
406
456
        
407
457
    } else {        // Empty or NULL message
430
480
// Display the configuration sheet for the user to choose their settings
431
481
- (NSWindow*)configureSheet
432
482
{
 
483
    int period;
 
484
 
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 ];
 
490
 
 
491
    mBlankingTimeString = [[ NSString alloc ] initWithFormat:@"%d", gBlankingTime ];
439
492
        [ mBlankingTimeTextField setStringValue:mBlankingTimeString ];
440
493
    
 
494
    period = getGFXDefaultPeriod() / 60;
 
495
    mDefaultPeriodString = [[ NSString alloc ] initWithFormat:@"%d", period ];
 
496
        [ mDefaultPeriodTextField setStringValue:mDefaultPeriodString ];
 
497
    
 
498
    period = getGFXSciencePeriod() / 60;
 
499
    mSciencePeriodString = [[ NSString alloc ] initWithFormat:@"%d", period ];
 
500
        [ mSciencePeriodTextField setStringValue:mSciencePeriodString ];
 
501
    
 
502
    period = getGGFXChangePeriod() / 60;
 
503
    mChangePeriodString = [[ NSString alloc ] initWithFormat:@"%d", period ];
 
504
        [ mChangePeriodTextField setStringValue:mChangePeriodString ];
 
505
    
441
506
        return mConfigureSheet;
442
507
}
443
508
 
444
509
// Called when the user clicked the SAVE button
445
510
- (IBAction) closeSheetSave:(id) sender
446
511
{
 
512
    int period;
 
513
 
447
514
    // get the defaults
448
515
        ScreenSaverDefaults *defaults = [ ScreenSaverDefaults defaultsForModuleWithName:mBundleID ];
449
516
 
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;
 
522
 
 
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));
 
528
 
 
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));
 
534
 
 
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));
454
540
        
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" ];
458
550
        
459
551
        // synchronize
460
552
    [ defaults synchronize ];
461
553
 
462
554
        // end the sheet
463
555
    [ NSApp endSheet:mConfigureSheet ];
 
556
    return;
 
557
Bad:
 
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];
464
564
}
465
565
 
466
566
// Called when the user clicked the CANCEL button