2 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation on the rights to use, copy, modify, merge,
10 * publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * Rickard E. (Rik) Faith <faith@redhat.com>
35 * Provides DPMS support and unifies all DPMS and other screen-saver
36 * support in one file. If -dpms is given on the command line, or the
37 * Xdmx server is not compiled with DPMS support, then the DPMS extension
38 * does not work for clients, but DPMS on the backends is still disables
39 * (and restored at Xdmx server shutdown time).
42 #ifdef HAVE_DMX_CONFIG_H
43 #include <dmx-config.h>
53 #include "windowstr.h" /* For screenIsSaved */
54 #include <X11/extensions/dpms.h>
56 static unsigned long dpmsGeneration
= 0;
57 static Bool dpmsSupported
= TRUE
;
60 _dmxDPMSInit(DMXScreenInfo
* dmxScreen
)
62 int event_base
, error_base
;
64 CARD16 level
, standby
, suspend
, off
;
68 if (dpmsGeneration
!= serverGeneration
) {
69 dpmsSupported
= TRUE
; /* On unless a backend doesn't support it */
70 dpmsGeneration
= serverGeneration
;
74 if (DPMSDisabledSwitch
)
75 dpmsSupported
= FALSE
; /* -dpms turns off */
78 dmxScreen
->dpmsCapable
= 0;
80 if (!dmxScreen
->beDisplay
) {
81 dmxLogOutput(dmxScreen
,
82 "Cannot determine if DPMS supported (detached screen)\n");
83 dpmsSupported
= FALSE
;
87 if (!DPMSQueryExtension(dmxScreen
->beDisplay
, &event_base
, &error_base
)) {
88 dmxLogOutput(dmxScreen
, "DPMS not supported\n");
89 dpmsSupported
= FALSE
;
92 if (!DPMSGetVersion(dmxScreen
->beDisplay
, &major
, &minor
)) {
93 dmxLogOutput(dmxScreen
, "DPMS not supported\n");
94 dpmsSupported
= FALSE
;
97 if (!DPMSCapable(dmxScreen
->beDisplay
)) {
98 dmxLogOutput(dmxScreen
, "DPMS %d.%d (not DPMS capable)\n",
100 dpmsSupported
= FALSE
;
104 DPMSInfo(dmxScreen
->beDisplay
, &level
, &state
);
105 DPMSGetTimeouts(dmxScreen
->beDisplay
, &standby
, &suspend
, &off
);
106 DPMSSetTimeouts(dmxScreen
->beDisplay
, 0, 0, 0);
107 DPMSEnable(dmxScreen
->beDisplay
);
108 DPMSForceLevel(dmxScreen
->beDisplay
, DPMSModeOn
);
109 dmxScreen
->dpmsCapable
= 1;
110 dmxScreen
->dpmsEnabled
= ! !state
;
111 dmxScreen
->dpmsStandby
= standby
;
112 dmxScreen
->dpmsSuspend
= suspend
;
113 dmxScreen
->dpmsOff
= off
;
119 case DPMSModeStandby
:
122 case DPMSModeSuspend
:
133 dmxLogOutput(dmxScreen
,
134 "DPMS %d.%d (%s, %s, %d %d %d)\n",
135 major
, minor
, monitor
, state
? "enabled" : "disabled",
136 standby
, suspend
, off
);
139 /** Initialize DPMS support. We save the current settings and turn off
140 * DPMS. The settings are restored in #dmxDPMSTerm. */
142 dmxDPMSInit(DMXScreenInfo
* dmxScreen
)
144 int interval
, preferBlanking
, allowExposures
;
147 _dmxDPMSInit(dmxScreen
);
149 if (!dmxScreen
->beDisplay
)
152 /* Turn off screen saver */
153 XGetScreenSaver(dmxScreen
->beDisplay
, &dmxScreen
->savedTimeout
, &interval
,
154 &preferBlanking
, &allowExposures
);
155 XSetScreenSaver(dmxScreen
->beDisplay
, 0, interval
,
156 preferBlanking
, allowExposures
);
157 XResetScreenSaver(dmxScreen
->beDisplay
);
158 dmxSync(dmxScreen
, FALSE
);
161 /** Terminate DPMS support on \a dmxScreen. We restore the settings
162 * saved in #dmxDPMSInit. */
164 dmxDPMSTerm(DMXScreenInfo
* dmxScreen
)
166 int timeout
, interval
, preferBlanking
, allowExposures
;
168 if (!dmxScreen
->beDisplay
)
171 XGetScreenSaver(dmxScreen
->beDisplay
, &timeout
, &interval
,
172 &preferBlanking
, &allowExposures
);
173 XSetScreenSaver(dmxScreen
->beDisplay
, dmxScreen
->savedTimeout
, interval
,
174 preferBlanking
, allowExposures
);
175 if (dmxScreen
->dpmsCapable
) {
176 /* Restore saved state */
177 DPMSForceLevel(dmxScreen
->beDisplay
, DPMSModeOn
);
178 DPMSSetTimeouts(dmxScreen
->beDisplay
, dmxScreen
->dpmsStandby
,
179 dmxScreen
->dpmsSuspend
, dmxScreen
->dpmsOff
);
180 if (dmxScreen
->dpmsEnabled
)
181 DPMSEnable(dmxScreen
->beDisplay
);
183 DPMSDisable(dmxScreen
->beDisplay
);
185 dmxSync(dmxScreen
, FALSE
);
188 /** Called when activity is detected so that DPMS power-saving mode can
193 if (screenIsSaved
== SCREEN_SAVER_ON
)
194 dixSaveScreens(serverClient
, SCREEN_SAVER_OFF
, ScreenSaverReset
);
197 DPMSSet(serverClient
, 0);
202 /** This is called on each server generation. It should determine if
203 * DPMS is supported on all of the backends and, if so, return TRUE. */
207 return dpmsSupported
;
210 /** This is used by clients (e.g., xset) to set the DPMS level. */
212 DPMSSet(ClientPtr client
, int level
)
224 DPMSPowerLevel
= level
;
226 for (i
= 0; i
< dmxNumScreens
; i
++) {
227 DMXScreenInfo
*dmxScreen
= &dmxScreens
[i
];
229 if (dmxScreen
->beDisplay
) {
230 DPMSForceLevel(dmxScreen
->beDisplay
, level
);
231 dmxSync(dmxScreen
, FALSE
);