1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim:expandtab:shiftwidth=4:tabstop=4:
3 : */
4 : /* ***** BEGIN LICENSE BLOCK *****
5 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 : *
7 : * The contents of this file are subject to the Mozilla Public License Version
8 : * 1.1 (the "License"); you may not use this file except in compliance with
9 : * the License. You may obtain a copy of the License at
10 : * http://www.mozilla.org/MPL/
11 : *
12 : * Software distributed under the License is distributed on an "AS IS" basis,
13 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 : * for the specific language governing rights and limitations under the
15 : * License.
16 : *
17 : * The Original Code is mozilla.org code.
18 : *
19 : * The Initial Developer of the Original Code is
20 : * Gijs Kruitbosch <gijskruitbosch@gmail.com>.
21 : * Portions created by the Initial Developer are Copyright (C) 2007
22 : * the Initial Developer. All Rights Reserved.
23 : *
24 : * Contributor(s):
25 : * Gijs Kruitbosch <gijskruitbosch@gmail.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either the GNU General Public License Version 2 or later (the "GPL"), or
29 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #include "nsIdleServiceGTK.h"
42 : #include "nsIServiceManager.h"
43 : #include "nsDebug.h"
44 : #include "prlink.h"
45 : #include "prlog.h"
46 :
47 :
48 : #ifdef PR_LOGGING
49 : static PRLogModuleInfo* sIdleLog = nsnull;
50 : #endif
51 :
52 : typedef bool (*_XScreenSaverQueryExtension_fn)(Display* dpy, int* event_base,
53 : int* error_base);
54 :
55 : typedef XScreenSaverInfo* (*_XScreenSaverAllocInfo_fn)(void);
56 :
57 : typedef void (*_XScreenSaverQueryInfo_fn)(Display* dpy, Drawable drw,
58 : XScreenSaverInfo *info);
59 :
60 : static bool sInitialized = false;
61 : static _XScreenSaverQueryExtension_fn _XSSQueryExtension = nsnull;
62 : static _XScreenSaverAllocInfo_fn _XSSAllocInfo = nsnull;
63 : static _XScreenSaverQueryInfo_fn _XSSQueryInfo = nsnull;
64 :
65 26 : NS_IMPL_ISUPPORTS2(nsIdleServiceGTK, nsIdleService, nsIIdleService)
66 :
67 1 : static void Initialize()
68 : {
69 : // This will leak - See comments in ~nsIdleServiceGTK().
70 1 : PRLibrary* xsslib = PR_LoadLibrary("libXss.so.1");
71 1 : if (!xsslib) // ouch.
72 : {
73 : #ifdef PR_LOGGING
74 0 : PR_LOG(sIdleLog, PR_LOG_WARNING, ("Failed to find libXss.so!\n"));
75 : #endif
76 0 : return;
77 : }
78 :
79 : _XSSQueryExtension = (_XScreenSaverQueryExtension_fn)
80 1 : PR_FindFunctionSymbol(xsslib, "XScreenSaverQueryExtension");
81 : _XSSAllocInfo = (_XScreenSaverAllocInfo_fn)
82 1 : PR_FindFunctionSymbol(xsslib, "XScreenSaverAllocInfo");
83 : _XSSQueryInfo = (_XScreenSaverQueryInfo_fn)
84 1 : PR_FindFunctionSymbol(xsslib, "XScreenSaverQueryInfo");
85 : #ifdef PR_LOGGING
86 1 : if (!_XSSQueryExtension)
87 0 : PR_LOG(sIdleLog, PR_LOG_WARNING, ("Failed to get XSSQueryExtension!\n"));
88 1 : if (!_XSSAllocInfo)
89 0 : PR_LOG(sIdleLog, PR_LOG_WARNING, ("Failed to get XSSAllocInfo!\n"));
90 1 : if (!_XSSQueryInfo)
91 0 : PR_LOG(sIdleLog, PR_LOG_WARNING, ("Failed to get XSSQueryInfo!\n"));
92 : #endif
93 :
94 1 : sInitialized = true;
95 : }
96 :
97 1 : nsIdleServiceGTK::nsIdleServiceGTK()
98 1 : : mXssInfo(nsnull)
99 : {
100 : #ifdef PR_LOGGING
101 1 : if (!sIdleLog)
102 1 : sIdleLog = PR_NewLogModule("nsIIdleService");
103 : #endif
104 :
105 1 : Initialize();
106 1 : }
107 :
108 3 : nsIdleServiceGTK::~nsIdleServiceGTK()
109 : {
110 1 : if (mXssInfo)
111 0 : XFree(mXssInfo);
112 :
113 : // It is not safe to unload libXScrnSaver until each display is closed because
114 : // the library registers callbacks through XESetCloseDisplay (Bug 397607).
115 : // (Also the library and its functions are scoped for the file not the object.)
116 : #if 0
117 : if (xsslib) {
118 : PR_UnloadLibrary(xsslib);
119 : xsslib = nsnull;
120 : }
121 : #endif
122 4 : }
123 :
124 : bool
125 1 : nsIdleServiceGTK::PollIdleTime(PRUint32 *aIdleTime)
126 : {
127 1 : if (!sInitialized) {
128 : // For some reason, we could not find xscreensaver. This this might be
129 : // because we are on a mobile platforms (e.g. Maemo/OSSO). In this
130 : // case, let the base class handle it
131 0 : return false;
132 : }
133 :
134 : // Ask xscreensaver about idle time:
135 1 : *aIdleTime = 0;
136 :
137 : // We might not have a display (cf. in xpcshell)
138 1 : Display *dplay = GDK_DISPLAY();
139 1 : if (!dplay) {
140 : #ifdef PR_LOGGING
141 1 : PR_LOG(sIdleLog, PR_LOG_WARNING, ("No display found!\n"));
142 : #endif
143 1 : return false;
144 : }
145 :
146 0 : if (!_XSSQueryExtension || !_XSSAllocInfo || !_XSSQueryInfo) {
147 0 : return false;
148 : }
149 :
150 : int event_base, error_base;
151 0 : if (_XSSQueryExtension(dplay, &event_base, &error_base))
152 : {
153 0 : if (!mXssInfo)
154 0 : mXssInfo = _XSSAllocInfo();
155 0 : if (!mXssInfo)
156 0 : return false;
157 0 : _XSSQueryInfo(dplay, GDK_ROOT_WINDOW(), mXssInfo);
158 0 : *aIdleTime = mXssInfo->idle;
159 0 : return true;
160 : }
161 : // If we get here, we couldn't get to XScreenSaver:
162 : #ifdef PR_LOGGING
163 0 : PR_LOG(sIdleLog, PR_LOG_WARNING, ("XSSQueryExtension returned false!\n"));
164 : #endif
165 0 : return false;
166 : }
167 :
168 : bool
169 0 : nsIdleServiceGTK::UsePollMode()
170 : {
171 0 : return sInitialized;
172 : }
173 :
|