Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / os-support / bsd / bsd_apm.c
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 pointer 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 #define numApmEvents (sizeof(bsdToXF86Array) / sizeof(bsdToXF86Array[0]))
41
42 static pmEvent
43 bsdToXF86(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 */
58 static int
59 bsdPMGetEventFromOS(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 */
83 static pmWait
84 bsdPMConfirmEventToOs(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
111 PMClose
112 xf86OSPMOpen(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
129 static void
130 bsdCloseAPM(void)
131 {
132 int fd;
133
134 if (APMihPtr) {
135 fd = xf86RemoveGeneralHandler(APMihPtr);
136 close(fd);
137 APMihPtr = NULL;
138 }
139 }