Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim:expandtab:shiftwidth=4:tabstop=4:
3 : */
4 : /* This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 :
8 : #include <gtk/gtk.h>
9 :
10 : #include "nsIdleServiceGTK.h"
11 : #include "nsIServiceManager.h"
12 : #include "nsDebug.h"
13 : #include "prlink.h"
14 : #include "mozilla/Logging.h"
15 :
16 : using mozilla::LogLevel;
17 :
18 : static mozilla::LazyLogModule sIdleLog("nsIIdleService");
19 :
20 : typedef bool (*_XScreenSaverQueryExtension_fn)(Display* dpy, int* event_base,
21 : int* error_base);
22 :
23 : typedef XScreenSaverInfo* (*_XScreenSaverAllocInfo_fn)(void);
24 :
25 : typedef void (*_XScreenSaverQueryInfo_fn)(Display* dpy, Drawable drw,
26 : XScreenSaverInfo *info);
27 :
28 : static bool sInitialized = false;
29 : static _XScreenSaverQueryExtension_fn _XSSQueryExtension = nullptr;
30 : static _XScreenSaverAllocInfo_fn _XSSAllocInfo = nullptr;
31 : static _XScreenSaverQueryInfo_fn _XSSQueryInfo = nullptr;
32 :
33 69 : NS_IMPL_ISUPPORTS_INHERITED0(nsIdleServiceGTK, nsIdleService)
34 :
35 1 : static void Initialize()
36 : {
37 1 : if (!GDK_IS_X11_DISPLAY(gdk_display_get_default()))
38 0 : return;
39 :
40 : // This will leak - See comments in ~nsIdleServiceGTK().
41 1 : PRLibrary* xsslib = PR_LoadLibrary("libXss.so.1");
42 1 : if (!xsslib) // ouch.
43 : {
44 0 : MOZ_LOG(sIdleLog, LogLevel::Warning, ("Failed to find libXss.so!\n"));
45 0 : return;
46 : }
47 :
48 1 : _XSSQueryExtension = (_XScreenSaverQueryExtension_fn)
49 1 : PR_FindFunctionSymbol(xsslib, "XScreenSaverQueryExtension");
50 1 : _XSSAllocInfo = (_XScreenSaverAllocInfo_fn)
51 1 : PR_FindFunctionSymbol(xsslib, "XScreenSaverAllocInfo");
52 1 : _XSSQueryInfo = (_XScreenSaverQueryInfo_fn)
53 1 : PR_FindFunctionSymbol(xsslib, "XScreenSaverQueryInfo");
54 :
55 1 : if (!_XSSQueryExtension)
56 0 : MOZ_LOG(sIdleLog, LogLevel::Warning, ("Failed to get XSSQueryExtension!\n"));
57 1 : if (!_XSSAllocInfo)
58 0 : MOZ_LOG(sIdleLog, LogLevel::Warning, ("Failed to get XSSAllocInfo!\n"));
59 1 : if (!_XSSQueryInfo)
60 0 : MOZ_LOG(sIdleLog, LogLevel::Warning, ("Failed to get XSSQueryInfo!\n"));
61 :
62 1 : sInitialized = true;
63 : }
64 :
65 1 : nsIdleServiceGTK::nsIdleServiceGTK()
66 1 : : mXssInfo(nullptr)
67 : {
68 1 : Initialize();
69 1 : }
70 :
71 0 : nsIdleServiceGTK::~nsIdleServiceGTK()
72 : {
73 0 : if (mXssInfo)
74 0 : XFree(mXssInfo);
75 :
76 : // It is not safe to unload libXScrnSaver until each display is closed because
77 : // the library registers callbacks through XESetCloseDisplay (Bug 397607).
78 : // (Also the library and its functions are scoped for the file not the object.)
79 : #if 0
80 : if (xsslib) {
81 : PR_UnloadLibrary(xsslib);
82 : xsslib = nullptr;
83 : }
84 : #endif
85 0 : }
86 :
87 : bool
88 0 : nsIdleServiceGTK::PollIdleTime(uint32_t *aIdleTime)
89 : {
90 0 : if (!sInitialized) {
91 : // For some reason, we could not find xscreensaver.
92 0 : return false;
93 : }
94 :
95 : // Ask xscreensaver about idle time:
96 0 : *aIdleTime = 0;
97 :
98 : // We might not have a display (cf. in xpcshell)
99 0 : Display *dplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
100 0 : if (!dplay) {
101 0 : MOZ_LOG(sIdleLog, LogLevel::Warning, ("No display found!\n"));
102 0 : return false;
103 : }
104 :
105 0 : if (!_XSSQueryExtension || !_XSSAllocInfo || !_XSSQueryInfo) {
106 0 : return false;
107 : }
108 :
109 : int event_base, error_base;
110 0 : if (_XSSQueryExtension(dplay, &event_base, &error_base))
111 : {
112 0 : if (!mXssInfo)
113 0 : mXssInfo = _XSSAllocInfo();
114 0 : if (!mXssInfo)
115 0 : return false;
116 0 : _XSSQueryInfo(dplay, GDK_ROOT_WINDOW(), mXssInfo);
117 0 : *aIdleTime = mXssInfo->idle;
118 0 : return true;
119 : }
120 : // If we get here, we couldn't get to XScreenSaver:
121 0 : MOZ_LOG(sIdleLog, LogLevel::Warning, ("XSSQueryExtension returned false!\n"));
122 0 : return false;
123 : }
124 :
125 : bool
126 0 : nsIdleServiceGTK::UsePollMode()
127 : {
128 0 : return sInitialized;
129 : }
|