1 /* $XFree86$ */ |
|
2 /* Copyright 2005 Sun Microsystems, Inc. All rights reserved. |
|
3 * |
|
4 * Permission is hereby granted, free of charge, to any person obtaining a |
|
5 * copy of this software and associated documentation files (the |
|
6 * "Software"), to deal in the Software without restriction, including |
|
7 * without limitation the rights to use, copy, modify, merge, publish, |
|
8 * distribute, and/or sell copies of the Software, and to permit persons |
|
9 * to whom the Software is furnished to do so, provided that the above |
|
10 * copyright notice(s) and this permission notice appear in all copies of |
|
11 * the Software and that both the above copyright notice(s) and this |
|
12 * permission notice appear in supporting documentation. |
|
13 * |
|
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT |
|
17 * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
|
18 * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL |
|
19 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING |
|
20 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
|
21 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
|
22 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
23 * |
|
24 * Except as contained in this notice, the name of a copyright holder |
|
25 * shall not be used in advertising or otherwise to promote the sale, use |
|
26 * or other dealings in this Software without prior written authorization |
|
27 * of the copyright holder. |
|
28 */ |
|
29 |
|
30 #ifdef HAVE_XORG_CONFIG_H |
|
31 #include <xorg-config.h> |
|
32 #endif |
|
33 |
|
34 #include <X11/X.h> |
|
35 #include "os.h" |
|
36 #include "xf86.h" |
|
37 #include "xf86Priv.h" |
|
38 #define XF86_OS_PRIVS |
|
39 #include "xf86_OSproc.h" |
|
40 #include "xf86_OSlib.h" |
|
41 |
|
42 #ifndef PLEASE_FIX_THIS |
|
43 #define APM_STANDBY_REQ 0xa01 |
|
44 #define APM_SUSPEND_REQ 0xa02 |
|
45 #define APM_NORMAL_RESUME 0xa03 |
|
46 #define APM_CRIT_RESUME 0xa04 |
|
47 #define APM_BATTERY_LOW 0xa05 |
|
48 #define APM_POWER_CHANGE 0xa06 |
|
49 #define APM_UPDATE_TIME 0xa07 |
|
50 #define APM_CRIT_SUSPEND_REQ 0xa08 |
|
51 #define APM_USER_STANDBY_REQ 0xa09 |
|
52 #define APM_USER_SUSPEND_REQ 0xa0a |
|
53 #define APM_SYS_STANDBY_RESUME 0xa0b |
|
54 #define APM_IOC_NEXTEVENT 0xa0c |
|
55 #define APM_IOC_RESUME 0xa0d |
|
56 #define APM_IOC_SUSPEND 0xa0e |
|
57 #define APM_IOC_STANDBY 0xa0f |
|
58 #endif |
|
59 |
|
60 typedef struct apm_event_info |
|
61 { |
|
62 int type; |
|
63 }apm_event_info; |
|
64 |
|
65 /* |
|
66 This may be replaced with a better device name |
|
67 very soon... |
|
68 */ |
|
69 #define APM_DEVICE "/dev/apm" |
|
70 #define APM_DEVICE1 "/dev/srn" |
|
71 |
|
72 static pointer APMihPtr = NULL; |
|
73 static void sunCloseAPM(void); |
|
74 |
|
75 static struct { |
|
76 u_int apmBsd; |
|
77 pmEvent xf86; |
|
78 } sunToXF86Array [] = { |
|
79 { APM_STANDBY_REQ, XF86_APM_SYS_STANDBY }, |
|
80 { APM_SUSPEND_REQ, XF86_APM_SYS_SUSPEND }, |
|
81 { APM_NORMAL_RESUME, XF86_APM_NORMAL_RESUME }, |
|
82 { APM_CRIT_RESUME, XF86_APM_CRITICAL_RESUME }, |
|
83 { APM_BATTERY_LOW, XF86_APM_LOW_BATTERY }, |
|
84 { APM_POWER_CHANGE, XF86_APM_POWER_STATUS_CHANGE }, |
|
85 { APM_UPDATE_TIME, XF86_APM_UPDATE_TIME }, |
|
86 { APM_CRIT_SUSPEND_REQ, XF86_APM_CRITICAL_SUSPEND }, |
|
87 { APM_USER_STANDBY_REQ, XF86_APM_USER_STANDBY }, |
|
88 { APM_USER_SUSPEND_REQ, XF86_APM_USER_SUSPEND }, |
|
89 { APM_SYS_STANDBY_RESUME, XF86_APM_STANDBY_RESUME }, |
|
90 #ifdef APM_CAPABILITY_CHANGE |
|
91 { APM_CAPABILITY_CHANGE, XF86_APM_CAPABILITY_CHANGED }, |
|
92 #endif |
|
93 }; |
|
94 |
|
95 #define numApmEvents (sizeof(sunToXF86Array) / sizeof(sunToXF86Array[0])) |
|
96 |
|
97 static pmEvent |
|
98 sunToXF86(int type) |
|
99 { |
|
100 int i; |
|
101 |
|
102 for (i = 0; i < numApmEvents; i++) { |
|
103 if (type == sunToXF86Array[i].apmBsd) { |
|
104 return sunToXF86Array[i].xf86; |
|
105 } |
|
106 } |
|
107 return XF86_APM_UNKNOWN; |
|
108 } |
|
109 |
|
110 /* |
|
111 * APM events can be requested direclty from /dev/apm |
|
112 */ |
|
113 static int |
|
114 sunPMGetEventFromOS(int fd, pmEvent *events, int num) |
|
115 { |
|
116 struct apm_event_info sunEvent; |
|
117 int i; |
|
118 |
|
119 for (i = 0; i < num; i++) { |
|
120 |
|
121 if (ioctl(fd, APM_IOC_NEXTEVENT, &sunEvent) < 0) { |
|
122 if (errno != EAGAIN) { |
|
123 xf86Msg(X_WARNING, "sunPMGetEventFromOS: APM_IOC_NEXTEVENT" |
|
124 " errno = %d\n", errno); |
|
125 } |
|
126 break; |
|
127 } |
|
128 events[i] = sunToXF86(sunEvent.type); |
|
129 } |
|
130 xf86Msg(X_WARNING, "Got some events\n"); |
|
131 return i; |
|
132 } |
|
133 |
|
134 /* |
|
135 * XXX This won't work on /dev/apm ! |
|
136 * We should either use /dev/apm_ctl (and kill apmd(8)) |
|
137 * or talk to apmd (but its protocol is not publically available)... |
|
138 */ |
|
139 static pmWait |
|
140 sunPMConfirmEventToOs(int fd, pmEvent event) |
|
141 { |
|
142 switch (event) { |
|
143 /* XXX: NOT CURRENTLY RETURNED FROM OS */ |
|
144 case XF86_APM_SYS_STANDBY: |
|
145 case XF86_APM_USER_STANDBY: |
|
146 if (ioctl( fd, APM_IOC_STANDBY, NULL ) == 0) |
|
147 return PM_WAIT; /* should we stop the Xserver in standby, too? */ |
|
148 else |
|
149 return PM_NONE; |
|
150 case XF86_APM_SYS_SUSPEND: |
|
151 case XF86_APM_CRITICAL_SUSPEND: |
|
152 case XF86_APM_USER_SUSPEND: |
|
153 xf86Msg(X_WARNING, "Got SUSPENDED\n"); |
|
154 if (ioctl( fd, APM_IOC_SUSPEND, NULL ) == 0) |
|
155 return PM_CONTINUE; |
|
156 else { |
|
157 xf86Msg(X_WARNING, "sunPMConfirmEventToOs: APM_IOC_SUSPEND" |
|
158 " errno = %d\n", errno); |
|
159 return PM_FAILED; |
|
160 } |
|
161 case XF86_APM_STANDBY_RESUME: |
|
162 case XF86_APM_NORMAL_RESUME: |
|
163 case XF86_APM_CRITICAL_RESUME: |
|
164 case XF86_APM_STANDBY_FAILED: |
|
165 case XF86_APM_SUSPEND_FAILED: |
|
166 xf86Msg(X_WARNING, "Got RESUME\n"); |
|
167 if (ioctl( fd, APM_IOC_RESUME, NULL ) == 0) |
|
168 return PM_CONTINUE; |
|
169 else { |
|
170 xf86Msg(X_WARNING, "sunPMConfirmEventToOs: APM_IOC_RESUME" |
|
171 " errno = %d\n", errno); |
|
172 return PM_FAILED; |
|
173 } |
|
174 default: |
|
175 return PM_NONE; |
|
176 } |
|
177 } |
|
178 |
|
179 PMClose |
|
180 xf86OSPMOpen(void) |
|
181 { |
|
182 int fd; |
|
183 |
|
184 if (APMihPtr || !xf86Info.pmFlag) { |
|
185 return NULL; |
|
186 } |
|
187 |
|
188 if ((fd = open(APM_DEVICE, O_RDWR)) == -1) { |
|
189 if ((fd = open(APM_DEVICE1, O_RDWR)) == -1) { |
|
190 return NULL; |
|
191 } |
|
192 } |
|
193 xf86PMGetEventFromOs = sunPMGetEventFromOS; |
|
194 xf86PMConfirmEventToOs = sunPMConfirmEventToOs; |
|
195 APMihPtr = xf86AddInputHandler(fd, xf86HandlePMEvents, NULL); |
|
196 return sunCloseAPM; |
|
197 } |
|
198 |
|
199 static void |
|
200 sunCloseAPM(void) |
|
201 { |
|
202 int fd; |
|
203 |
|
204 if (APMihPtr) { |
|
205 fd = xf86RemoveInputHandler(APMihPtr); |
|
206 close(fd); |
|
207 APMihPtr = NULL; |
|
208 } |
|
209 } |
|