Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/widget/gtk/nsIdleServiceGTK.cpp
Line
Count
Source (jump to first uncovered line)
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
static void Initialize()
34
0
{
35
0
    if (!GDK_IS_X11_DISPLAY(gdk_display_get_default()))
36
0
        return;
37
0
38
0
    // This will leak - See comments in ~nsIdleServiceGTK().
39
0
    PRLibrary* xsslib = PR_LoadLibrary("libXss.so.1");
40
0
    if (!xsslib) // ouch.
41
0
    {
42
0
        MOZ_LOG(sIdleLog, LogLevel::Warning, ("Failed to find libXss.so!\n"));
43
0
        return;
44
0
    }
45
0
46
0
    _XSSQueryExtension = (_XScreenSaverQueryExtension_fn)
47
0
        PR_FindFunctionSymbol(xsslib, "XScreenSaverQueryExtension");
48
0
    _XSSAllocInfo = (_XScreenSaverAllocInfo_fn)
49
0
        PR_FindFunctionSymbol(xsslib, "XScreenSaverAllocInfo");
50
0
    _XSSQueryInfo = (_XScreenSaverQueryInfo_fn)
51
0
        PR_FindFunctionSymbol(xsslib, "XScreenSaverQueryInfo");
52
0
53
0
    if (!_XSSQueryExtension)
54
0
        MOZ_LOG(sIdleLog, LogLevel::Warning, ("Failed to get XSSQueryExtension!\n"));
55
0
    if (!_XSSAllocInfo)
56
0
        MOZ_LOG(sIdleLog, LogLevel::Warning, ("Failed to get XSSAllocInfo!\n"));
57
0
    if (!_XSSQueryInfo)
58
0
        MOZ_LOG(sIdleLog, LogLevel::Warning, ("Failed to get XSSQueryInfo!\n"));
59
0
60
0
    sInitialized = true;
61
0
}
62
63
nsIdleServiceGTK::nsIdleServiceGTK()
64
    : mXssInfo(nullptr)
65
0
{
66
0
    Initialize();
67
0
}
68
69
nsIdleServiceGTK::~nsIdleServiceGTK()
70
0
{
71
0
    if (mXssInfo)
72
0
        XFree(mXssInfo);
73
0
74
0
// It is not safe to unload libXScrnSaver until each display is closed because
75
0
// the library registers callbacks through XESetCloseDisplay (Bug 397607).
76
0
// (Also the library and its functions are scoped for the file not the object.)
77
#if 0
78
    if (xsslib) {
79
        PR_UnloadLibrary(xsslib);
80
        xsslib = nullptr;
81
    }
82
#endif
83
}
84
85
bool
86
nsIdleServiceGTK::PollIdleTime(uint32_t *aIdleTime)
87
0
{
88
0
    if (!sInitialized) {
89
0
        // For some reason, we could not find xscreensaver.
90
0
        return false;
91
0
    }
92
0
93
0
    // Ask xscreensaver about idle time:
94
0
    *aIdleTime = 0;
95
0
96
0
    // We might not have a display (cf. in xpcshell)
97
0
    Display *dplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
98
0
    if (!dplay) {
99
0
        MOZ_LOG(sIdleLog, LogLevel::Warning, ("No display found!\n"));
100
0
        return false;
101
0
    }
102
0
103
0
    if (!_XSSQueryExtension || !_XSSAllocInfo || !_XSSQueryInfo) {
104
0
        return false;
105
0
    }
106
0
107
0
    int event_base, error_base;
108
0
    if (_XSSQueryExtension(dplay, &event_base, &error_base))
109
0
    {
110
0
        if (!mXssInfo)
111
0
            mXssInfo = _XSSAllocInfo();
112
0
        if (!mXssInfo)
113
0
            return false;
114
0
        _XSSQueryInfo(dplay, GDK_ROOT_WINDOW(), mXssInfo);
115
0
        *aIdleTime = mXssInfo->idle;
116
0
        return true;
117
0
    }
118
0
    // If we get here, we couldn't get to XScreenSaver:
119
0
    MOZ_LOG(sIdleLog, LogLevel::Warning, ("XSSQueryExtension returned false!\n"));
120
0
    return false;
121
0
}
122
123
bool
124
nsIdleServiceGTK::UsePollMode()
125
0
{
126
0
    return sInitialized;
127
0
}