• Main Page
  • Classes
  • Files
  • File List

COSXScreenSaver.cpp

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

Generated on Fri May 24 2013 00:00:04 for Synergy by  doxygen 1.7.1