Imported Upstream version 1.11.4
[ubuntu-omap:xserver.git] / hw / xfree86 / common / xf86DPMS.c
1 /*
2  * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Except as contained in this notice, the name of the copyright holder(s)
23  * and author(s) shall not be used in advertising or otherwise to promote
24  * the sale, use or other dealings in this Software without prior written
25  * authorization from the copyright holder(s) and author(s).
26  */
27
28 /*
29  * This file contains the DPMS functions required by the extension.
30  */
31
32 #ifdef HAVE_XORG_CONFIG_H
33 #include <xorg-config.h>
34 #endif
35
36 #include <X11/X.h>
37 #include "os.h"
38 #include "globals.h"
39 #include "xf86.h"
40 #include "xf86Priv.h"
41 #ifdef DPMSExtension
42 #include <X11/extensions/dpmsconst.h>
43 #include "dpmsproc.h"
44 #endif
45 #include "xf86VGAarbiter.h"
46
47
48 #ifdef DPMSExtension
49 static DevPrivateKeyRec DPMSKeyRec;
50 static DevPrivateKey DPMSKey;
51 static Bool DPMSClose(int i, ScreenPtr pScreen);
52 static int DPMSCount = 0;
53 #endif
54
55
56 Bool
57 xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags)
58 {
59 #ifdef DPMSExtension
60     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
61     DPMSPtr pDPMS;
62     pointer DPMSOpt;
63     MessageType enabled_from;
64
65     DPMSKey = &DPMSKeyRec;
66
67     if (!dixRegisterPrivateKey(&DPMSKeyRec, PRIVATE_SCREEN, sizeof (DPMSRec)))
68         return FALSE;
69
70     pDPMS = dixLookupPrivate(&pScreen->devPrivates, DPMSKey);
71     pScrn->DPMSSet = set;
72     pDPMS->Flags = flags;
73     DPMSOpt = xf86FindOption(pScrn->options, "dpms");
74     if (DPMSDisabledSwitch) {
75         enabled_from = X_CMDLINE;
76         DPMSEnabled = FALSE;
77     }
78     else if (DPMSOpt) {
79         enabled_from = X_CONFIG;
80         DPMSEnabled = xf86CheckBoolOption(pScrn->options, "dpms", FALSE);
81         xf86MarkOptionUsed(DPMSOpt);
82     }
83     else {
84         enabled_from = X_DEFAULT;
85         DPMSEnabled = TRUE;
86     }
87     if (DPMSEnabled)
88         xf86DrvMsg(pScreen->myNum, enabled_from, "DPMS enabled\n");
89     pDPMS->Enabled = DPMSEnabled;
90     pDPMS->CloseScreen = pScreen->CloseScreen;
91     pScreen->CloseScreen = DPMSClose;
92     DPMSCount++;
93     return TRUE;
94 #else
95     return FALSE;
96 #endif
97 }
98
99
100 #ifdef DPMSExtension
101
102 static Bool
103 DPMSClose(int i, ScreenPtr pScreen)
104 {
105     DPMSPtr pDPMS;
106
107     /* This shouldn't happen */
108     if (DPMSKey == NULL)
109         return FALSE;
110
111     pDPMS = dixLookupPrivate(&pScreen->devPrivates, DPMSKey);
112
113     /* This shouldn't happen */
114     if (!pDPMS)
115         return FALSE;
116
117     pScreen->CloseScreen = pDPMS->CloseScreen;
118
119     /*
120      * Turn on DPMS when shutting down. If this function can be used
121      * depends on the order the driver wraps things. If this is called
122      * after the driver has shut down everything the driver will have
123      * to deal with this internally.
124      */
125     if (xf86Screens[i]->vtSema && xf86Screens[i]->DPMSSet) {
126         xf86Screens[i]->DPMSSet(xf86Screens[i],DPMSModeOn,0);
127     }
128     
129     if (--DPMSCount == 0)
130         DPMSKey = NULL;
131     return pScreen->CloseScreen(i, pScreen);
132 }
133
134
135 /*
136  * DPMSSet --
137  *      Device dependent DPMS mode setting hook.  This is called whenever
138  *      the DPMS mode is to be changed.
139  */
140 int
141 DPMSSet(ClientPtr client, int level)
142 {
143     int rc, i;
144     DPMSPtr pDPMS;
145     ScrnInfoPtr pScrn;
146
147     DPMSPowerLevel = level;
148
149     if (DPMSKey == NULL)
150         return Success;
151
152     if (level != DPMSModeOn) {
153         rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, ScreenSaverActive);
154         if (rc != Success)
155             return rc;
156     }
157
158     /* For each screen, set the DPMS level */
159     for (i = 0; i < xf86NumScreens; i++) {
160         pScrn = xf86Screens[i];
161         pDPMS = dixLookupPrivate(&screenInfo.screens[i]->devPrivates, DPMSKey);
162         if (pDPMS && pScrn->DPMSSet && pDPMS->Enabled && pScrn->vtSema) { 
163             xf86VGAarbiterLock(pScrn);
164             pScrn->DPMSSet(pScrn, level, 0);
165             xf86VGAarbiterUnlock(pScrn);
166         }
167     }
168     return Success;
169 }
170
171
172 /*
173  * DPMSSupported --
174  *      Return TRUE if any screen supports DPMS.
175  */
176 Bool
177 DPMSSupported(void)
178 {
179     int i;
180     DPMSPtr pDPMS;
181     ScrnInfoPtr pScrn;
182
183     if (DPMSKey == NULL) {
184         return FALSE;
185     }
186
187     /* For each screen, check if DPMS is supported */
188     for (i = 0; i < xf86NumScreens; i++) {
189         pScrn = xf86Screens[i];
190         pDPMS = dixLookupPrivate(&screenInfo.screens[i]->devPrivates, DPMSKey);
191         if (pDPMS && pScrn->DPMSSet)
192             return TRUE;
193     }
194     return FALSE;
195 }
196
197 #endif /* DPMSExtension */