• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //    http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "sleep.h"
18 #include "utility.h"
19 
20 #if defined(__APPLE__)
21 #include <IOKit/pwr_mgt/IOPMLib.h>
22 #include <IOKit/IOMessage.h>
23 
24 struct
25 {
26     io_connect_t connection;
27     IONotificationPortRef port;
28     io_object_t iterator;
29 } sleepInfo;
30 
31 void sleepCallback(void* refcon, io_service_t service, natural_t messageType,
32                    void* messageArgument);
33 
sleepCallback(void * refcon UNUSED,io_service_t service UNUSED,natural_t messageType,void * messageArgument)34 void sleepCallback(void* refcon UNUSED, io_service_t service UNUSED,
35                    natural_t messageType, void* messageArgument)
36 {
37 
38     IOReturn result;
39     /*
40     service -- The IOService whose state has changed.
41     messageType -- A messageType enum, defined by IOKit/IOMessage.h or by the
42     IOService's family. messageArgument -- An argument for the message,
43     dependent on the messageType.
44     */
45     switch (messageType)
46     {
47         case kIOMessageSystemWillSleep:
48             // Handle demand sleep (such as sleep caused by running out of
49             // batteries, closing the lid of a laptop, or selecting
50             // sleep from the Apple menu.
51             IOAllowPowerChange(sleepInfo.connection, (long)messageArgument);
52             vlog("Hard sleep occurred.\n");
53             break;
54         case kIOMessageCanSystemSleep:
55             // In this case, the computer has been idle for several minutes
56             // and will sleep soon so you must either allow or cancel
57             // this notification. Important: if you don’t respond, there will
58             // be a 30-second timeout before the computer sleeps.
59             // IOCancelPowerChange(root_port,(long)messageArgument);
60             result = IOCancelPowerChange(sleepInfo.connection,
61                                          (long)messageArgument);
62             if (kIOReturnSuccess != result)
63                 vlog("sleep prevention failed. (%d)\n", result);
64             break;
65         case kIOMessageSystemHasPoweredOn:
66             // Handle wakeup.
67             break;
68     }
69 }
70 #endif
71 
72 
PreventSleep(void)73 void PreventSleep(void)
74 {
75 #if defined(__APPLE__)
76     vlog("Disabling sleep... ");
77     sleepInfo.iterator = (io_object_t)0;
78     sleepInfo.port = NULL;
79     sleepInfo.connection = IORegisterForSystemPower(
80         &sleepInfo, // void * refcon,
81         &sleepInfo.port, // IONotificationPortRef * thePortRef,
82         sleepCallback, // IOServiceInterestCallback callback,
83         &sleepInfo.iterator // io_object_t * notifier
84     );
85 
86     if ((io_connect_t)0 == sleepInfo.connection)
87         vlog("failed.\n");
88     else
89         vlog("done.\n");
90 
91     CFRunLoopAddSource(CFRunLoopGetCurrent(),
92                        IONotificationPortGetRunLoopSource(sleepInfo.port),
93                        kCFRunLoopDefaultMode);
94 #else
95     vlog("*** PreventSleep() is not implemented on this platform.\n");
96 #endif
97 }
98 
ResumeSleep(void)99 void ResumeSleep(void)
100 {
101 #if defined(__APPLE__)
102     IOReturn result = IODeregisterForSystemPower(&sleepInfo.iterator);
103     if (0 != result)
104         vlog("Got error %d restoring sleep \n", result);
105     else
106         vlog("Sleep restored.\n");
107 #else
108     vlog("*** ResumeSleep() is not implemented on this platform.\n");
109 #endif
110 }
111