Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

COSXScreenSaver.cpp

00001 /*
00002  * synergy -- mouse and keyboard sharing utility
00003  * Copyright (C) 2004 Chris Schoeneman
00004  * 
00005  * This package is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * found in the file COPYING that should have accompanied this file.
00008  * 
00009  * This package is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  */
00014 
00015 #import "COSXScreenSaver.h"
00016 #import "COSXScreenSaverUtil.h"
00017 #import "CLog.h"
00018 #import "IEventQueue.h"
00019 #import "IPrimaryScreen.h"
00020 #import <string.h>
00021 
00022 //
00023 // COSXScreenSaver
00024 //
00025 
00026 COSXScreenSaver::COSXScreenSaver(void* eventTarget) :
00027     m_eventTarget(eventTarget),
00028     m_enabled(true)
00029 {
00030     m_autoReleasePool       = screenSaverUtilCreatePool();
00031     m_screenSaverController = screenSaverUtilCreateController();
00032 
00033     // install launch/termination event handlers
00034     EventTypeSpec launchEventTypes[2];
00035     launchEventTypes[0].eventClass = kEventClassApplication;
00036     launchEventTypes[0].eventKind  = kEventAppLaunched;
00037     launchEventTypes[1].eventClass = kEventClassApplication;
00038     launchEventTypes[1].eventKind  = kEventAppTerminated;
00039     
00040     EventHandlerUPP launchTerminationEventHandler =
00041         NewEventHandlerUPP(launchTerminationCallback);
00042     InstallApplicationEventHandler(launchTerminationEventHandler, 2,
00043                                 launchEventTypes, this,
00044                                 &m_launchTerminationEventHandlerRef);
00045     DisposeEventHandlerUPP(launchTerminationEventHandler);
00046     
00047     m_screenSaverPSN.highLongOfPSN = 0;
00048     m_screenSaverPSN.lowLongOfPSN  = 0;
00049 
00050     // test if screensaver is running and find process number
00051     if (isActive()) {
00052         ProcessInfoRec  procInfo;
00053         Str31           procName;   // pascal string. first byte holds length.
00054         memset(&procInfo, 0, sizeof(procInfo));
00055         procInfo.processName       = procName;
00056         procInfo.processInfoLength = sizeof(ProcessInfoRec);
00057 
00058         ProcessSerialNumber psn;
00059         OSErr err = GetNextProcess(&psn);
00060         while (err == 0) {
00061             memset(procName, 0, sizeof(procName));
00062             err = GetProcessInformation(&psn, &procInfo);
00063             if (err != 0) {
00064                 break;
00065             }
00066             if (strcmp("ScreenSaverEngine", (const char*)&procName[1]) == 0) {
00067                 m_screenSaverPSN = psn;
00068                 break;
00069             }
00070             err = GetNextProcess(&psn);
00071         }
00072     }
00073 }
00074 
00075 COSXScreenSaver::~COSXScreenSaver()
00076 {
00077     RemoveEventHandler(m_launchTerminationEventHandlerRef);
00078 //  screenSaverUtilReleaseController(m_screenSaverController);
00079     screenSaverUtilReleasePool(m_autoReleasePool);
00080 }
00081 
00082 void
00083 COSXScreenSaver::enable()
00084 {
00085     m_enabled = true;
00086     screenSaverUtilEnable(m_screenSaverController);
00087 }
00088 
00089 void
00090 COSXScreenSaver::disable()
00091 {
00092     m_enabled = false;
00093     screenSaverUtilDisable(m_screenSaverController);
00094 }
00095 
00096 void
00097 COSXScreenSaver::activate()
00098 {
00099     screenSaverUtilActivate(m_screenSaverController);
00100 }
00101 
00102 void
00103 COSXScreenSaver::deactivate()
00104 {
00105     screenSaverUtilDeactivate(m_screenSaverController, m_enabled);
00106 }
00107 
00108 bool
00109 COSXScreenSaver::isActive() const
00110 {
00111     return (screenSaverUtilIsActive(m_screenSaverController) != 0);
00112 }
00113 
00114 void
00115 COSXScreenSaver::processLaunched(ProcessSerialNumber psn)
00116 {
00117     CFStringRef processName;
00118     OSStatus    err = CopyProcessName(&psn, &processName);
00119     
00120     if (err == 0 && CFEqual(CFSTR("ScreenSaverEngine"), processName)) {
00121         m_screenSaverPSN = psn;
00122         LOG((CLOG_DEBUG1 "ScreenSaverEngine launched. Enabled=%d", m_enabled));
00123         if (m_enabled) {
00124             EVENTQUEUE->addEvent(
00125                 CEvent(IPrimaryScreen::getScreensaverActivatedEvent(),
00126                     m_eventTarget));
00127         }
00128     }
00129 }
00130 
00131 void
00132 COSXScreenSaver::processTerminated(ProcessSerialNumber psn)
00133 {
00134     if (m_screenSaverPSN.highLongOfPSN == psn.highLongOfPSN &&
00135         m_screenSaverPSN.lowLongOfPSN  == psn.lowLongOfPSN) {
00136         LOG((CLOG_DEBUG1 "ScreenSaverEngine terminated. Enabled=%d", m_enabled));
00137         if (m_enabled) {
00138             EVENTQUEUE->addEvent(
00139                 CEvent(IPrimaryScreen::getScreensaverDeactivatedEvent(),
00140                     m_eventTarget));
00141         }
00142         
00143         m_screenSaverPSN.highLongOfPSN = 0;
00144         m_screenSaverPSN.lowLongOfPSN  = 0;
00145     }
00146 }
00147 
00148 pascal OSStatus
00149 COSXScreenSaver::launchTerminationCallback(
00150                 EventHandlerCallRef nextHandler,
00151                 EventRef theEvent, void* userData)
00152 {
00153     OSStatus        result;
00154     ProcessSerialNumber psn; 
00155     EventParamType  actualType;
00156     UInt32          actualSize;
00157 
00158     result = GetEventParameter(theEvent, kEventParamProcessID,
00159                                typeProcessSerialNumber, &actualType,
00160                                sizeof(psn), &actualSize, &psn);
00161 
00162     if ((result == noErr) &&
00163         (actualSize > 0) &&
00164         (actualType == typeProcessSerialNumber)) {
00165         COSXScreenSaver* screenSaver = (COSXScreenSaver*)userData;
00166         UInt32 eventKind = GetEventKind(theEvent);
00167         if (eventKind == kEventAppLaunched) {
00168             screenSaver->processLaunched(psn);
00169         }
00170         else if (eventKind == kEventAppTerminated) {
00171             screenSaver->processTerminated(psn);
00172         }
00173     }
00174     return (CallNextEventHandler(nextHandler, theEvent));
00175 }

Generated on Fri Nov 6 00:21:14 2009 for synergy-plus by  doxygen 1.3.9.1