forked from nomi-san/parsec-vdd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
PowerEvents.cs
247 lines (238 loc) · 13.2 KB
/
PowerEvents.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
using System;
using System.Runtime.InteropServices;
namespace ParsecVDisplay
{
internal static class PowerEvents
{
static EventHandler<PowerBroadcastType> _powerModeChanged;
public static event EventHandler<PowerBroadcastType> PowerModeChanged
{
add
{
_powerModeChanged += value;
if (_powerEventHandler == IntPtr.Zero)
{
var result = Native.PowerRegisterSuspendResumeNotification(2, _dnsp, out _powerEventHandler);
if (result != 0)
throw new Exception("Failed To Register PowerSuspendResumeNotification");
}
}
remove
{
_powerModeChanged -= value;
if (_powerModeChanged == null)
{
if (Native.PowerUnregisterSuspendResumeNotification(_powerEventHandler) != 0)
throw new Exception("Failed To Unregister PowerSuspendResumeNotification");
_powerEventHandler = IntPtr.Zero;
}
}
}
static IntPtr _powerEventHandler;
static Native.DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS _dnsp = new Native.DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS
{
Callback = OnDeviceNotify,
Context = IntPtr.Zero
};
static uint OnDeviceNotify(IntPtr context, uint type, IntPtr setting)
{
_powerModeChanged?.Invoke(null, (PowerBroadcastType)type);
return 0;
}
public enum PowerBroadcastType
{
PBT_APMQUERYSUSPEND = 0,
//
// Summary:
// The PBT_APMQUERYSUSPEND message is sent to request permission to suspend the
// computer. An application that grants permission should carry out preparations
// for the suspension before returning. Return TRUE to grant the request to suspend.
// To deny the request, return BROADCAST_QUERY_DENY.
PBT_APMQUERYSTANDBY = 1,
//
// Summary:
// [PBT_APMQUERYSUSPENDFAILED is available for use in the operating systems specified
// in the Requirements section. Support for this event was removed in Windows Vista.
// Use SetThreadExecutionState instead.]
// Notifies applications that permission to suspend the computer was denied. This
// event is broadcast if any application or driver returned BROADCAST_QUERY_DENY
// to a previous PBT_APMQUERYSUSPEND event.
// A window receives this event through the WM_POWERBROADCAST message. The wParam
// and lParam parameters are set as described following.
//
// Remarks:
// lParam: Reserved; must be zero.
// No return value.
// Applications typically respond to this event by resuming normal operation.
PBT_APMQUERYSUSPENDFAILED = 2,
//
// Summary:
// The PBT_APMQUERYSUSPENDFAILED message is sent to notify the application that
// suspension was denied by some other application. However, this message is only
// sent when we receive PBT_APMQUERY* before.
PBT_APMQUERYSTANDBYFAILED = 3,
//
// Summary:
// Notifies applications that the computer is about to enter a suspended state.
// This event is typically broadcast when all applications and installable drivers
// have returned TRUE to a previous PBT_APMQUERYSUSPEND event.
// A window receives this event through the WM_POWERBROADCAST message. The wParam
// and lParam parameters are set as described following.
//
// Remarks:
// lParam: Reserved; must be zero.
// No return value.
// An application should process this event by completing all tasks necessary to
// save data.
// The system allows approximately two seconds for an application to handle this
// notification. If an application is still performing operations after its time
// allotment has expired, the system may interrupt the application.
PBT_APMSUSPEND = 4,
//
// Summary:
// Undocumented.
PBT_APMSTANDBY = 5,
//
// Summary:
// [PBT_APMRESUMECRITICAL is available for use in the operating systems specified
// in the Requirements section. Support for this event was removed in Windows Vista.
// Use PBT_APMRESUMEAUTOMATIC instead.]
// Notifies applications that the system has resumed operation. This event can indicate
// that some or all applications did not receive a PBT_APMSUSPEND event. For example,
// this event can be broadcast after a critical suspension caused by a failing battery.
// A window receives this event through the WM_POWERBROADCAST message. The wParam
// and lParam parameters are set as described following.
//
// Remarks:
// lParam: Reserved; must be zero.
// No return value.
// Because a critical suspension occurs without prior notification, resources and
// data previously available may not be present when the application receives this
// event. The application should attempt to restore its state to the best of its
// ability. While in a critical suspension, the system maintains the state of the
// DRAM and local hard disks, but may not maintain net connections. An application
// may need to take action with respect to files that were open on the network before
// critical suspension.
PBT_APMRESUMECRITICAL = 6,
//
// Summary:
// Notifies applications that the system has resumed operation after being suspended.
// A window receives this event through the WM_POWERBROADCAST message. The wParam
// and lParam parameters are set as described following.
//
// Remarks:
// lParam: Reserved; must be zero.
// No return value.
// An application can receive this event only if it received the PBT_APMSUSPEND
// event before the computer was suspended. Otherwise, the application will receive
// a PBT_APMRESUMECRITICAL event.
// If the system wakes due to user activity (such as pressing the power button)
// or if the system detects user interaction at the physical console (such as mouse
// or keyboard input) after waking unattended, the system first broadcasts the PBT_APMRESUMEAUTOMATIC
// event, then it broadcasts the PBT_APMRESUMESUSPEND event. In addition, the system
// turns on the display. Your application should reopen files that it closed when
// the system entered sleep and prepare for user input.
// If the system wakes due to an external wake signal (remote wake), the system
// broadcasts only the PBT_APMRESUMEAUTOMATIC event. The PBT_APMRESUMESUSPEND event
// is not sent.
PBT_APMRESUMESUSPEND = 7,
//
// Summary:
// The PBT_APMRESUMESTANDBY event is broadcast as a notification that the system
// has resumed operation after being standby.
PBT_APMRESUMESTANDBY = 8,
//
// Summary:
// [PBT_APMBATTERYLOW is available for use in the operating systems specified in
// the Requirements section. Support for this event was removed in Windows Vista.
// Use PBT_APMPOWERSTATUSCHANGE instead.]
// Notifies applications that the battery power is low.
// A window receives this event through the WM_POWERBROADCAST message. The wParam
// and lParam parameters are set as described following.
//
// Remarks:
// lParam: Reserved, must be zero.
// No return value.
// This event is broadcast when a system's APM BIOS signals an APM battery low notification.
// Because some APM BIOS implementations do not provide notifications when batteries
// are low, this event may never be broadcast on some computers.
PBT_APMBATTERYLOW = 9,
//
// Summary:
// Notifies applications of a change in the power status of the computer, such as
// a switch from battery power to A/C. The system also broadcasts this event when
// remaining battery power slips below the threshold specified by the user or if
// the battery power changes by a specified percentage.
// A window receives this event through the WM_POWERBROADCAST message. The wParam
// and lParam parameters are set as described following.
//
// Remarks:
// lParam: Reserved; must be zero.
// No return value.
// An application should process this event by calling the GetSystemPowerStatus
// function to retrieve the current power status of the computer. In particular,
// the application should check the ACLineStatus, BatteryFlag, BatteryLifeTime,
// and BatteryLifePercent members of the SYSTEM_POWER_STATUS structure for any changes.
// This event can occur when battery life drops to less than 5 minutes, or when
// the percentage of battery life drops below 10 percent, or if the battery life
// changes by 3 percent.
PBT_APMPOWERSTATUSCHANGE = 10,
//
// Summary:
// [PBT_APMOEMEVENT is available for use in the operating systems specified in the
// Requirements section. Support for this event was removed in Windows Vista.]
// Notifies applications that the APM BIOS has signaled an APM OEM event.
// A window receives this event through the WM_POWERBROADCAST message. The wParam
// and lParam parameters are set as described following.
//
// Remarks:
// lParam: The OEM-defined event code that was signaled by the system's APM BIOS.
// OEM event codes are in the range 0200h - 02FFh.
// No return value.
// Because not all APM BIOS implementations provide OEM event notifications, this
// event may never be broadcast on some computers.
PBT_APMOEMEVENT = 11,
//
// Summary:
// Notifies applications that the system is resuming from sleep or hibernation.
// This event is delivered every time the system resumes and does not indicate whether
// a user is present.
// A window receives this event through the WM_POWERBROADCAST message. The wParam
// and lParam parameters are set as described following.
//
// Remarks:
// lParam: Reserved; must be zero.
// No return value.
// If the system detects any user activity after broadcasting PBT_APMRESUMEAUTOMATIC,
// it will broadcast a PBT_APMRESUMESUSPEND event to let applications know they
// can resume full interaction with the user.
PBT_APMRESUMEAUTOMATIC = 18,
//
// Summary:
// Power setting change event sent with a WM_POWERBROADCAST window message or in
// a HandlerEx notification callback for services.
//
// Remarks:
// lParam: Pointer to a POWERBROADCAST_SETTING structure.
// No return value.
PBT_POWERSETTINGCHANGE = 32787,
ERROR_ERROR = 10101
}
static class Native
{
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate uint DeviceNotifyCallbackRoutine(IntPtr Context, uint Type, IntPtr Setting);
[StructLayout(LayoutKind.Sequential)]
public struct DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS
{
[MarshalAs(UnmanagedType.FunctionPtr)]
public DeviceNotifyCallbackRoutine Callback;
public IntPtr Context;
}
[DllImport("powrprof.dll", SetLastError = false, ExactSpelling = true)]
public static extern uint PowerRegisterSuspendResumeNotification(int Flags, in DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS Recipient, out IntPtr RegistrationHandle);
[DllImport("powrprof.dll", SetLastError = false, ExactSpelling = true)]
public static extern uint PowerUnregisterSuspendResumeNotification(IntPtr RegistrationHandle);
}
}
}