xf86PM.c revision 35c4bbdf
1/* 2 * Copyright (c) 2000-2002 by The XFree86 Project, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Except as contained in this notice, the name of the copyright holder(s) 23 * and author(s) shall not be used in advertising or otherwise to promote 24 * the sale, use or other dealings in this Software without prior written 25 * authorization from the copyright holder(s) and author(s). 26 */ 27 28#ifdef HAVE_XORG_CONFIG_H 29#include <xorg-config.h> 30#endif 31 32#include <X11/X.h> 33#include "xf86.h" 34#include "xf86Priv.h" 35#include "xf86Xinput.h" 36#include "xf86_OSproc.h" 37 38int (*xf86PMGetEventFromOs) (int fd, pmEvent * events, int num) = NULL; 39pmWait (*xf86PMConfirmEventToOs) (int fd, pmEvent event) = NULL; 40 41static Bool suspended = FALSE; 42 43static int 44eventName(pmEvent event, const char **str) 45{ 46 switch (event) { 47 case XF86_APM_SYS_STANDBY: 48 *str = "System Standby Request"; 49 return 0; 50 case XF86_APM_SYS_SUSPEND: 51 *str = "System Suspend Request"; 52 return 0; 53 case XF86_APM_CRITICAL_SUSPEND: 54 *str = "Critical Suspend"; 55 return 0; 56 case XF86_APM_USER_STANDBY: 57 *str = "User System Standby Request"; 58 return 0; 59 case XF86_APM_USER_SUSPEND: 60 *str = "User System Suspend Request"; 61 return 0; 62 case XF86_APM_STANDBY_RESUME: 63 *str = "System Standby Resume"; 64 return 0; 65 case XF86_APM_NORMAL_RESUME: 66 *str = "Normal Resume System"; 67 return 0; 68 case XF86_APM_CRITICAL_RESUME: 69 *str = "Critical Resume System"; 70 return 0; 71 case XF86_APM_LOW_BATTERY: 72 *str = "Battery Low"; 73 return 3; 74 case XF86_APM_POWER_STATUS_CHANGE: 75 *str = "Power Status Change"; 76 return 3; 77 case XF86_APM_UPDATE_TIME: 78 *str = "Update Time"; 79 return 3; 80 case XF86_APM_CAPABILITY_CHANGED: 81 *str = "Capability Changed"; 82 return 3; 83 case XF86_APM_STANDBY_FAILED: 84 *str = "Standby Request Failed"; 85 return 0; 86 case XF86_APM_SUSPEND_FAILED: 87 *str = "Suspend Request Failed"; 88 return 0; 89 default: 90 *str = "Unknown Event"; 91 return 0; 92 } 93} 94 95static void 96suspend(pmEvent event, Bool undo) 97{ 98 int i; 99 InputInfoPtr pInfo; 100 101 for (i = 0; i < xf86NumScreens; i++) { 102 if (xf86Screens[i]->EnableDisableFBAccess) 103 (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], FALSE); 104 } 105 pInfo = xf86InputDevs; 106 while (pInfo) { 107 DisableDevice(pInfo->dev, TRUE); 108 pInfo = pInfo->next; 109 } 110 OsBlockSIGIO(); 111 for (i = 0; i < xf86NumScreens; i++) { 112 if (xf86Screens[i]->PMEvent) 113 xf86Screens[i]->PMEvent(xf86Screens[i], event, undo); 114 else { 115 xf86Screens[i]->LeaveVT(xf86Screens[i]); 116 xf86Screens[i]->vtSema = FALSE; 117 } 118 } 119 xf86AccessLeave(); 120 121} 122 123static void 124resume(pmEvent event, Bool undo) 125{ 126 int i; 127 InputInfoPtr pInfo; 128 129 xf86AccessEnter(); 130 for (i = 0; i < xf86NumScreens; i++) { 131 if (xf86Screens[i]->PMEvent) 132 xf86Screens[i]->PMEvent(xf86Screens[i], event, undo); 133 else { 134 xf86Screens[i]->vtSema = TRUE; 135 xf86Screens[i]->EnterVT(xf86Screens[i]); 136 } 137 } 138 OsReleaseSIGIO(); 139 for (i = 0; i < xf86NumScreens; i++) { 140 if (xf86Screens[i]->EnableDisableFBAccess) 141 (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE); 142 } 143 dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset); 144 pInfo = xf86InputDevs; 145 while (pInfo) { 146 EnableDevice(pInfo->dev, TRUE); 147 pInfo = pInfo->next; 148 } 149} 150 151static void 152DoApmEvent(pmEvent event, Bool undo) 153{ 154 int i; 155 156 switch (event) { 157#if 0 158 case XF86_APM_SYS_STANDBY: 159 case XF86_APM_USER_STANDBY: 160#endif 161 case XF86_APM_SYS_SUSPEND: 162 case XF86_APM_CRITICAL_SUSPEND: /*do we want to delay a critical suspend? */ 163 case XF86_APM_USER_SUSPEND: 164 /* should we do this ? */ 165 if (!undo && !suspended) { 166 suspend(event, undo); 167 suspended = TRUE; 168 } 169 else if (undo && suspended) { 170 resume(event, undo); 171 suspended = FALSE; 172 } 173 break; 174#if 0 175 case XF86_APM_STANDBY_RESUME: 176#endif 177 case XF86_APM_NORMAL_RESUME: 178 case XF86_APM_CRITICAL_RESUME: 179 if (suspended) { 180 resume(event, undo); 181 suspended = FALSE; 182 } 183 break; 184 default: 185 OsBlockSIGIO(); 186 for (i = 0; i < xf86NumScreens; i++) { 187 if (xf86Screens[i]->PMEvent) { 188 xf86Screens[i]->PMEvent(xf86Screens[i], event, undo); 189 } 190 } 191 OsReleaseSIGIO(); 192 break; 193 } 194} 195 196#define MAX_NO_EVENTS 8 197 198void 199xf86HandlePMEvents(int fd, void *data) 200{ 201 pmEvent events[MAX_NO_EVENTS]; 202 int i, n; 203 Bool wait = FALSE; 204 205 if (!xf86PMGetEventFromOs) 206 return; 207 208 if ((n = xf86PMGetEventFromOs(fd, events, MAX_NO_EVENTS))) { 209 do { 210 for (i = 0; i < n; i++) { 211 const char *str = NULL; 212 int verb = eventName(events[i], &str); 213 214 xf86MsgVerb(X_INFO, verb, "PM Event received: %s\n", str); 215 DoApmEvent(events[i], FALSE); 216 switch (xf86PMConfirmEventToOs(fd, events[i])) { 217 case PM_WAIT: 218 wait = TRUE; 219 break; 220 case PM_CONTINUE: 221 wait = FALSE; 222 break; 223 case PM_FAILED: 224 DoApmEvent(events[i], TRUE); 225 wait = FALSE; 226 break; 227 default: 228 break; 229 } 230 } 231 if (wait) 232 n = xf86PMGetEventFromOs(fd, events, MAX_NO_EVENTS); 233 else 234 break; 235 } while (1); 236 } 237} 238