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
;
59 static void _dmxDPMSInit(DMXScreenInfo
*dmxScreen
)
61 int event_base
, error_base
;
63 CARD16 level
, standby
, suspend
, off
;
67 if (dpmsGeneration
!= serverGeneration
) {
68 dpmsSupported
= TRUE
; /* On unless a backend doesn't support it */
69 dpmsGeneration
= serverGeneration
;
73 if (DPMSDisabledSwitch
) dpmsSupported
= FALSE
; /* -dpms turns off */
76 dmxScreen
->dpmsCapable
= 0;
78 if (!dmxScreen
->beDisplay
) {
79 dmxLogOutput(dmxScreen
,
80 "Cannot determine if DPMS supported (detached screen)\n");
81 dpmsSupported
= FALSE
;
85 if (!DPMSQueryExtension(dmxScreen
->beDisplay
,
86 &event_base
, &error_base
)) {
87 dmxLogOutput(dmxScreen
, "DPMS not supported\n");
88 dpmsSupported
= FALSE
;
91 if (!DPMSGetVersion(dmxScreen
->beDisplay
, &major
, &minor
)) {
92 dmxLogOutput(dmxScreen
, "DPMS not supported\n");
93 dpmsSupported
= FALSE
;
96 if (!DPMSCapable(dmxScreen
->beDisplay
)) {
97 dmxLogOutput(dmxScreen
, "DPMS %d.%d (not DPMS capable)\n",
99 dpmsSupported
= FALSE
;
103 DPMSInfo(dmxScreen
->beDisplay
, &level
, &state
);
104 DPMSGetTimeouts(dmxScreen
->beDisplay
, &standby
, &suspend
, &off
);
105 DPMSSetTimeouts(dmxScreen
->beDisplay
, 0, 0, 0);
106 DPMSEnable(dmxScreen
->beDisplay
);
107 DPMSForceLevel(dmxScreen
->beDisplay
, DPMSModeOn
);
108 dmxScreen
->dpmsCapable
= 1;
109 dmxScreen
->dpmsEnabled
= !!state
;
110 dmxScreen
->dpmsStandby
= standby
;
111 dmxScreen
->dpmsSuspend
= suspend
;
112 dmxScreen
->dpmsOff
= off
;
115 case DPMSModeOn
: monitor
= "on"; break;
116 case DPMSModeStandby
: monitor
= "standby"; break;
117 case DPMSModeSuspend
: monitor
= "suspend"; break;
118 case DPMSModeOff
: monitor
= "off"; break;
119 default: monitor
= "unknown"; break;
122 dmxLogOutput(dmxScreen
,
123 "DPMS %d.%d (%s, %s, %d %d %d)\n",
124 major
, minor
, monitor
, state
? "enabled" : "disabled",
125 standby
, suspend
, off
);
128 /** Initialize DPMS support. We save the current settings and turn off
129 * DPMS. The settings are restored in #dmxDPMSTerm. */
130 void dmxDPMSInit(DMXScreenInfo
*dmxScreen
)
132 int interval
, preferBlanking
, allowExposures
;
135 _dmxDPMSInit(dmxScreen
);
137 if (!dmxScreen
->beDisplay
)
140 /* Turn off screen saver */
141 XGetScreenSaver(dmxScreen
->beDisplay
, &dmxScreen
->savedTimeout
, &interval
,
142 &preferBlanking
, &allowExposures
);
143 XSetScreenSaver(dmxScreen
->beDisplay
, 0, interval
,
144 preferBlanking
, allowExposures
);
145 XResetScreenSaver(dmxScreen
->beDisplay
);
146 dmxSync(dmxScreen
, FALSE
);
149 /** Terminate DPMS support on \a dmxScreen. We restore the settings
150 * saved in #dmxDPMSInit. */
151 void dmxDPMSTerm(DMXScreenInfo
*dmxScreen
)
153 int timeout
, interval
, preferBlanking
, allowExposures
;
155 if (!dmxScreen
->beDisplay
)
158 XGetScreenSaver(dmxScreen
->beDisplay
, &timeout
, &interval
,
159 &preferBlanking
, &allowExposures
);
160 XSetScreenSaver(dmxScreen
->beDisplay
, dmxScreen
->savedTimeout
, interval
,
161 preferBlanking
, allowExposures
);
162 if (dmxScreen
->dpmsCapable
) {
163 /* Restore saved state */
164 DPMSForceLevel(dmxScreen
->beDisplay
, DPMSModeOn
);
165 DPMSSetTimeouts(dmxScreen
->beDisplay
, dmxScreen
->dpmsStandby
,
166 dmxScreen
->dpmsSuspend
, dmxScreen
->dpmsOff
);
167 if (dmxScreen
->dpmsEnabled
) DPMSEnable(dmxScreen
->beDisplay
);
168 else DPMSDisable(dmxScreen
->beDisplay
);
170 dmxSync(dmxScreen
, FALSE
);
173 /** Called when activity is detected so that DPMS power-saving mode can
175 void dmxDPMSWakeup(void)
177 if (screenIsSaved
== SCREEN_SAVER_ON
)
178 SaveScreens(SCREEN_SAVER_OFF
, ScreenSaverReset
);
180 if (DPMSPowerLevel
) DPMSSet(0);
185 /** This is called on each server generation. It should determine if
186 * DPMS is supported on all of the backends and, if so, return TRUE. */
187 Bool
DPMSSupported(void)
189 return dpmsSupported
;
192 /** This is used by clients (e.g., xset) to set the DPMS level. */
193 void DPMSSet(int level
)
197 if (!dpmsSupported
) return;
199 if (level
< 0) level
= DPMSModeOn
;
200 if (level
> 3) level
= DPMSModeOff
;
202 DPMSPowerLevel
= level
;
204 for (i
= 0; i
< dmxNumScreens
; i
++) {
205 DMXScreenInfo
*dmxScreen
= &dmxScreens
[i
];
206 if (dmxScreen
->beDisplay
) {
207 DPMSForceLevel(dmxScreen
->beDisplay
, level
);
208 dmxSync(dmxScreen
, FALSE
);