Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / os-support / bsd / bsd_apm.c
CommitLineData
a09e091a
JB
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
17static pointer APMihPtr = NULL;
18static void bsdCloseAPM(void);
19
20static 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#define numApmEvents (sizeof(bsdToXF86Array) / sizeof(bsdToXF86Array[0]))
41
42static pmEvent
43bsdToXF86(int type)
44{
45 int i;
46
47 for (i = 0; i < numApmEvents; i++) {
48 if (type == bsdToXF86Array[i].apmBsd) {
49 return bsdToXF86Array[i].xf86;
50 }
51 }
52 return XF86_APM_UNKNOWN;
53}
54
55/*
56 * APM events can be requested direclty from /dev/apm
57 */
58static int
59bsdPMGetEventFromOS(int fd, pmEvent * events, int num)
60{
61 struct apm_event_info bsdEvent;
62 int i;
63
64 for (i = 0; i < num; i++) {
65
66 if (ioctl(fd, APM_IOC_NEXTEVENT, &bsdEvent) < 0) {
67 if (errno != EAGAIN) {
68 xf86Msg(X_WARNING, "bsdPMGetEventFromOS: APM_IOC_NEXTEVENT"
69 " %s\n", strerror(errno));
70 }
71 break;
72 }
73 events[i] = bsdToXF86(bsdEvent.type);
74 }
75 return i;
76}
77
78/*
79 * XXX This won't work on /dev/apm !
80 * We should either use /dev/apm_ctl (and kill apmd(8))
81 * or talk to apmd (but its protocol is not publically available)...
82 */
83static pmWait
84bsdPMConfirmEventToOs(int fd, pmEvent event)
85{
86 switch (event) {
87 case XF86_APM_SYS_STANDBY:
88 case XF86_APM_USER_STANDBY:
89 if (ioctl(fd, APM_IOC_STANDBY, NULL) == 0)
90 return PM_WAIT; /* should we stop the Xserver in standby, too? */
91 else
92 return PM_NONE;
93 case XF86_APM_SYS_SUSPEND:
94 case XF86_APM_CRITICAL_SUSPEND:
95 case XF86_APM_USER_SUSPEND:
96 if (ioctl(fd, APM_IOC_SUSPEND, NULL) == 0)
97 return PM_WAIT;
98 else
99 return PM_NONE;
100 case XF86_APM_STANDBY_RESUME:
101 case XF86_APM_NORMAL_RESUME:
102 case XF86_APM_CRITICAL_RESUME:
103 case XF86_APM_STANDBY_FAILED:
104 case XF86_APM_SUSPEND_FAILED:
105 return PM_CONTINUE;
106 default:
107 return PM_NONE;
108 }
109}
110
111PMClose
112xf86OSPMOpen(void)
113{
114 int fd;
115
116 if (APMihPtr || !xf86Info.pmFlag) {
117 return NULL;
118 }
119
120 if ((fd = open(APM_DEVICE, O_RDWR)) == -1) {
121 return NULL;
122 }
123 xf86PMGetEventFromOs = bsdPMGetEventFromOS;
124 xf86PMConfirmEventToOs = bsdPMConfirmEventToOs;
125 APMihPtr = xf86AddGeneralHandler(fd, xf86HandlePMEvents, NULL);
126 return bsdCloseAPM;
127}
128
129static void
130bsdCloseAPM(void)
131{
132 int fd;
133
134 if (APMihPtr) {
135 fd = xf86RemoveGeneralHandler(APMihPtr);
136 close(fd);
137 APMihPtr = NULL;
138 }
139}