// Routine to startup and install all the hooks and stuff BOOL vncDesktop::Startup() { KillScreenSaver(); if (!InitDesktop()) return FALSE; if (!InitBitmap()) return FALSE; if (!ThunkBitmapInfo()) return FALSE; EnableOptimisedBlits(); if (!SetPixFormat()) return FALSE; if (!SetPixShifts()) return FALSE; if (!SetPalette()) return FALSE; if (!InitWindow()) return FALSE; // Add the system hook /* if (!SetHooks( GetCurrentThreadId(), RFB_SCREEN_UPDATE, RFB_COPYRECT_UPDATE, RFB_MOUSE_UPDATE )) { //vnclog.Print(LL_INTERR, VNCLOG("failed to set system hooks\n")); // Switch on full screen polling, so they can see something, at least... m_server->PollFullScreen(TRUE); } else { //vnclog.Print(LL_INTERR, VNCLOG("set hooks OK\n")); } // Start up the keyboard and mouse filters SetKeyboardFilterHook(m_server->LocalInputsDisabled()); SetMouseFilterHook(m_server->LocalInputsDisabled()); */ m_server->PollFullScreen(TRUE); // Start a timer to handle Polling Mode. The timer will cause // an "idle" event once every quarter second, which is necessary if Polling // Mode is being used, to cause TriggerUpdate to be called. m_timerid = SetTimer(m_hwnd, 1, 250, NULL); // Initialise the buffer object m_buffer.SetDesktop(this); // Create the quarter-screen rectangle for polling m_qtrscreen = rfb::Rect(0, 0, m_bmrect.br.x, m_bmrect.br.y/4); // Everything is ok, so return TRUE return TRUE; }
// Returns new desired Animation Frequency (per second) or 0 for no change int CScreensaver::getSSMessage(char **theMessage, int* coveredFreq) { int newFrequency = TEXTLOGOFREQUENCY; *coveredFreq = 0; pid_t myPid; CC_STATE ccstate; OSStatus err; if (ScreenIsBlanked) { setSSMessageText(0); // No text message *theMessage = m_MessageText; return NOTEXTLOGOFREQUENCY; } CheckDualGPUStatus(); switch (saverState) { case SaverState_RelaunchCoreClient: err = initBOINCApp(); break; case SaverState_LaunchingCoreClient: if (m_wasAlreadyRunning) { setSSMessageText(ConnectingCCMsg); } else { setSSMessageText(LaunchingCCMsg); } myPid = FindProcessPID(NULL, m_CoreClientPID); if (myPid) { saverState = SaverState_CoreClientRunning; if (!rpc->init(NULL)) { // Initialize communications with Core Client m_bConnected = true; if (IsDualGPUMacbook) { ccstate.clear(); ccstate.global_prefs.init_bools(); int result = rpc->get_state(ccstate); if (!result) { OKToRunOnBatteries = ccstate.global_prefs.run_on_batteries; } else { OKToRunOnBatteries = false; } if (OKToRunOnBatteries) { SetDiscreteGPU(true); } } } // Set up a separate thread for communicating with Core Client // and running screensaver graphics CreateDataManagementThread(); // ToDo: Add a timeout after which we display error message } else // Take care of the possible race condition where the Core Client was in the // process of shutting down just as ScreenSaver started, so initBOINCApp() // found it already running but now it has shut down. if (m_wasAlreadyRunning) { // If we launched it, then just wait for it to start saverState = SaverState_RelaunchCoreClient; } break; case SaverState_CoreClientRunning: if (IsDualGPUMacbook && RunningOnBattery && !OKToRunOnBatteries) { setSSMessageText(RunningOnBatteryMsg); break; } // RPC called in DataManagementProc() setSSMessageText(ConnectingCCMsg); if (! m_bResetCoreState) { saverState = SaverState_ConnectedToCoreClient; } break; case SaverState_ConnectedToCoreClient: if (IsDualGPUMacbook && RunningOnBattery && !OKToRunOnBatteries) { setSSMessageText(RunningOnBatteryMsg); break; } switch (m_hrError) { case 0: setSSMessageText(ConnectedCCMsg); break; // No status response yet from DataManagementProc case SCRAPPERR_SCREENSAVERBLANKED: setSSMessageText(0); // No text message ScreenIsBlanked = true; if (IsDualGPUMacbook && (GPUSelectConnect != IO_OBJECT_NULL)) { IOServiceClose(GPUSelectConnect); GPUSelectConnect = IO_OBJECT_NULL; } break; #if 0 // Not currently used case SCRAPPERR_QUITSCREENSAVERREQUESTED: // setSSMessageText(BOINCExitedSaverMode); // Wait 1 second to allow ScreenSaver engine to close us down if (++gQuitCounter > (m_MessageText[0] ? TEXTLOGOFREQUENCY : NOTEXTLOGOFREQUENCY)) { closeBOINCSaver(); KillScreenSaver(); // Stop the ScreenSaver Engine } break; #endif case SCRAPPERR_CANTLAUNCHDEFAULTGFXAPP: setSSMessageText(CantLaunchDefaultGFXAppMsg); break; case SCRAPPERR_DEFAULTGFXAPPCANTCONNECT: setSSMessageText(DefaultGFXAppCantRPCMsg); break; case SCRAPPERR_DEFAULTGFXAPPCRASHED: setSSMessageText(DefaultGFXAppCrashedMsg); break; default: // m_bErrorMode is TRUE if we should display moving logo (no graphics app is running) // m_bErrorMode is FALSE if a graphics app was launched and has not exit if (! m_bErrorMode) { // NOTE: My tests seem to confirm that the top window is always the first // window returned by NSWindowList under OS 10.5 and the second window // returned by NSWindowList under OS 10.3.9 and OS 10.4. However, Apple's // documentation is unclear whether we can depend on this. So I have // added some safety by doing two things: // [1] Only use the NSWindowList test when we have started project or default // graphics. // [2] Assume that our window is covered 45 seconds after starting project // graphics even if the NSWindowList test did not indicate that is so. // // The -animateOneFrame method in Mac_SaverModuleView.m does the NSWindowList test // only if we return a non-zero value for coveredFreq. // // Tell the calling routine to set the frame rate to NOTEXTLOGOFREQUENCY if // NSWindowList indicates that science app graphics window has covered our window. *coveredFreq = NOTEXTLOGOFREQUENCY; if (m_iGraphicsStartingMsgCounter > 0) { // Show ScreenSaverAppStartingMsg for GFX_STARTING_MSG_DURATION seconds or until // NSWindowList indicates that science app graphics window has covered our window setSSMessageText(ScreenSaverAppStartingMsg); m_iGraphicsStartingMsgCounter--; } else { // Don't waste CPU cycles when the science app is drawing over our window setSSMessageText(0); // No text message } } // End if (! m_bErrorMode) break; // End default case of switch (m_hrError) } // end switch (m_hrError) break; // End case SaverState_ConnectedToCoreClient of switch (saverState) case SaverState_ControlPanelTestMode: setSSMessageText(BOINCTestModeMsg); break; case SaverState_UnrecoverableError: setSSMessageText(BOINCUnrecoverableErrorMsg); break; case SaverState_CantLaunchCoreClient: if (IsDualGPUMacbook && RunningOnBattery && !OKToRunOnBatteries) { setSSMessageText(RunningOnBatteryMsg); break; } setSSMessageText(CantLaunchCCMsg); // Set up a separate thread for running screensaver graphics // even if we can't communicate with core client CreateDataManagementThread(); break; case SaverState_Idle: break; // Should never get here; fixes compiler warning } // end switch (saverState) if (IsDualGPUMacbook && RunningOnBattery && !OKToRunOnBatteries) { if ((m_dwBlankScreen) && (time(0) > m_dwBlankTime) && (m_dwBlankTime > 0)) { setSSMessageText(0); // No text message ScreenIsBlanked = true; } } if (m_MessageText[0]) { newFrequency = TEXTLOGOFREQUENCY; } else { newFrequency = NOTEXTLOGOFREQUENCY; } *theMessage = m_MessageText; return newFrequency; }