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