// // Copyright (c) 2017 The Khronos Group Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include "sleep.h" #include "utility.h" #if defined(__APPLE__) #include #include struct { io_connect_t connection; IONotificationPortRef port; io_object_t iterator; } sleepInfo; void sleepCallback(void* refcon, io_service_t service, natural_t messageType, void* messageArgument); void sleepCallback(void* refcon UNUSED, io_service_t service UNUSED, natural_t messageType, void* messageArgument) { IOReturn result; /* service -- The IOService whose state has changed. messageType -- A messageType enum, defined by IOKit/IOMessage.h or by the IOService's family. messageArgument -- An argument for the message, dependent on the messageType. */ switch (messageType) { case kIOMessageSystemWillSleep: // Handle demand sleep (such as sleep caused by running out of // batteries, closing the lid of a laptop, or selecting // sleep from the Apple menu. IOAllowPowerChange(sleepInfo.connection, (long)messageArgument); vlog("Hard sleep occurred.\n"); break; case kIOMessageCanSystemSleep: // In this case, the computer has been idle for several minutes // and will sleep soon so you must either allow or cancel // this notification. Important: if you don’t respond, there will // be a 30-second timeout before the computer sleeps. // IOCancelPowerChange(root_port,(long)messageArgument); result = IOCancelPowerChange(sleepInfo.connection, (long)messageArgument); if (kIOReturnSuccess != result) vlog("sleep prevention failed. (%d)\n", result); break; case kIOMessageSystemHasPoweredOn: // Handle wakeup. break; } } #endif void PreventSleep(void) { #if defined(__APPLE__) vlog("Disabling sleep... "); sleepInfo.iterator = (io_object_t)0; sleepInfo.port = NULL; sleepInfo.connection = IORegisterForSystemPower( &sleepInfo, // void * refcon, &sleepInfo.port, // IONotificationPortRef * thePortRef, sleepCallback, // IOServiceInterestCallback callback, &sleepInfo.iterator // io_object_t * notifier ); if ((io_connect_t)0 == sleepInfo.connection) vlog("failed.\n"); else vlog("done.\n"); CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(sleepInfo.port), kCFRunLoopDefaultMode); #else vlog("*** PreventSleep() is not implemented on this platform.\n"); #endif } void ResumeSleep(void) { #if defined(__APPLE__) IOReturn result = IODeregisterForSystemPower(&sleepInfo.iterator); if (0 != result) vlog("Got error %d restoring sleep \n", result); else vlog("Sleep restored.\n"); #else vlog("*** ResumeSleep() is not implemented on this platform.\n"); #endif }