bool CXWindowsScreenSaver::handleXEvent(const XEvent* xevent) { switch (xevent->type) { case CreateNotify: if (m_xscreensaver == None) { if (isXScreenSaver(xevent->xcreatewindow.window)) { // found the xscreensaver setXScreenSaver(xevent->xcreatewindow.window); } else { // another window to watch. to detect the xscreensaver // window we look for a property but that property may // not yet exist by the time we get this event so we // have to watch the window for property changes. // this would be so much easier if xscreensaver did the // smart thing and stored its window in a property on // the root window. addWatchXScreenSaver(xevent->xcreatewindow.window); } } break; case DestroyNotify: if (xevent->xdestroywindow.window == m_xscreensaver) { // xscreensaver is gone LOG((CLOG_DEBUG "xscreensaver died")); setXScreenSaver(None); return true; } break; case PropertyNotify: if (xevent->xproperty.state == PropertyNewValue) { if (isXScreenSaver(xevent->xproperty.window)) { // found the xscreensaver setXScreenSaver(xevent->xcreatewindow.window); } } break; case MapNotify: if (xevent->xmap.window == m_xscreensaver) { // xscreensaver has activated setXScreenSaverActive(true); return true; } break; case UnmapNotify: if (xevent->xunmap.window == m_xscreensaver) { // xscreensaver has deactivated setXScreenSaverActive(false); return true; } break; } return false; }
bool CXWindowsScreenSaver::findXScreenSaver() { // do nothing if we've already got the xscreensaver window if (m_xscreensaver == None) { // find top-level window xscreensaver window Window root = DefaultRootWindow(m_display); Window rw, pw, *cw; unsigned int nc; if (XQueryTree(m_display, root, &rw, &pw, &cw, &nc)) { for (unsigned int i = 0; i < nc; ++i) { if (isXScreenSaver(cw[i])) { setXScreenSaver(cw[i]); break; } } XFree(cw); } } return (m_xscreensaver != None); }
CXWindowsScreenSaver::CXWindowsScreenSaver( Display* display, Window window, void* eventTarget, IEventQueue* events) : m_display(display), m_xscreensaverSink(window), m_eventTarget(eventTarget), m_xscreensaver(None), m_xscreensaverActive(false), m_dpms(false), m_disabled(false), m_suppressDisable(false), m_disableTimer(NULL), m_disablePos(0), m_events(events) { // get atoms m_atomScreenSaver = XInternAtom(m_display, "SCREENSAVER", False); m_atomScreenSaverVersion = XInternAtom(m_display, "_SCREENSAVER_VERSION", False); m_atomScreenSaverActivate = XInternAtom(m_display, "ACTIVATE", False); m_atomScreenSaverDeactivate = XInternAtom(m_display, "DEACTIVATE", False); // check for DPMS extension. this is an alternative screen saver // that powers down the display. #if HAVE_X11_EXTENSIONS_DPMS_H int eventBase, errorBase; if (DPMSQueryExtension(m_display, &eventBase, &errorBase)) { if (DPMSCapable(m_display)) { // we have DPMS m_dpms = true; } } #endif // watch top-level windows for changes bool error = false; { CXWindowsUtil::CErrorLock lock(m_display, &error); Window root = DefaultRootWindow(m_display); XWindowAttributes attr; XGetWindowAttributes(m_display, root, &attr); m_rootEventMask = attr.your_event_mask; XSelectInput(m_display, root, m_rootEventMask | SubstructureNotifyMask); } if (error) { LOG((CLOG_DEBUG "didn't set root event mask")); m_rootEventMask = 0; } // get the built-in settings XGetScreenSaver(m_display, &m_timeout, &m_interval, &m_preferBlanking, &m_allowExposures); // get the DPMS settings m_dpmsEnabled = isDPMSEnabled(); // get the xscreensaver window, if any if (!findXScreenSaver()) { setXScreenSaver(None); } // install disable timer event handler m_events->adoptHandler(CEvent::kTimer, this, new TMethodEventJob<CXWindowsScreenSaver>(this, &CXWindowsScreenSaver::handleDisableTimer)); }
CXWindowsScreenSaver::CXWindowsScreenSaver( CXWindowsScreen* screen, Display* display) : m_screen(screen), m_display(display), m_notify(None), m_xscreensaver(None), m_xscreensaverActive(false), m_disabled(false), m_suppressDisable(false), m_disableJobInstalled(false) { // screen saver disable callback m_disableJob = new TMethodJob<CXWindowsScreenSaver>(this, &CXWindowsScreenSaver::disableCallback); // get atoms m_atomScreenSaver = XInternAtom(m_display, "SCREENSAVER", False); m_atomScreenSaverVersion = XInternAtom(m_display, "_SCREENSAVER_VERSION", False); m_atomScreenSaverActivate = XInternAtom(m_display, "ACTIVATE", False); m_atomScreenSaverDeactivate = XInternAtom(m_display, "DEACTIVATE", False); m_atomSynergyScreenSaver = XInternAtom(m_display, "SYNERGY_SCREENSAVER", False); // create dummy window to receive xscreensaver responses. this // shouldn't be necessary (we should be able to send responses // to None) but it doesn't hurt. XSetWindowAttributes attr; attr.event_mask = 0;//PropertyChangeMask; attr.do_not_propagate_mask = 0; attr.override_redirect = True; m_xscreensaverSink = XCreateWindow(m_display, DefaultRootWindow(m_display), 0, 0, 1, 1, 0, 0, InputOnly, CopyFromParent, CWDontPropagate | CWEventMask | CWOverrideRedirect, &attr); LOG((CLOG_DEBUG "xscreensaver sink window is 0x%08x", m_xscreensaverSink)); // watch top-level windows for changes { bool error = false; CXWindowsUtil::CErrorLock lock(m_display, &error); Window root = DefaultRootWindow(m_display); XWindowAttributes attr; XGetWindowAttributes(m_display, root, &attr); m_rootEventMask = attr.your_event_mask; XSelectInput(m_display, root, m_rootEventMask | SubstructureNotifyMask); if (error) { LOG((CLOG_DEBUG "didn't set root event mask")); m_rootEventMask = 0; } } // get the xscreensaver window, if any if (!findXScreenSaver()) { setXScreenSaver(None); } // get the built-in settings XGetScreenSaver(m_display, &m_timeout, &m_interval, &m_preferBlanking, &m_allowExposures); }