xref: /OK3568_Linux_fs/external/xserver/hw/xfree86/os-support/bsd/bsd_apm.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 #ifdef HAVE_XORG_CONFIG_H
2 #include <xorg-config.h>
3 #endif
4 
5 #include <X11/X.h>
6 #include "os.h"
7 #include "xf86.h"
8 #include "xf86Priv.h"
9 #define XF86_OS_PRIVS
10 #include "xf86_OSproc.h"
11 #include "xf86_OSlib.h"
12 
13 #include <machine/apmvar.h>
14 
15 #define APM_DEVICE "/dev/apm"
16 
17 static void *APMihPtr = NULL;
18 static void bsdCloseAPM(void);
19 
20 static struct {
21     u_int apmBsd;
22     pmEvent xf86;
23 } bsdToXF86Array[] = {
24     {APM_STANDBY_REQ, XF86_APM_SYS_STANDBY},
25     {APM_SUSPEND_REQ, XF86_APM_SYS_SUSPEND},
26     {APM_NORMAL_RESUME, XF86_APM_NORMAL_RESUME},
27     {APM_CRIT_RESUME, XF86_APM_CRITICAL_RESUME},
28     {APM_BATTERY_LOW, XF86_APM_LOW_BATTERY},
29     {APM_POWER_CHANGE, XF86_APM_POWER_STATUS_CHANGE},
30     {APM_UPDATE_TIME, XF86_APM_UPDATE_TIME},
31     {APM_CRIT_SUSPEND_REQ, XF86_APM_CRITICAL_SUSPEND},
32     {APM_USER_STANDBY_REQ, XF86_APM_USER_STANDBY},
33     {APM_USER_SUSPEND_REQ, XF86_APM_USER_SUSPEND},
34     {APM_SYS_STANDBY_RESUME, XF86_APM_STANDBY_RESUME},
35 #ifdef APM_CAPABILITY_CHANGE
36     {APM_CAPABILITY_CHANGE, XF86_APM_CAPABILITY_CHANGED},
37 #endif
38 };
39 
40 static pmEvent
bsdToXF86(int type)41 bsdToXF86(int type)
42 {
43     int i;
44 
45     for (i = 0; i < ARRAY_SIZE(bsdToXF86Array); i++) {
46         if (type == bsdToXF86Array[i].apmBsd) {
47             return bsdToXF86Array[i].xf86;
48         }
49     }
50     return XF86_APM_UNKNOWN;
51 }
52 
53 /*
54  * APM events can be requested direclty from /dev/apm
55  */
56 static int
bsdPMGetEventFromOS(int fd,pmEvent * events,int num)57 bsdPMGetEventFromOS(int fd, pmEvent * events, int num)
58 {
59     struct apm_event_info bsdEvent;
60     int i;
61 
62     for (i = 0; i < num; i++) {
63 
64         if (ioctl(fd, APM_IOC_NEXTEVENT, &bsdEvent) < 0) {
65             if (errno != EAGAIN) {
66                 xf86Msg(X_WARNING, "bsdPMGetEventFromOS: APM_IOC_NEXTEVENT"
67                         " %s\n", strerror(errno));
68             }
69             break;
70         }
71         events[i] = bsdToXF86(bsdEvent.type);
72     }
73     return i;
74 }
75 
76 /*
77  * XXX This won't work on /dev/apm !
78  *     We should either use /dev/apm_ctl (and kill apmd(8))
79  *     or talk to apmd (but its protocol is not publically available)...
80  */
81 static pmWait
bsdPMConfirmEventToOs(int fd,pmEvent event)82 bsdPMConfirmEventToOs(int fd, pmEvent event)
83 {
84     switch (event) {
85     case XF86_APM_SYS_STANDBY:
86     case XF86_APM_USER_STANDBY:
87         if (ioctl(fd, APM_IOC_STANDBY, NULL) == 0)
88             return PM_WAIT;     /* should we stop the Xserver in standby, too? */
89         else
90             return PM_NONE;
91     case XF86_APM_SYS_SUSPEND:
92     case XF86_APM_CRITICAL_SUSPEND:
93     case XF86_APM_USER_SUSPEND:
94         if (ioctl(fd, APM_IOC_SUSPEND, NULL) == 0)
95             return PM_WAIT;
96         else
97             return PM_NONE;
98     case XF86_APM_STANDBY_RESUME:
99     case XF86_APM_NORMAL_RESUME:
100     case XF86_APM_CRITICAL_RESUME:
101     case XF86_APM_STANDBY_FAILED:
102     case XF86_APM_SUSPEND_FAILED:
103         return PM_CONTINUE;
104     default:
105         return PM_NONE;
106     }
107 }
108 
109 PMClose
xf86OSPMOpen(void)110 xf86OSPMOpen(void)
111 {
112     int fd;
113 
114     if (APMihPtr || !xf86Info.pmFlag) {
115         return NULL;
116     }
117 
118     if ((fd = open(APM_DEVICE, O_RDWR)) == -1) {
119         return NULL;
120     }
121     xf86PMGetEventFromOs = bsdPMGetEventFromOS;
122     xf86PMConfirmEventToOs = bsdPMConfirmEventToOs;
123     APMihPtr = xf86AddGeneralHandler(fd, xf86HandlePMEvents, NULL);
124     return bsdCloseAPM;
125 }
126 
127 static void
bsdCloseAPM(void)128 bsdCloseAPM(void)
129 {
130     int fd;
131 
132     if (APMihPtr) {
133         fd = xf86RemoveGeneralHandler(APMihPtr);
134         close(fd);
135         APMihPtr = NULL;
136     }
137 }
138