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);
|
||||
}
|
||||
log((CLOG_DEBUG1 "recv screen saver on=%d", on));
|
||||
// FIXME
|
||||
m_screen->screenSaver(on != 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "CXWindowsSecondaryScreen.h"
|
||||
#include "CClient.h"
|
||||
#include "CXWindowsClipboard.h"
|
||||
#include "CXWindowsScreenSaver.h"
|
||||
#include "CXWindowsUtil.h"
|
||||
#include "CThread.h"
|
||||
#include "CLog.h"
|
||||
|
@ -119,6 +120,9 @@ CXWindowsSecondaryScreen::open(CClient* client)
|
|||
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
||||
grabClipboard(id);
|
||||
}
|
||||
|
||||
// disable the screen saver
|
||||
getScreenSaver()->disable();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -126,6 +130,9 @@ CXWindowsSecondaryScreen::close()
|
|||
{
|
||||
assert(m_client != NULL);
|
||||
|
||||
// restore the screen saver settings
|
||||
getScreenSaver()->enable();
|
||||
|
||||
// close the display
|
||||
closeDisplay();
|
||||
|
||||
|
@ -287,6 +294,18 @@ CXWindowsSecondaryScreen::grabClipboard(ClipboardID id)
|
|||
setDisplayClipboard(id, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsSecondaryScreen::screenSaver(bool activate)
|
||||
{
|
||||
CDisplayLock display(this);
|
||||
if (activate) {
|
||||
getScreenSaver()->activate();
|
||||
}
|
||||
else {
|
||||
getScreenSaver()->deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsSecondaryScreen::getMousePos(SInt32& x, SInt32& y) const
|
||||
{
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
virtual void mouseWheel(SInt32 delta);
|
||||
virtual void setClipboard(ClipboardID, const IClipboard*);
|
||||
virtual void grabClipboard(ClipboardID);
|
||||
virtual void screenSaver(bool activate);
|
||||
virtual void getMousePos(SInt32& x, SInt32& y) const;
|
||||
virtual void getShape(SInt32&, SInt32&, SInt32&, SInt32&) const;
|
||||
virtual SInt32 getJumpZoneSize() const;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "CXWindowsScreen.h"
|
||||
#include "CXWindowsClipboard.h"
|
||||
#include "CXWindowsScreenSaver.h"
|
||||
#include "CXWindowsUtil.h"
|
||||
#include "CClipboard.h"
|
||||
#include "XScreen.h"
|
||||
|
@ -21,7 +22,8 @@ CXWindowsScreen::CXWindowsScreen() :
|
|||
m_root(None),
|
||||
m_x(0), m_y(0),
|
||||
m_w(0), m_h(0),
|
||||
m_stop(false)
|
||||
m_stop(false),
|
||||
m_screenSaver(NULL)
|
||||
{
|
||||
assert(s_screen == NULL);
|
||||
s_screen = this;
|
||||
|
@ -77,6 +79,9 @@ CXWindowsScreen::openDisplay()
|
|||
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
||||
m_clipboard[id] = createClipboard(id);
|
||||
}
|
||||
|
||||
// initialize the screen saver
|
||||
m_screenSaver = new CXWindowsScreenSaver(m_display);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -87,9 +92,14 @@ CXWindowsScreen::closeDisplay()
|
|||
// let subclass close down display
|
||||
onCloseDisplay(m_display);
|
||||
|
||||
// done with screen saver
|
||||
delete m_screenSaver;
|
||||
m_screenSaver = NULL;
|
||||
|
||||
// destroy clipboards
|
||||
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
||||
delete m_clipboard[id];
|
||||
m_clipboard[id] = NULL;
|
||||
}
|
||||
|
||||
// close the display
|
||||
|
@ -285,9 +295,20 @@ CXWindowsScreen::processEvent(XEvent* xevent)
|
|||
return true;
|
||||
}
|
||||
|
||||
// let screen saver have a go
|
||||
if (m_screenSaver->processEvent(xevent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CXWindowsScreenSaver*
|
||||
CXWindowsScreen::getScreenSaver() const
|
||||
{
|
||||
return m_screenSaver;
|
||||
}
|
||||
|
||||
bool
|
||||
CXWindowsScreen::setDisplayClipboard(ClipboardID id,
|
||||
const IClipboard* clipboard)
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
#endif
|
||||
|
||||
class IClipboard;
|
||||
class IScreenSaver;
|
||||
class CXWindowsClipboard;
|
||||
class CXWindowsScreenSaver;
|
||||
|
||||
class CXWindowsScreen {
|
||||
public:
|
||||
|
@ -68,6 +70,10 @@ protected:
|
|||
bool getDisplayClipboard(ClipboardID,
|
||||
IClipboard* clipboard) const;
|
||||
|
||||
// get the screen saver object
|
||||
CXWindowsScreenSaver*
|
||||
getScreenSaver() const;
|
||||
|
||||
// called by openDisplay() to allow subclasses to prepare the display.
|
||||
// the display is locked and passed to the subclass.
|
||||
virtual void onOpenDisplay(Display*) = 0;
|
||||
|
@ -116,6 +122,9 @@ private:
|
|||
// clipboards
|
||||
CXWindowsClipboard* m_clipboard[kClipboardEnd];
|
||||
|
||||
// screen saver
|
||||
CXWindowsScreenSaver* m_screenSaver;
|
||||
|
||||
// X is not thread safe
|
||||
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
|
||||
noinst_LIBRARIES = libplatform.a
|
||||
libplatform_a_SOURCES = \
|
||||
CPlatform.cpp \
|
||||
CXWindowsClipboard.cpp \
|
||||
CXWindowsScreen.cpp \
|
||||
CXWindowsUtil.cpp \
|
||||
CPlatform.h \
|
||||
CUnixPlatform.h \
|
||||
CXWindowsClipboard.h \
|
||||
CXWindowsScreen.h \
|
||||
CXWindowsUtil.h \
|
||||
IPlatform.h \
|
||||
libplatform_a_SOURCES = \
|
||||
CPlatform.cpp \
|
||||
CXWindowsClipboard.cpp \
|
||||
CXWindowsScreen.cpp \
|
||||
CXWindowsScreenSaver.cpp \
|
||||
CXWindowsUtil.cpp \
|
||||
CPlatform.h \
|
||||
CUnixPlatform.h \
|
||||
CXWindowsClipboard.h \
|
||||
CXWindowsScreen.h \
|
||||
CXWindowsScreenSaver.h \
|
||||
CXWindowsUtil.h \
|
||||
IPlatform.h \
|
||||
$(NULL)
|
||||
INCLUDES = \
|
||||
-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
|
||||
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 (m_active == index->second && m_active != m_primaryInfo) {
|
||||
// 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_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);
|
||||
}
|
||||
|
||||
// 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
|
||||
delete index->second;
|
||||
m_screens.erase(index);
|
||||
|
|
|
@ -58,6 +58,7 @@ public:
|
|||
void onMouseMoveSecondary(SInt32 dx, SInt32 dy);
|
||||
void onMouseWheel(SInt32 delta);
|
||||
void grabClipboard(ClipboardID);
|
||||
void onScreenSaver(bool activated);
|
||||
|
||||
// handle updates from primary
|
||||
void setInfo(SInt32 xScreen, SInt32 yScreen,
|
||||
|
@ -207,6 +208,7 @@ private:
|
|||
|
||||
CMutex m_mutex;
|
||||
|
||||
// the name of the primary screen
|
||||
CString m_name;
|
||||
|
||||
double m_bindTimeout;
|
||||
|
@ -214,8 +216,10 @@ private:
|
|||
ISocketFactory* m_socketFactory;
|
||||
ISecurityFactory* m_securityFactory;
|
||||
|
||||
// running threads
|
||||
CThreadList m_threads;
|
||||
|
||||
// the screens
|
||||
IPrimaryScreen* m_primary;
|
||||
CScreenList m_screens;
|
||||
CScreenInfo* m_active;
|
||||
|
@ -227,10 +231,16 @@ private:
|
|||
// current mouse position (in absolute secondary screen coordinates)
|
||||
SInt32 m_x, m_y;
|
||||
|
||||
// current configuration
|
||||
CConfig m_config;
|
||||
|
||||
// clipboard cache
|
||||
CClipboardInfo m_clipboards[kClipboardEnd];
|
||||
|
||||
// state saved when screen saver activates
|
||||
CScreenInfo* m_activeSaver;
|
||||
SInt32 m_xSaver, m_ySaver;
|
||||
|
||||
// HTTP request processing stuff
|
||||
CHTTPServer* m_httpServer;
|
||||
CCondVar<SInt32> m_httpAvailable;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "CXWindowsPrimaryScreen.h"
|
||||
#include "CServer.h"
|
||||
#include "CXWindowsClipboard.h"
|
||||
#include "CXWindowsScreenSaver.h"
|
||||
#include "CXWindowsUtil.h"
|
||||
#include "CThread.h"
|
||||
#include "CLog.h"
|
||||
|
@ -60,6 +61,14 @@ CXWindowsPrimaryScreen::run()
|
|||
}
|
||||
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:
|
||||
{
|
||||
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);
|
||||
|
||||
// get notified of screen saver activation/deactivation
|
||||
m_atomScreenSaver = XInternAtom(display, "SCREENSAVER", False);
|
||||
getScreenSaver()->setNotify(m_window);
|
||||
|
||||
// update key state
|
||||
updateModifierMap(display);
|
||||
|
||||
|
@ -298,6 +311,10 @@ CXWindowsPrimaryScreen::close()
|
|||
{
|
||||
assert(m_server != NULL);
|
||||
|
||||
// stop being notified of screen saver activation/deactivation
|
||||
getScreenSaver()->setNotify(None);
|
||||
m_atomScreenSaver = None;
|
||||
|
||||
// close the display
|
||||
closeDisplay();
|
||||
|
||||
|
|
|
@ -62,6 +62,9 @@ private:
|
|||
bool m_active;
|
||||
Window m_window;
|
||||
|
||||
// atom for screen saver messages
|
||||
Atom m_atomScreenSaver;
|
||||
|
||||
// note toggle keys that toggle on up/down (false) or on
|
||||
// transition (true)
|
||||
bool m_numLockHalfDuplex;
|
||||
|
|
|
@ -62,23 +62,11 @@ public:
|
|||
// soon after an enter().
|
||||
virtual void setClipboard(ClipboardID, const IClipboard*) = 0;
|
||||
|
||||
/*
|
||||
// show or hide the screen saver
|
||||
virtual void onScreenSaver(bool show) = 0;
|
||||
*/
|
||||
|
||||
// synergy should own the clipboard
|
||||
virtual void grabClipboard(ClipboardID) = 0;
|
||||
|
||||
// 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
|
||||
virtual void getShape(SInt32& x, SInt32& y,
|
||||
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().
|
||||
virtual void setClipboard(ClipboardID, const IClipboard*) = 0;
|
||||
|
||||
/*
|
||||
// show or hide the screen saver
|
||||
virtual void screenSaver(bool show) = 0;
|
||||
*/
|
||||
|
||||
// take ownership of clipboard
|
||||
virtual void grabClipboard(ClipboardID) = 0;
|
||||
|
||||
// activate or deactivate the screen saver
|
||||
virtual void screenSaver(bool activate) = 0;
|
||||
|
||||
// accessors
|
||||
|
||||
// get the position of the mouse on the screen
|
||||
|
|
|
@ -19,6 +19,7 @@ libsynergy_a_SOURCES = \
|
|||
ClipboardTypes.h \
|
||||
IClipboard.h \
|
||||
IPrimaryScreen.h \
|
||||
IScreenSaver.h \
|
||||
ISecondaryScreen.h \
|
||||
IServerProtocol.h \
|
||||
ISocketFactory.h \
|
||||
|
|
Loading…
Reference in New Issue