checkpoint. adding screen saver support. only on X so far
and untested. also some known problems: not detecting an xscreensaver started after us and not detecting built-in screen saver activation (not sure if we can without using ugly extensions).
This commit is contained in:
parent
4e37691a9c
commit
504bfa2def
|
@ -551,7 +551,7 @@ CClient::onScreenSaver()
|
||||||
CProtocolUtil::readf(m_input, kMsgCScreenSaver + 4, &on);
|
CProtocolUtil::readf(m_input, kMsgCScreenSaver + 4, &on);
|
||||||
}
|
}
|
||||||
log((CLOG_DEBUG1 "recv screen saver on=%d", on));
|
log((CLOG_DEBUG1 "recv screen saver on=%d", on));
|
||||||
// FIXME
|
m_screen->screenSaver(on != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "CXWindowsSecondaryScreen.h"
|
#include "CXWindowsSecondaryScreen.h"
|
||||||
#include "CClient.h"
|
#include "CClient.h"
|
||||||
#include "CXWindowsClipboard.h"
|
#include "CXWindowsClipboard.h"
|
||||||
|
#include "CXWindowsScreenSaver.h"
|
||||||
#include "CXWindowsUtil.h"
|
#include "CXWindowsUtil.h"
|
||||||
#include "CThread.h"
|
#include "CThread.h"
|
||||||
#include "CLog.h"
|
#include "CLog.h"
|
||||||
|
@ -119,6 +120,9 @@ CXWindowsSecondaryScreen::open(CClient* client)
|
||||||
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
||||||
grabClipboard(id);
|
grabClipboard(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// disable the screen saver
|
||||||
|
getScreenSaver()->disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -126,6 +130,9 @@ CXWindowsSecondaryScreen::close()
|
||||||
{
|
{
|
||||||
assert(m_client != NULL);
|
assert(m_client != NULL);
|
||||||
|
|
||||||
|
// restore the screen saver settings
|
||||||
|
getScreenSaver()->enable();
|
||||||
|
|
||||||
// close the display
|
// close the display
|
||||||
closeDisplay();
|
closeDisplay();
|
||||||
|
|
||||||
|
@ -287,6 +294,18 @@ CXWindowsSecondaryScreen::grabClipboard(ClipboardID id)
|
||||||
setDisplayClipboard(id, NULL);
|
setDisplayClipboard(id, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsSecondaryScreen::screenSaver(bool activate)
|
||||||
|
{
|
||||||
|
CDisplayLock display(this);
|
||||||
|
if (activate) {
|
||||||
|
getScreenSaver()->activate();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
getScreenSaver()->deactivate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CXWindowsSecondaryScreen::getMousePos(SInt32& x, SInt32& y) const
|
CXWindowsSecondaryScreen::getMousePos(SInt32& x, SInt32& y) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,6 +29,7 @@ public:
|
||||||
virtual void mouseWheel(SInt32 delta);
|
virtual void mouseWheel(SInt32 delta);
|
||||||
virtual void setClipboard(ClipboardID, const IClipboard*);
|
virtual void setClipboard(ClipboardID, const IClipboard*);
|
||||||
virtual void grabClipboard(ClipboardID);
|
virtual void grabClipboard(ClipboardID);
|
||||||
|
virtual void screenSaver(bool activate);
|
||||||
virtual void getMousePos(SInt32& x, SInt32& y) const;
|
virtual void getMousePos(SInt32& x, SInt32& y) const;
|
||||||
virtual void getShape(SInt32&, SInt32&, SInt32&, SInt32&) const;
|
virtual void getShape(SInt32&, SInt32&, SInt32&, SInt32&) const;
|
||||||
virtual SInt32 getJumpZoneSize() const;
|
virtual SInt32 getJumpZoneSize() const;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "CXWindowsScreen.h"
|
#include "CXWindowsScreen.h"
|
||||||
#include "CXWindowsClipboard.h"
|
#include "CXWindowsClipboard.h"
|
||||||
|
#include "CXWindowsScreenSaver.h"
|
||||||
#include "CXWindowsUtil.h"
|
#include "CXWindowsUtil.h"
|
||||||
#include "CClipboard.h"
|
#include "CClipboard.h"
|
||||||
#include "XScreen.h"
|
#include "XScreen.h"
|
||||||
|
@ -21,7 +22,8 @@ CXWindowsScreen::CXWindowsScreen() :
|
||||||
m_root(None),
|
m_root(None),
|
||||||
m_x(0), m_y(0),
|
m_x(0), m_y(0),
|
||||||
m_w(0), m_h(0),
|
m_w(0), m_h(0),
|
||||||
m_stop(false)
|
m_stop(false),
|
||||||
|
m_screenSaver(NULL)
|
||||||
{
|
{
|
||||||
assert(s_screen == NULL);
|
assert(s_screen == NULL);
|
||||||
s_screen = this;
|
s_screen = this;
|
||||||
|
@ -77,6 +79,9 @@ CXWindowsScreen::openDisplay()
|
||||||
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
||||||
m_clipboard[id] = createClipboard(id);
|
m_clipboard[id] = createClipboard(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initialize the screen saver
|
||||||
|
m_screenSaver = new CXWindowsScreenSaver(m_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -87,9 +92,14 @@ CXWindowsScreen::closeDisplay()
|
||||||
// let subclass close down display
|
// let subclass close down display
|
||||||
onCloseDisplay(m_display);
|
onCloseDisplay(m_display);
|
||||||
|
|
||||||
|
// done with screen saver
|
||||||
|
delete m_screenSaver;
|
||||||
|
m_screenSaver = NULL;
|
||||||
|
|
||||||
// destroy clipboards
|
// destroy clipboards
|
||||||
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
||||||
delete m_clipboard[id];
|
delete m_clipboard[id];
|
||||||
|
m_clipboard[id] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// close the display
|
// close the display
|
||||||
|
@ -285,9 +295,20 @@ CXWindowsScreen::processEvent(XEvent* xevent)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// let screen saver have a go
|
||||||
|
if (m_screenSaver->processEvent(xevent)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CXWindowsScreenSaver*
|
||||||
|
CXWindowsScreen::getScreenSaver() const
|
||||||
|
{
|
||||||
|
return m_screenSaver;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CXWindowsScreen::setDisplayClipboard(ClipboardID id,
|
CXWindowsScreen::setDisplayClipboard(ClipboardID id,
|
||||||
const IClipboard* clipboard)
|
const IClipboard* clipboard)
|
||||||
|
|
|
@ -10,7 +10,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class IClipboard;
|
class IClipboard;
|
||||||
|
class IScreenSaver;
|
||||||
class CXWindowsClipboard;
|
class CXWindowsClipboard;
|
||||||
|
class CXWindowsScreenSaver;
|
||||||
|
|
||||||
class CXWindowsScreen {
|
class CXWindowsScreen {
|
||||||
public:
|
public:
|
||||||
|
@ -68,6 +70,10 @@ protected:
|
||||||
bool getDisplayClipboard(ClipboardID,
|
bool getDisplayClipboard(ClipboardID,
|
||||||
IClipboard* clipboard) const;
|
IClipboard* clipboard) const;
|
||||||
|
|
||||||
|
// get the screen saver object
|
||||||
|
CXWindowsScreenSaver*
|
||||||
|
getScreenSaver() const;
|
||||||
|
|
||||||
// called by openDisplay() to allow subclasses to prepare the display.
|
// called by openDisplay() to allow subclasses to prepare the display.
|
||||||
// the display is locked and passed to the subclass.
|
// the display is locked and passed to the subclass.
|
||||||
virtual void onOpenDisplay(Display*) = 0;
|
virtual void onOpenDisplay(Display*) = 0;
|
||||||
|
@ -116,6 +122,9 @@ private:
|
||||||
// clipboards
|
// clipboards
|
||||||
CXWindowsClipboard* m_clipboard[kClipboardEnd];
|
CXWindowsClipboard* m_clipboard[kClipboardEnd];
|
||||||
|
|
||||||
|
// screen saver
|
||||||
|
CXWindowsScreenSaver* m_screenSaver;
|
||||||
|
|
||||||
// X is not thread safe
|
// X is not thread safe
|
||||||
CMutex m_mutex;
|
CMutex m_mutex;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,255 @@
|
||||||
|
#include "CXWindowsScreenSaver.h"
|
||||||
|
#include "CXWindowsUtil.h"
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// CXWindowsScreenSaver
|
||||||
|
//
|
||||||
|
|
||||||
|
CXWindowsScreenSaver::CXWindowsScreenSaver(Display* display) :
|
||||||
|
m_display(display),
|
||||||
|
m_notify(None),
|
||||||
|
m_xscreensaver(None)
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// watch top-level windows for changes
|
||||||
|
{
|
||||||
|
bool error = false;
|
||||||
|
CXWindowsUtil::CErrorLock lock(&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) {
|
||||||
|
m_rootEventMask = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the xscreensaver window, if any
|
||||||
|
updateXScreenSaver();
|
||||||
|
|
||||||
|
// get the built-in settings
|
||||||
|
XGetScreenSaver(m_display, &m_timeout, &m_interval,
|
||||||
|
&m_preferBlanking, &m_allowExposures);
|
||||||
|
}
|
||||||
|
|
||||||
|
CXWindowsScreenSaver::~CXWindowsScreenSaver()
|
||||||
|
{
|
||||||
|
// stop watching root for events
|
||||||
|
CXWindowsUtil::CErrorLock lock;
|
||||||
|
Window root = DefaultRootWindow(m_display);
|
||||||
|
XSelectInput(m_display, root, m_rootEventMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CXWindowsScreenSaver::processEvent(XEvent* xevent)
|
||||||
|
{
|
||||||
|
switch (xevent->type) {
|
||||||
|
case DestroyNotify:
|
||||||
|
if (xevent->xdestroywindow.window == m_xscreensaver) {
|
||||||
|
// xscreensaver is gone
|
||||||
|
setXScreenSaver(false);
|
||||||
|
m_xscreensaver = None;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MapNotify:
|
||||||
|
if (xevent->xmap.window == m_xscreensaver) {
|
||||||
|
// xscreensaver has activated
|
||||||
|
setXScreenSaver(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UnmapNotify:
|
||||||
|
if (xevent->xunmap.window == m_xscreensaver) {
|
||||||
|
// xscreensaver has deactivated
|
||||||
|
setXScreenSaver(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsScreenSaver::setNotify(Window notify)
|
||||||
|
{
|
||||||
|
m_notify = notify;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsScreenSaver::enable()
|
||||||
|
{
|
||||||
|
// try xscreensaver
|
||||||
|
updateXScreenSaver();
|
||||||
|
if (m_xscreensaver) {
|
||||||
|
// FIXME
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use built-in X screen saver
|
||||||
|
XSetScreenSaver(m_display, m_timeout, m_interval,
|
||||||
|
m_preferBlanking, m_allowExposures);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsScreenSaver::disable()
|
||||||
|
{
|
||||||
|
// try xscreensaver
|
||||||
|
updateXScreenSaver();
|
||||||
|
if (m_xscreensaver) {
|
||||||
|
// FIXME
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use built-in X screen saver
|
||||||
|
XGetScreenSaver(m_display, &m_timeout, &m_interval,
|
||||||
|
&m_preferBlanking, &m_allowExposures);
|
||||||
|
XSetScreenSaver(m_display, 0, m_interval,
|
||||||
|
m_preferBlanking, m_allowExposures);
|
||||||
|
// FIXME -- now deactivate?
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsScreenSaver::activate()
|
||||||
|
{
|
||||||
|
// try xscreensaver
|
||||||
|
updateXScreenSaver();
|
||||||
|
if (m_xscreensaver) {
|
||||||
|
sendXScreenSaverCommand(m_atomScreenSaverActivate);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use built-in X screen saver
|
||||||
|
XForceScreenSaver(m_display, ScreenSaverActive);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsScreenSaver::deactivate()
|
||||||
|
{
|
||||||
|
// try xscreensaver
|
||||||
|
updateXScreenSaver();
|
||||||
|
if (m_xscreensaver) {
|
||||||
|
sendXScreenSaverCommand(m_atomScreenSaverDeactivate);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use built-in X screen saver
|
||||||
|
XForceScreenSaver(m_display, ScreenSaverReset);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CXWindowsScreenSaver::isActive() const
|
||||||
|
{
|
||||||
|
// check xscreensaver
|
||||||
|
if (m_xscreensaver != None) {
|
||||||
|
return m_xscreensaverActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
// can't check built-in X screen saver activity
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsScreenSaver::sendNotify(bool activated)
|
||||||
|
{
|
||||||
|
if (m_notify != None) {
|
||||||
|
XEvent event;
|
||||||
|
event.xclient.type = ClientMessage;
|
||||||
|
event.xclient.display = m_display;
|
||||||
|
event.xclient.window = m_notify;
|
||||||
|
event.xclient.message_type = m_atomScreenSaver;
|
||||||
|
event.xclient.format = 32;
|
||||||
|
event.xclient.data.l[0] = activated ? 1 : 0;
|
||||||
|
event.xclient.data.l[1] = 0;
|
||||||
|
event.xclient.data.l[2] = 0;
|
||||||
|
event.xclient.data.l[3] = 0;
|
||||||
|
event.xclient.data.l[4] = 0;
|
||||||
|
|
||||||
|
CXWindowsUtil::CErrorLock lock;
|
||||||
|
XSendEvent(m_display, m_notify, False, 0, &event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsScreenSaver::setXScreenSaver(bool activated)
|
||||||
|
{
|
||||||
|
if (m_xscreensaverActive != activated) {
|
||||||
|
m_xscreensaverActive = activated;
|
||||||
|
sendNotify(activated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsScreenSaver::updateXScreenSaver()
|
||||||
|
{
|
||||||
|
// do nothing if we've already got the xscreensaver window
|
||||||
|
if (m_xscreensaver != None) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find top-level window with m_atomScreenSaverVersion string property
|
||||||
|
CXWindowsUtil::CErrorLock lock;
|
||||||
|
Window root = DefaultRootWindow(m_display);
|
||||||
|
Window rw, pw, *cw;
|
||||||
|
unsigned int nc;
|
||||||
|
if (XQueryTree(m_display, root, &rw, &pw, &cw, &nc)) {
|
||||||
|
CString data;
|
||||||
|
Atom type;
|
||||||
|
for (unsigned int i = 0; i < nc; ++i) {
|
||||||
|
if (CXWindowsUtil::getWindowProperty(m_display, cw[i],
|
||||||
|
m_atomScreenSaverVersion,
|
||||||
|
&data, &type, NULL, False) &&
|
||||||
|
type == XA_STRING) {
|
||||||
|
m_xscreensaver = cw[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XFree(cw);
|
||||||
|
}
|
||||||
|
|
||||||
|
// see if xscreensaver is active
|
||||||
|
if (m_xscreensaver != None) {
|
||||||
|
bool error = false;
|
||||||
|
CXWindowsUtil::CErrorLock lock(&error);
|
||||||
|
XWindowAttributes attr;
|
||||||
|
XGetWindowAttributes(m_display, m_xscreensaver, &attr);
|
||||||
|
setXScreenSaver(!error && attr.map_state != IsUnmapped);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setXScreenSaver(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsScreenSaver::sendXScreenSaverCommand(
|
||||||
|
Atom cmd, long arg1, long arg2) const
|
||||||
|
{
|
||||||
|
XEvent event;
|
||||||
|
event.xclient.type = ClientMessage;
|
||||||
|
event.xclient.display = m_display;
|
||||||
|
event.xclient.window = None;
|
||||||
|
event.xclient.message_type = m_atomScreenSaver;
|
||||||
|
event.xclient.format = 32;
|
||||||
|
event.xclient.data.l[0] = static_cast<long>(cmd);
|
||||||
|
event.xclient.data.l[1] = arg1;
|
||||||
|
event.xclient.data.l[2] = arg2;
|
||||||
|
event.xclient.data.l[3] = 0;
|
||||||
|
event.xclient.data.l[4] = 0;
|
||||||
|
|
||||||
|
CXWindowsUtil::CErrorLock lock;
|
||||||
|
XSendEvent(m_display, m_xscreensaver, False, 0, &event);
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
#ifndef CXWINDOWSSCREENSAVER_H
|
||||||
|
#define CXWINDOWSSCREENSAVER_H
|
||||||
|
|
||||||
|
#include "IScreenSaver.h"
|
||||||
|
#if defined(X_DISPLAY_MISSING)
|
||||||
|
# error X11 is required to build synergy
|
||||||
|
#else
|
||||||
|
# include <X11/Xlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class CXWindowsScreenSaver : public IScreenSaver {
|
||||||
|
public:
|
||||||
|
// note -- the caller must ensure that Display* passed to c'tor isn't
|
||||||
|
// being used in another call to Xlib when calling any method on this
|
||||||
|
// object (including during the c'tor and d'tor) except processEvent().
|
||||||
|
CXWindowsScreenSaver(Display*);
|
||||||
|
virtual ~CXWindowsScreenSaver();
|
||||||
|
|
||||||
|
// process X event. returns true if the event was handled.
|
||||||
|
bool processEvent(XEvent*);
|
||||||
|
|
||||||
|
// tells this object to send a ClientMessage to the given window
|
||||||
|
// when the screen saver activates or deactivates. only one
|
||||||
|
// window can be notified. the message type is the "SCREENSAVER"
|
||||||
|
// atom, the format is 32, and the data.l[0] member is non-zero
|
||||||
|
// if activated, zero if deactivated. pass in None to disable
|
||||||
|
// notification;
|
||||||
|
void setNotify(Window);
|
||||||
|
|
||||||
|
// IScreenSaver overrides
|
||||||
|
virtual void enable();
|
||||||
|
virtual void disable();
|
||||||
|
virtual void activate();
|
||||||
|
virtual void deactivate();
|
||||||
|
virtual bool isActive() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// send a notification
|
||||||
|
void sendNotify(bool activated);
|
||||||
|
|
||||||
|
// set xscreensaver's activation state flag. sends notification
|
||||||
|
// if the state has changed.
|
||||||
|
void setXScreenSaver(bool activated);
|
||||||
|
|
||||||
|
// find the running xscreensaver's window
|
||||||
|
void updateXScreenSaver();
|
||||||
|
|
||||||
|
// send a command to xscreensaver
|
||||||
|
void sendXScreenSaverCommand(Atom, long = 0, long = 0) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// the X display
|
||||||
|
Display* m_display;
|
||||||
|
|
||||||
|
// old event mask on root window
|
||||||
|
long m_rootEventMask;
|
||||||
|
|
||||||
|
// window to notify on screen saver activation/deactivation
|
||||||
|
Window m_notify;
|
||||||
|
|
||||||
|
// xscreensaver's window
|
||||||
|
Window m_xscreensaver;
|
||||||
|
|
||||||
|
// xscreensaver activation state
|
||||||
|
bool m_xscreensaverActive;
|
||||||
|
|
||||||
|
// atoms used to communicate with xscreensaver's window
|
||||||
|
Atom m_atomScreenSaver;
|
||||||
|
Atom m_atomScreenSaverVersion;
|
||||||
|
Atom m_atomScreenSaverActivate;
|
||||||
|
Atom m_atomScreenSaverDeactivate;
|
||||||
|
|
||||||
|
// built-in screen saver settings
|
||||||
|
int m_timeout;
|
||||||
|
int m_interval;
|
||||||
|
int m_preferBlanking;
|
||||||
|
int m_allowExposures;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -4,17 +4,19 @@ DEPTH = ..
|
||||||
|
|
||||||
# FIXME -- add CUnixPlatform.cpp as an unbuilt source
|
# FIXME -- add CUnixPlatform.cpp as an unbuilt source
|
||||||
noinst_LIBRARIES = libplatform.a
|
noinst_LIBRARIES = libplatform.a
|
||||||
libplatform_a_SOURCES = \
|
libplatform_a_SOURCES = \
|
||||||
CPlatform.cpp \
|
CPlatform.cpp \
|
||||||
CXWindowsClipboard.cpp \
|
CXWindowsClipboard.cpp \
|
||||||
CXWindowsScreen.cpp \
|
CXWindowsScreen.cpp \
|
||||||
CXWindowsUtil.cpp \
|
CXWindowsScreenSaver.cpp \
|
||||||
CPlatform.h \
|
CXWindowsUtil.cpp \
|
||||||
CUnixPlatform.h \
|
CPlatform.h \
|
||||||
CXWindowsClipboard.h \
|
CUnixPlatform.h \
|
||||||
CXWindowsScreen.h \
|
CXWindowsClipboard.h \
|
||||||
CXWindowsUtil.h \
|
CXWindowsScreen.h \
|
||||||
IPlatform.h \
|
CXWindowsScreenSaver.h \
|
||||||
|
CXWindowsUtil.h \
|
||||||
|
IPlatform.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
INCLUDES = \
|
INCLUDES = \
|
||||||
-I$(DEPTH)/base \
|
-I$(DEPTH)/base \
|
||||||
|
|
|
@ -709,6 +709,66 @@ CServer::onMouseWheel(SInt32 delta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CServer::onScreenSaver(bool activated)
|
||||||
|
{
|
||||||
|
log((CLOG_DEBUG "onScreenSaver %s", activated ? "activated" : "deactivated"));
|
||||||
|
CLock lock(&m_mutex);
|
||||||
|
|
||||||
|
if (activated) {
|
||||||
|
// save current screen and position
|
||||||
|
m_activeSaver = m_active;
|
||||||
|
m_xSaver = m_x;
|
||||||
|
m_ySaver = m_y;
|
||||||
|
|
||||||
|
// jump to primary screen
|
||||||
|
if (m_active != m_primaryInfo) {
|
||||||
|
// FIXME -- should have separate "center" pixel reported by screen
|
||||||
|
m_x = m_primaryInfo->m_x + (m_primaryInfo->m_w >> 1);
|
||||||
|
m_y = m_primaryInfo->m_y + (m_primaryInfo->m_h >> 1);
|
||||||
|
m_active = m_primaryInfo;
|
||||||
|
m_primary->enter(m_x, m_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// jump back to previous screen and position. we must check
|
||||||
|
// that the position is still valid since the screen may have
|
||||||
|
// changed resolutions while the screen saver was running.
|
||||||
|
if (m_activeSaver != NULL && m_activeSaver != m_primaryInfo) {
|
||||||
|
// check position
|
||||||
|
CScreenInfo* screen = m_activeSaver;
|
||||||
|
if (m_xSaver < screen->m_x + screen->m_zoneSize) {
|
||||||
|
m_xSaver = screen->m_x + screen->m_zoneSize;
|
||||||
|
}
|
||||||
|
else if (m_xSaver >= screen->m_x +
|
||||||
|
screen->m_w - screen->m_zoneSize) {
|
||||||
|
m_xSaver = screen->m_x + screen->m_w - screen->m_zoneSize - 1;
|
||||||
|
}
|
||||||
|
if (m_ySaver < screen->m_y + screen->m_zoneSize) {
|
||||||
|
m_ySaver = screen->m_y + screen->m_zoneSize;
|
||||||
|
}
|
||||||
|
else if (m_ySaver >= screen->m_y +
|
||||||
|
screen->m_h - screen->m_zoneSize) {
|
||||||
|
m_ySaver = screen->m_y + screen->m_h - screen->m_zoneSize - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now jump
|
||||||
|
switchScreen(screen, m_xSaver, m_ySaver);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset state
|
||||||
|
m_activeSaver = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send message to all secondary screens
|
||||||
|
for (CScreenList::const_iterator index = m_screens.begin();
|
||||||
|
index != m_screens.end(); ++index) {
|
||||||
|
if (index->second->m_protocol != NULL) {
|
||||||
|
index->second->m_protocol->sendScreenSaver(activated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CServer::isLockedToScreen() const
|
CServer::isLockedToScreen() const
|
||||||
{
|
{
|
||||||
|
@ -1557,6 +1617,7 @@ CServer::removeConnection(const CString& name)
|
||||||
// if this is active screen then we have to jump off of it
|
// if this is active screen then we have to jump off of it
|
||||||
if (m_active == index->second && m_active != m_primaryInfo) {
|
if (m_active == index->second && m_active != m_primaryInfo) {
|
||||||
// record new position (center of primary screen)
|
// record new position (center of primary screen)
|
||||||
|
// FIXME -- should have separate "center" pixel reported by screen
|
||||||
m_x = m_primaryInfo->m_x + (m_primaryInfo->m_w >> 1);
|
m_x = m_primaryInfo->m_x + (m_primaryInfo->m_w >> 1);
|
||||||
m_y = m_primaryInfo->m_y + (m_primaryInfo->m_h >> 1);
|
m_y = m_primaryInfo->m_y + (m_primaryInfo->m_h >> 1);
|
||||||
|
|
||||||
|
@ -1570,6 +1631,13 @@ CServer::removeConnection(const CString& name)
|
||||||
m_primary->enter(m_x, m_y);
|
m_primary->enter(m_x, m_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if this screen had the cursor when the screen saver activated
|
||||||
|
// then we can't switch back to it when the screen saver
|
||||||
|
// deactivates.
|
||||||
|
if (m_activeSaver == index->second) {
|
||||||
|
m_activeSaver = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// done with screen info
|
// done with screen info
|
||||||
delete index->second;
|
delete index->second;
|
||||||
m_screens.erase(index);
|
m_screens.erase(index);
|
||||||
|
|
|
@ -58,6 +58,7 @@ public:
|
||||||
void onMouseMoveSecondary(SInt32 dx, SInt32 dy);
|
void onMouseMoveSecondary(SInt32 dx, SInt32 dy);
|
||||||
void onMouseWheel(SInt32 delta);
|
void onMouseWheel(SInt32 delta);
|
||||||
void grabClipboard(ClipboardID);
|
void grabClipboard(ClipboardID);
|
||||||
|
void onScreenSaver(bool activated);
|
||||||
|
|
||||||
// handle updates from primary
|
// handle updates from primary
|
||||||
void setInfo(SInt32 xScreen, SInt32 yScreen,
|
void setInfo(SInt32 xScreen, SInt32 yScreen,
|
||||||
|
@ -207,6 +208,7 @@ private:
|
||||||
|
|
||||||
CMutex m_mutex;
|
CMutex m_mutex;
|
||||||
|
|
||||||
|
// the name of the primary screen
|
||||||
CString m_name;
|
CString m_name;
|
||||||
|
|
||||||
double m_bindTimeout;
|
double m_bindTimeout;
|
||||||
|
@ -214,8 +216,10 @@ private:
|
||||||
ISocketFactory* m_socketFactory;
|
ISocketFactory* m_socketFactory;
|
||||||
ISecurityFactory* m_securityFactory;
|
ISecurityFactory* m_securityFactory;
|
||||||
|
|
||||||
|
// running threads
|
||||||
CThreadList m_threads;
|
CThreadList m_threads;
|
||||||
|
|
||||||
|
// the screens
|
||||||
IPrimaryScreen* m_primary;
|
IPrimaryScreen* m_primary;
|
||||||
CScreenList m_screens;
|
CScreenList m_screens;
|
||||||
CScreenInfo* m_active;
|
CScreenInfo* m_active;
|
||||||
|
@ -227,10 +231,16 @@ private:
|
||||||
// current mouse position (in absolute secondary screen coordinates)
|
// current mouse position (in absolute secondary screen coordinates)
|
||||||
SInt32 m_x, m_y;
|
SInt32 m_x, m_y;
|
||||||
|
|
||||||
|
// current configuration
|
||||||
CConfig m_config;
|
CConfig m_config;
|
||||||
|
|
||||||
|
// clipboard cache
|
||||||
CClipboardInfo m_clipboards[kClipboardEnd];
|
CClipboardInfo m_clipboards[kClipboardEnd];
|
||||||
|
|
||||||
|
// state saved when screen saver activates
|
||||||
|
CScreenInfo* m_activeSaver;
|
||||||
|
SInt32 m_xSaver, m_ySaver;
|
||||||
|
|
||||||
// HTTP request processing stuff
|
// HTTP request processing stuff
|
||||||
CHTTPServer* m_httpServer;
|
CHTTPServer* m_httpServer;
|
||||||
CCondVar<SInt32> m_httpAvailable;
|
CCondVar<SInt32> m_httpAvailable;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "CXWindowsPrimaryScreen.h"
|
#include "CXWindowsPrimaryScreen.h"
|
||||||
#include "CServer.h"
|
#include "CServer.h"
|
||||||
#include "CXWindowsClipboard.h"
|
#include "CXWindowsClipboard.h"
|
||||||
|
#include "CXWindowsScreenSaver.h"
|
||||||
#include "CXWindowsUtil.h"
|
#include "CXWindowsUtil.h"
|
||||||
#include "CThread.h"
|
#include "CThread.h"
|
||||||
#include "CLog.h"
|
#include "CLog.h"
|
||||||
|
@ -60,6 +61,14 @@ CXWindowsPrimaryScreen::run()
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ClientMessage:
|
||||||
|
if (xevent.xclient.message_type == m_atomScreenSaver ||
|
||||||
|
xevent.xclient.format == 32) {
|
||||||
|
// screen saver activation/deactivation event
|
||||||
|
m_server->onScreenSaver(xevent.xclient.data.l[0] != 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
{
|
{
|
||||||
log((CLOG_DEBUG1 "event: KeyPress code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
|
log((CLOG_DEBUG1 "event: KeyPress code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
|
||||||
|
@ -267,6 +276,10 @@ CXWindowsPrimaryScreen::open(CServer* server)
|
||||||
{
|
{
|
||||||
CDisplayLock display(this);
|
CDisplayLock display(this);
|
||||||
|
|
||||||
|
// get notified of screen saver activation/deactivation
|
||||||
|
m_atomScreenSaver = XInternAtom(display, "SCREENSAVER", False);
|
||||||
|
getScreenSaver()->setNotify(m_window);
|
||||||
|
|
||||||
// update key state
|
// update key state
|
||||||
updateModifierMap(display);
|
updateModifierMap(display);
|
||||||
|
|
||||||
|
@ -298,6 +311,10 @@ CXWindowsPrimaryScreen::close()
|
||||||
{
|
{
|
||||||
assert(m_server != NULL);
|
assert(m_server != NULL);
|
||||||
|
|
||||||
|
// stop being notified of screen saver activation/deactivation
|
||||||
|
getScreenSaver()->setNotify(None);
|
||||||
|
m_atomScreenSaver = None;
|
||||||
|
|
||||||
// close the display
|
// close the display
|
||||||
closeDisplay();
|
closeDisplay();
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,9 @@ private:
|
||||||
bool m_active;
|
bool m_active;
|
||||||
Window m_window;
|
Window m_window;
|
||||||
|
|
||||||
|
// atom for screen saver messages
|
||||||
|
Atom m_atomScreenSaver;
|
||||||
|
|
||||||
// note toggle keys that toggle on up/down (false) or on
|
// note toggle keys that toggle on up/down (false) or on
|
||||||
// transition (true)
|
// transition (true)
|
||||||
bool m_numLockHalfDuplex;
|
bool m_numLockHalfDuplex;
|
||||||
|
|
|
@ -62,23 +62,11 @@ public:
|
||||||
// soon after an enter().
|
// soon after an enter().
|
||||||
virtual void setClipboard(ClipboardID, const IClipboard*) = 0;
|
virtual void setClipboard(ClipboardID, const IClipboard*) = 0;
|
||||||
|
|
||||||
/*
|
|
||||||
// show or hide the screen saver
|
|
||||||
virtual void onScreenSaver(bool show) = 0;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// synergy should own the clipboard
|
// synergy should own the clipboard
|
||||||
virtual void grabClipboard(ClipboardID) = 0;
|
virtual void grabClipboard(ClipboardID) = 0;
|
||||||
|
|
||||||
// accessors
|
// accessors
|
||||||
|
|
||||||
/*
|
|
||||||
// get the screen's name. all screens must have a name unique on
|
|
||||||
// the server they connect to. the hostname is usually an
|
|
||||||
// appropriate name.
|
|
||||||
virtual CString getName() const = 0;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// get the screen region
|
// get the screen region
|
||||||
virtual void getShape(SInt32& x, SInt32& y,
|
virtual void getShape(SInt32& x, SInt32& y,
|
||||||
SInt32& width, SInt32& height) const = 0;
|
SInt32& width, SInt32& height) const = 0;
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef ISCREENSAVER_H
|
||||||
|
#define ISCREENSAVER_H
|
||||||
|
|
||||||
|
#include "IInterface.h"
|
||||||
|
|
||||||
|
class IScreenSaver : public IInterface {
|
||||||
|
public:
|
||||||
|
// note -- the c'tor/d'tor must *not* enable/disable the screen saver
|
||||||
|
|
||||||
|
// manipulators
|
||||||
|
|
||||||
|
// enable/disable the screen saver. enable() should restore the
|
||||||
|
// screen saver settings to what they were when disable() was
|
||||||
|
// previously called. if disable() wasn't previously called then
|
||||||
|
// it should keep the current settings or use reasonable defaults.
|
||||||
|
virtual void enable() = 0;
|
||||||
|
virtual void disable() = 0;
|
||||||
|
|
||||||
|
// activate/deactivate (i.e. show/hide) the screen saver.
|
||||||
|
// deactivate() also resets the screen saver timer.
|
||||||
|
virtual void activate() = 0;
|
||||||
|
virtual void deactivate() = 0;
|
||||||
|
|
||||||
|
// accessors
|
||||||
|
|
||||||
|
// returns true iff the screen saver is active
|
||||||
|
virtual bool isActive() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -55,14 +55,12 @@ public:
|
||||||
// soon after an enter().
|
// soon after an enter().
|
||||||
virtual void setClipboard(ClipboardID, const IClipboard*) = 0;
|
virtual void setClipboard(ClipboardID, const IClipboard*) = 0;
|
||||||
|
|
||||||
/*
|
|
||||||
// show or hide the screen saver
|
|
||||||
virtual void screenSaver(bool show) = 0;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// take ownership of clipboard
|
// take ownership of clipboard
|
||||||
virtual void grabClipboard(ClipboardID) = 0;
|
virtual void grabClipboard(ClipboardID) = 0;
|
||||||
|
|
||||||
|
// activate or deactivate the screen saver
|
||||||
|
virtual void screenSaver(bool activate) = 0;
|
||||||
|
|
||||||
// accessors
|
// accessors
|
||||||
|
|
||||||
// get the position of the mouse on the screen
|
// get the position of the mouse on the screen
|
||||||
|
|
|
@ -19,6 +19,7 @@ libsynergy_a_SOURCES = \
|
||||||
ClipboardTypes.h \
|
ClipboardTypes.h \
|
||||||
IClipboard.h \
|
IClipboard.h \
|
||||||
IPrimaryScreen.h \
|
IPrimaryScreen.h \
|
||||||
|
IScreenSaver.h \
|
||||||
ISecondaryScreen.h \
|
ISecondaryScreen.h \
|
||||||
IServerProtocol.h \
|
IServerProtocol.h \
|
||||||
ISocketFactory.h \
|
ISocketFactory.h \
|
||||||
|
|
Loading…
Reference in New Issue