Blame widget/gtk/nsIdleServiceGTK.cpp

Packit f0b94e
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
Packit f0b94e
/* vim:expandtab:shiftwidth=4:tabstop=4:
Packit f0b94e
 */
Packit f0b94e
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit f0b94e
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit f0b94e
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit f0b94e
Packit f0b94e
#include <gtk/gtk.h>
Packit f0b94e
Packit f0b94e
#include "nsIdleServiceGTK.h"
Packit f0b94e
#include "nsIServiceManager.h"
Packit f0b94e
#include "nsDebug.h"
Packit f0b94e
#include "prlink.h"
Packit f0b94e
#include "mozilla/Logging.h"
Packit f0b94e
Packit f0b94e
using mozilla::LogLevel;
Packit f0b94e
Packit f0b94e
static mozilla::LazyLogModule sIdleLog("nsIIdleService");
Packit f0b94e
Packit f0b94e
typedef bool (*_XScreenSaverQueryExtension_fn)(Display* dpy, int* event_base,
Packit f0b94e
                                               int* error_base);
Packit f0b94e
Packit f0b94e
typedef XScreenSaverInfo* (*_XScreenSaverAllocInfo_fn)(void);
Packit f0b94e
Packit f0b94e
typedef void (*_XScreenSaverQueryInfo_fn)(Display* dpy, Drawable drw,
Packit f0b94e
                                          XScreenSaverInfo* info);
Packit f0b94e
Packit f0b94e
static bool sInitialized = false;
Packit f0b94e
static _XScreenSaverQueryExtension_fn _XSSQueryExtension = nullptr;
Packit f0b94e
static _XScreenSaverAllocInfo_fn _XSSAllocInfo = nullptr;
Packit f0b94e
static _XScreenSaverQueryInfo_fn _XSSQueryInfo = nullptr;
Packit f0b94e
Packit f0b94e
static void Initialize() {
Packit f0b94e
  if (!GDK_IS_X11_DISPLAY(gdk_display_get_default())) return;
Packit f0b94e
Packit f0b94e
  // This will leak - See comments in ~nsIdleServiceGTK().
Packit f0b94e
  PRLibrary* xsslib = PR_LoadLibrary("libXss.so.1");
Packit f0b94e
  if (!xsslib)  // ouch.
Packit f0b94e
  {
Packit f0b94e
    MOZ_LOG(sIdleLog, LogLevel::Warning, ("Failed to find libXss.so!\n"));
Packit f0b94e
    return;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  _XSSQueryExtension = (_XScreenSaverQueryExtension_fn)PR_FindFunctionSymbol(
Packit f0b94e
      xsslib, "XScreenSaverQueryExtension");
Packit f0b94e
  _XSSAllocInfo = (_XScreenSaverAllocInfo_fn)PR_FindFunctionSymbol(
Packit f0b94e
      xsslib, "XScreenSaverAllocInfo");
Packit f0b94e
  _XSSQueryInfo = (_XScreenSaverQueryInfo_fn)PR_FindFunctionSymbol(
Packit f0b94e
      xsslib, "XScreenSaverQueryInfo");
Packit f0b94e
Packit f0b94e
  if (!_XSSQueryExtension)
Packit f0b94e
    MOZ_LOG(sIdleLog, LogLevel::Warning,
Packit f0b94e
            ("Failed to get XSSQueryExtension!\n"));
Packit f0b94e
  if (!_XSSAllocInfo)
Packit f0b94e
    MOZ_LOG(sIdleLog, LogLevel::Warning, ("Failed to get XSSAllocInfo!\n"));
Packit f0b94e
  if (!_XSSQueryInfo)
Packit f0b94e
    MOZ_LOG(sIdleLog, LogLevel::Warning, ("Failed to get XSSQueryInfo!\n"));
Packit f0b94e
Packit f0b94e
  sInitialized = true;
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
nsIdleServiceGTK::nsIdleServiceGTK() : mXssInfo(nullptr) { Initialize(); }
Packit f0b94e
Packit f0b94e
nsIdleServiceGTK::~nsIdleServiceGTK() {
Packit f0b94e
  if (mXssInfo) XFree(mXssInfo);
Packit f0b94e
Packit f0b94e
// It is not safe to unload libXScrnSaver until each display is closed because
Packit f0b94e
// the library registers callbacks through XESetCloseDisplay (Bug 397607).
Packit f0b94e
// (Also the library and its functions are scoped for the file not the object.)
Packit f0b94e
#if 0
Packit f0b94e
    if (xsslib) {
Packit f0b94e
        PR_UnloadLibrary(xsslib);
Packit f0b94e
        xsslib = nullptr;
Packit f0b94e
    }
Packit f0b94e
#endif
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
bool nsIdleServiceGTK::PollIdleTime(uint32_t* aIdleTime) {
Packit f0b94e
  if (!sInitialized) {
Packit f0b94e
    // For some reason, we could not find xscreensaver.
Packit f0b94e
    return false;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  // Ask xscreensaver about idle time:
Packit f0b94e
  *aIdleTime = 0;
Packit f0b94e
Packit f0b94e
  // We might not have a display (cf. in xpcshell)
Packit f0b94e
  Display* dplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
Packit f0b94e
  if (!dplay) {
Packit f0b94e
    MOZ_LOG(sIdleLog, LogLevel::Warning, ("No display found!\n"));
Packit f0b94e
    return false;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  if (!_XSSQueryExtension || !_XSSAllocInfo || !_XSSQueryInfo) {
Packit f0b94e
    return false;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  int event_base, error_base;
Packit f0b94e
  if (_XSSQueryExtension(dplay, &event_base, &error_base)) {
Packit f0b94e
    if (!mXssInfo) mXssInfo = _XSSAllocInfo();
Packit f0b94e
    if (!mXssInfo) return false;
Packit f0b94e
    _XSSQueryInfo(dplay, GDK_ROOT_WINDOW(), mXssInfo);
Packit f0b94e
    *aIdleTime = mXssInfo->idle;
Packit f0b94e
    return true;
Packit f0b94e
  }
Packit f0b94e
  // If we get here, we couldn't get to XScreenSaver:
Packit f0b94e
  MOZ_LOG(sIdleLog, LogLevel::Warning, ("XSSQueryExtension returned false!\n"));
Packit f0b94e
  return false;
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
bool nsIdleServiceGTK::UsePollMode() { return sInitialized; }