mirror of
https://github.com/debauchee/barrier.git
synced 2026-11-04 06:24:48 +08:00
checkpoint. still refactoring. merged common code from primary
screens into CPrimaryScreen and merged common code from secondary screens into CSecondaryScreen. changed is-a relationship to a has-a between the primary and secondary screen classes and the generic platform dependent screen class to avoid multiple inheritance of implementation. also standardized the interface for those generic screen classes. adding a platform now involves implementing simpler interfaces: IScreen for the generic screen, IScreenEventHandler and some methods of CPrimaryScreen for the primary screen, and IScreenEventHandler and some methods of CSecondaryScreen for the secondary screen. did X11 platform but not win32 platform.
This commit is contained in:
@@ -3,14 +3,22 @@
|
||||
#include "CXWindowsScreenSaver.h"
|
||||
#include "CXWindowsUtil.h"
|
||||
#include "CClipboard.h"
|
||||
#include "IScreenEventHandler.h"
|
||||
#include "IScreenReceiver.h"
|
||||
#include "XScreen.h"
|
||||
#include "CLock.h"
|
||||
#include "CThread.h"
|
||||
#include "CLog.h"
|
||||
#include "IJob.h"
|
||||
#include "CString.h"
|
||||
#include <cstdlib>
|
||||
//#include "CString.h"
|
||||
//#include <cstdlib>
|
||||
#include <cstring>
|
||||
#if defined(X_DISPLAY_MISSING)
|
||||
# error X11 is required to build synergy
|
||||
#else
|
||||
# include <X11/X.h>
|
||||
# include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
//
|
||||
// CXWindowsScreen::CTimer
|
||||
@@ -68,15 +76,24 @@ CXWindowsScreen::CTimer::operator<(const CTimer& t) const
|
||||
|
||||
CXWindowsScreen* CXWindowsScreen::s_screen = NULL;
|
||||
|
||||
CXWindowsScreen::CXWindowsScreen() :
|
||||
CXWindowsScreen::CXWindowsScreen(IScreenReceiver* receiver,
|
||||
IScreenEventHandler* eventHandler) :
|
||||
m_display(NULL),
|
||||
m_root(None),
|
||||
m_stop(false),
|
||||
m_receiver(receiver),
|
||||
m_eventHandler(eventHandler),
|
||||
m_window(None),
|
||||
m_x(0), m_y(0),
|
||||
m_w(0), m_h(0),
|
||||
m_stop(false),
|
||||
m_screenSaver(NULL)
|
||||
m_screensaver(NULL),
|
||||
m_screensaverNotify(false),
|
||||
m_atomScreensaver(None)
|
||||
{
|
||||
assert(s_screen == NULL);
|
||||
assert(s_screen == NULL);
|
||||
assert(m_receiver != NULL);
|
||||
assert(m_eventHandler != NULL);
|
||||
|
||||
s_screen = this;
|
||||
}
|
||||
|
||||
@@ -120,6 +137,77 @@ CXWindowsScreen::removeTimerNoLock(IJob* job)
|
||||
m_timers.swap(tmp);
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::setWindow(Window window)
|
||||
{
|
||||
CLock lock(&m_mutex);
|
||||
assert(m_display != NULL);
|
||||
|
||||
// destroy the clipboards
|
||||
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
||||
delete m_clipboard[id];
|
||||
m_clipboard[id] = NULL;
|
||||
}
|
||||
|
||||
// save the new window
|
||||
m_window = window;
|
||||
|
||||
// initialize the clipboards
|
||||
if (m_window != None) {
|
||||
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
||||
m_clipboard[id] = new CXWindowsClipboard(m_display, m_window, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Window
|
||||
CXWindowsScreen::getRoot() const
|
||||
{
|
||||
assert(m_display != NULL);
|
||||
return m_root;
|
||||
}
|
||||
|
||||
Cursor
|
||||
CXWindowsScreen::getBlankCursor() const
|
||||
{
|
||||
return m_cursor;
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::open()
|
||||
{
|
||||
assert(m_display == NULL);
|
||||
|
||||
// set the X I/O error handler so we catch the display disconnecting
|
||||
XSetIOErrorHandler(&CXWindowsScreen::ioErrorHandler);
|
||||
|
||||
// get the DISPLAY
|
||||
const char* display = getenv("DISPLAY");
|
||||
if (display == NULL) {
|
||||
display = ":0.0";
|
||||
}
|
||||
|
||||
// open the display
|
||||
log((CLOG_DEBUG "XOpenDisplay(\"%s\")", display));
|
||||
m_display = XOpenDisplay(display);
|
||||
if (m_display == NULL) {
|
||||
throw XScreenOpenFailure();
|
||||
}
|
||||
|
||||
// get root window
|
||||
m_root = DefaultRootWindow(m_display);
|
||||
|
||||
// create the transparent cursor
|
||||
createBlankCursor();
|
||||
|
||||
// get screen shape
|
||||
updateScreenShape();
|
||||
|
||||
// initialize the screen saver
|
||||
m_atomScreensaver = XInternAtom(m_display, "SCREENSAVER", False);
|
||||
m_screensaver = new CXWindowsScreenSaver(this, m_display);
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::mainLoop()
|
||||
{
|
||||
@@ -147,7 +235,7 @@ CXWindowsScreen::mainLoop()
|
||||
// have a go at it.
|
||||
m_mutex.unlock();
|
||||
if (!onPreDispatch(&event)) {
|
||||
onEvent(&event);
|
||||
m_eventHandler->onEvent(&event);
|
||||
}
|
||||
m_mutex.lock();
|
||||
}
|
||||
@@ -162,23 +250,210 @@ CXWindowsScreen::exitMainLoop()
|
||||
m_stop = true;
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::close()
|
||||
{
|
||||
CLock lock(&m_mutex);
|
||||
|
||||
// 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
|
||||
if (m_display != NULL) {
|
||||
XCloseDisplay(m_display);
|
||||
m_display = NULL;
|
||||
log((CLOG_DEBUG "closed display"));
|
||||
}
|
||||
XSetIOErrorHandler(NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
CXWindowsScreen::onPreDispatch(const CEvent* event)
|
||||
CXWindowsScreen::setClipboard(ClipboardID id, const IClipboard* clipboard)
|
||||
{
|
||||
CLock lock(&m_mutex);
|
||||
|
||||
// fail if we don't have the requested clipboard
|
||||
if (m_clipboard[id] == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the actual time. ICCCM does not allow CurrentTime.
|
||||
Time timestamp = CXWindowsUtil::getCurrentTime(
|
||||
m_display, m_clipboard[id]->getWindow());
|
||||
|
||||
if (clipboard != NULL) {
|
||||
// save clipboard data
|
||||
return CClipboard::copy(m_clipboard[id], clipboard, timestamp);
|
||||
}
|
||||
else {
|
||||
// assert clipboard ownership
|
||||
if (!m_clipboard[id]->open(timestamp)) {
|
||||
return false;
|
||||
}
|
||||
m_clipboard[id]->empty();
|
||||
m_clipboard[id]->close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::checkClipboards()
|
||||
{
|
||||
// do nothing, we're always up to date
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::openScreenSaver(bool notify)
|
||||
{
|
||||
CLock lock(&m_mutex);
|
||||
assert(m_screensaver != NULL);
|
||||
|
||||
m_screensaverNotify = notify;
|
||||
if (m_screensaverNotify) {
|
||||
m_screensaver->setNotify(m_window);
|
||||
}
|
||||
else {
|
||||
m_screensaver->disable();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::closeScreenSaver()
|
||||
{
|
||||
CLock lock(&m_mutex);
|
||||
if (m_screensaver != NULL) {
|
||||
if (m_screensaverNotify) {
|
||||
m_screensaver->setNotify(None);
|
||||
}
|
||||
else {
|
||||
m_screensaver->enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::screensaver(bool activate)
|
||||
{
|
||||
CLock lock(&m_mutex);
|
||||
assert(m_screensaver != NULL);
|
||||
|
||||
if (activate) {
|
||||
m_screensaver->activate();
|
||||
}
|
||||
else {
|
||||
m_screensaver->deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::syncDesktop()
|
||||
{
|
||||
// do nothing; X doesn't suffer from this bogosity
|
||||
}
|
||||
|
||||
bool
|
||||
CXWindowsScreen::getClipboard(ClipboardID id, IClipboard* clipboard) const
|
||||
{
|
||||
assert(clipboard != NULL);
|
||||
|
||||
// block others from using the display while we get the clipboard
|
||||
CLock lock(&m_mutex);
|
||||
|
||||
// fail if we don't have the requested clipboard
|
||||
if (m_clipboard[id] == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the actual time. ICCCM does not allow CurrentTime.
|
||||
Time timestamp = CXWindowsUtil::getCurrentTime(
|
||||
m_display, m_clipboard[id]->getWindow());
|
||||
|
||||
// copy the clipboard
|
||||
return CClipboard::copy(clipboard, m_clipboard[id], timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::getShape(SInt32& x, SInt32& y, SInt32& w, SInt32& h) const
|
||||
{
|
||||
CLock lock(&m_mutex);
|
||||
assert(m_display != NULL);
|
||||
|
||||
x = m_x;
|
||||
y = m_y;
|
||||
w = m_w;
|
||||
h = m_h;
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::getCursorPos(SInt32& x, SInt32& y) const
|
||||
{
|
||||
CLock lock(&m_mutex);
|
||||
assert(m_display != NULL);
|
||||
|
||||
Window root, window;
|
||||
int mx, my, xWindow, yWindow;
|
||||
unsigned int mask;
|
||||
if (XQueryPointer(m_display, getRoot(), &root, &window,
|
||||
&mx, &my, &xWindow, &yWindow, &mask)) {
|
||||
x = mx;
|
||||
y = my;
|
||||
}
|
||||
else {
|
||||
getCursorCenter(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::getCursorCenter(SInt32& x, SInt32& y) const
|
||||
{
|
||||
CLock lock(&m_mutex);
|
||||
assert(m_display != NULL);
|
||||
|
||||
x = m_x + (m_w >> 1);
|
||||
y = m_y + (m_h >> 1);
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::updateScreenShape()
|
||||
{
|
||||
m_x = 0;
|
||||
m_y = 0;
|
||||
m_w = WidthOfScreen(DefaultScreenOfDisplay(m_display));
|
||||
m_h = HeightOfScreen(DefaultScreenOfDisplay(m_display));
|
||||
log((CLOG_INFO "screen shape: %d,%d %dx%d", m_x, m_y, m_w, m_h));
|
||||
}
|
||||
|
||||
bool
|
||||
CXWindowsScreen::onPreDispatch(CEvent* event)
|
||||
{
|
||||
assert(event != NULL);
|
||||
const XEvent* xevent = &event->m_event;
|
||||
XEvent* xevent = &event->m_event;
|
||||
|
||||
switch (xevent->type) {
|
||||
case MappingNotify:
|
||||
// keyboard mapping changed
|
||||
XRefreshKeyboardMapping(&xevent->xmapping);
|
||||
|
||||
// pass event on
|
||||
break;
|
||||
|
||||
case SelectionClear:
|
||||
{
|
||||
// we just lost the selection. that means someone else
|
||||
// grabbed the selection so this screen is now the
|
||||
// selection owner. report that to the subclass.
|
||||
// selection owner. report that to the receiver.
|
||||
ClipboardID id = getClipboardID(xevent->xselectionclear.selection);
|
||||
if (id != kClipboardEnd) {
|
||||
log((CLOG_DEBUG "lost clipboard %d ownership at time %d", id, xevent->xselectionclear.time));
|
||||
m_clipboard[id]->lost(xevent->xselectionclear.time);
|
||||
onLostClipboard(id);
|
||||
m_receiver->onGrabClipboard(id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -225,6 +500,15 @@ CXWindowsScreen::onPreDispatch(const CEvent* event)
|
||||
}
|
||||
break;
|
||||
|
||||
case ClientMessage:
|
||||
if (xevent->xclient.message_type == m_atomScreensaver ||
|
||||
xevent->xclient.format == 32) {
|
||||
// screen saver activation/deactivation event
|
||||
m_eventHandler->onScreensaver(xevent->xclient.data.l[0] != 0);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case DestroyNotify:
|
||||
// looks like one of the windows that requested a clipboard
|
||||
// transfer has gone bye-bye.
|
||||
@@ -237,150 +521,10 @@ CXWindowsScreen::onPreDispatch(const CEvent* event)
|
||||
// let screen saver have a go
|
||||
{
|
||||
CLock lock(&m_mutex);
|
||||
m_screenSaver->onPreDispatch(xevent);
|
||||
m_screensaver->onPreDispatch(xevent);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::openDisplay()
|
||||
{
|
||||
assert(m_display == NULL);
|
||||
|
||||
// set the X I/O error handler so we catch the display disconnecting
|
||||
XSetIOErrorHandler(&CXWindowsScreen::ioErrorHandler);
|
||||
|
||||
// get the DISPLAY
|
||||
const char* display = getenv("DISPLAY");
|
||||
if (display == NULL) {
|
||||
display = ":0.0";
|
||||
}
|
||||
|
||||
// open the display
|
||||
log((CLOG_DEBUG "XOpenDisplay(\"%s\")", display));
|
||||
m_display = XOpenDisplay(display);
|
||||
if (m_display == NULL) {
|
||||
throw XScreenOpenFailure();
|
||||
}
|
||||
|
||||
// get default screen and root window
|
||||
m_screen = DefaultScreen(m_display);
|
||||
m_root = RootWindow(m_display, m_screen);
|
||||
|
||||
// create the transparent cursor
|
||||
createBlankCursor();
|
||||
|
||||
// get screen shape
|
||||
updateScreenShape();
|
||||
|
||||
// initialize the screen saver
|
||||
m_screenSaver = new CXWindowsScreenSaver(this, m_display);
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::closeDisplay()
|
||||
{
|
||||
CLock lock(&m_mutex);
|
||||
|
||||
// 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
|
||||
if (m_display != NULL) {
|
||||
XCloseDisplay(m_display);
|
||||
m_display = NULL;
|
||||
log((CLOG_DEBUG "closed display"));
|
||||
}
|
||||
XSetIOErrorHandler(NULL);
|
||||
}
|
||||
|
||||
Display*
|
||||
CXWindowsScreen::getDisplay() const
|
||||
{
|
||||
return m_display;
|
||||
}
|
||||
|
||||
int
|
||||
CXWindowsScreen::getScreen() const
|
||||
{
|
||||
assert(m_display != NULL);
|
||||
return m_screen;
|
||||
}
|
||||
|
||||
Window
|
||||
CXWindowsScreen::getRoot() const
|
||||
{
|
||||
assert(m_display != NULL);
|
||||
return m_root;
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::initClipboards(Window window)
|
||||
{
|
||||
assert(m_display != NULL);
|
||||
assert(window != None);
|
||||
|
||||
// initialize clipboards
|
||||
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
||||
m_clipboard[id] = new CXWindowsClipboard(m_display, window, id);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::updateScreenShape()
|
||||
{
|
||||
m_x = 0;
|
||||
m_y = 0;
|
||||
m_w = WidthOfScreen(ScreenOfDisplay(m_display, m_screen));
|
||||
m_h = HeightOfScreen(ScreenOfDisplay(m_display, m_screen));
|
||||
log((CLOG_INFO "screen shape: %d,%d %dx%d", m_x, m_y, m_w, m_h));
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::getScreenShape(SInt32& x, SInt32& y,
|
||||
SInt32& w, SInt32& h) const
|
||||
{
|
||||
assert(m_display != NULL);
|
||||
|
||||
x = m_x;
|
||||
y = m_y;
|
||||
w = m_w;
|
||||
h = m_h;
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::getCursorPos(SInt32& x, SInt32& y) const
|
||||
{
|
||||
assert(m_display != NULL);
|
||||
|
||||
Window root, window;
|
||||
int mx, my, xWindow, yWindow;
|
||||
unsigned int mask;
|
||||
if (XQueryPointer(m_display, getRoot(), &root, &window,
|
||||
&mx, &my, &xWindow, &yWindow, &mask)) {
|
||||
x = mx;
|
||||
y = my;
|
||||
}
|
||||
else {
|
||||
getCursorCenter(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::getCursorCenter(SInt32& x, SInt32& y) const
|
||||
{
|
||||
assert(m_display != NULL);
|
||||
|
||||
x = m_x + (m_w >> 1);
|
||||
y = m_y + (m_h >> 1);
|
||||
return m_eventHandler->onPreDispatch(event);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -417,30 +561,6 @@ CXWindowsScreen::createBlankCursor()
|
||||
XFreePixmap(m_display, bitmap);
|
||||
}
|
||||
|
||||
Cursor
|
||||
CXWindowsScreen::getBlankCursor() const
|
||||
{
|
||||
return m_cursor;
|
||||
}
|
||||
|
||||
ClipboardID
|
||||
CXWindowsScreen::getClipboardID(Atom selection) const
|
||||
{
|
||||
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
||||
if (m_clipboard[id] != NULL &&
|
||||
m_clipboard[id]->getSelection() == selection) {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
return kClipboardEnd;
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsScreen::onUnexpectedClose()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
bool
|
||||
CXWindowsScreen::processTimers()
|
||||
{
|
||||
@@ -486,62 +606,16 @@ CXWindowsScreen::processTimers()
|
||||
}
|
||||
}
|
||||
|
||||
CXWindowsScreenSaver*
|
||||
CXWindowsScreen::getScreenSaver() const
|
||||
ClipboardID
|
||||
CXWindowsScreen::getClipboardID(Atom selection) const
|
||||
{
|
||||
return m_screenSaver;
|
||||
}
|
||||
|
||||
bool
|
||||
CXWindowsScreen::setDisplayClipboard(ClipboardID id,
|
||||
const IClipboard* clipboard)
|
||||
{
|
||||
CLock lock(&m_mutex);
|
||||
|
||||
// fail if we don't have the requested clipboard
|
||||
if (m_clipboard[id] == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the actual time. ICCCM does not allow CurrentTime.
|
||||
Time timestamp = CXWindowsUtil::getCurrentTime(
|
||||
m_display, m_clipboard[id]->getWindow());
|
||||
|
||||
if (clipboard != NULL) {
|
||||
// save clipboard data
|
||||
return CClipboard::copy(m_clipboard[id], clipboard, timestamp);
|
||||
}
|
||||
else {
|
||||
// assert clipboard ownership
|
||||
if (!m_clipboard[id]->open(timestamp)) {
|
||||
return false;
|
||||
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
||||
if (m_clipboard[id] != NULL &&
|
||||
m_clipboard[id]->getSelection() == selection) {
|
||||
return id;
|
||||
}
|
||||
m_clipboard[id]->empty();
|
||||
m_clipboard[id]->close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CXWindowsScreen::getDisplayClipboard(ClipboardID id,
|
||||
IClipboard* clipboard) const
|
||||
{
|
||||
assert(clipboard != NULL);
|
||||
|
||||
// block others from using the display while we get the clipboard
|
||||
CLock lock(&m_mutex);
|
||||
|
||||
// fail if we don't have the requested clipboard
|
||||
if (m_clipboard[id] == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the actual time. ICCCM does not allow CurrentTime.
|
||||
Time timestamp = CXWindowsUtil::getCurrentTime(
|
||||
m_display, m_clipboard[id]->getWindow());
|
||||
|
||||
// copy the clipboard
|
||||
return CClipboard::copy(clipboard, m_clipboard[id], timestamp);
|
||||
return kClipboardEnd;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -584,17 +658,17 @@ CXWindowsScreen::ioErrorHandler(Display*)
|
||||
// so we set it to NULL), and exit.
|
||||
log((CLOG_WARN "X display has unexpectedly disconnected"));
|
||||
s_screen->m_display = NULL;
|
||||
s_screen->onUnexpectedClose();
|
||||
s_screen->m_eventHandler->onError();
|
||||
log((CLOG_CRIT "quiting due to X display disconnection"));
|
||||
exit(17);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// CXWindowsScreen::CDisplayLock
|
||||
// CDisplayLock
|
||||
//
|
||||
|
||||
CXWindowsScreen::CDisplayLock::CDisplayLock(const CXWindowsScreen* screen) :
|
||||
CDisplayLock::CDisplayLock(const CXWindowsScreen* screen) :
|
||||
m_mutex(&screen->m_mutex),
|
||||
m_display(screen->m_display)
|
||||
{
|
||||
@@ -603,12 +677,12 @@ CXWindowsScreen::CDisplayLock::CDisplayLock(const CXWindowsScreen* screen) :
|
||||
m_mutex->lock();
|
||||
}
|
||||
|
||||
CXWindowsScreen::CDisplayLock::~CDisplayLock()
|
||||
CDisplayLock::~CDisplayLock()
|
||||
{
|
||||
m_mutex->unlock();
|
||||
}
|
||||
|
||||
CXWindowsScreen::CDisplayLock::operator Display*() const
|
||||
CDisplayLock::operator Display*() const
|
||||
{
|
||||
return m_display;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef CXWINDOWSSCREEN_H
|
||||
#define CXWINDOWSSCREEN_H
|
||||
|
||||
#include "IScreen.h"
|
||||
#include "ClipboardTypes.h"
|
||||
#include "CMutex.h"
|
||||
#include "CStopwatch.h"
|
||||
@@ -13,9 +14,9 @@
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
class IClipboard;
|
||||
class IJob;
|
||||
class IScreenSaver;
|
||||
class IScreenEventHandler;
|
||||
class IScreenReceiver;
|
||||
class CXWindowsClipboard;
|
||||
class CXWindowsScreenSaver;
|
||||
|
||||
@@ -25,9 +26,9 @@ public:
|
||||
SInt32 m_result;
|
||||
};
|
||||
|
||||
class CXWindowsScreen {
|
||||
class CXWindowsScreen : public IScreen {
|
||||
public:
|
||||
CXWindowsScreen();
|
||||
CXWindowsScreen(IScreenReceiver*, IScreenEventHandler*);
|
||||
virtual ~CXWindowsScreen();
|
||||
|
||||
// manipulators
|
||||
@@ -39,94 +40,41 @@ public:
|
||||
void addTimer(IJob*, double timeout);
|
||||
void removeTimer(IJob*);
|
||||
|
||||
protected:
|
||||
class CDisplayLock {
|
||||
public:
|
||||
CDisplayLock(const CXWindowsScreen*);
|
||||
~CDisplayLock();
|
||||
// set the window (created by the subclass). this performs some
|
||||
// initialization and saves the window in case it's needed later.
|
||||
void setWindow(Window);
|
||||
|
||||
operator Display*() const;
|
||||
// accessors
|
||||
|
||||
private:
|
||||
const CMutex* m_mutex;
|
||||
Display* m_display;
|
||||
};
|
||||
friend class CDisplayLock;
|
||||
|
||||
// runs an event loop and returns when exitMainLoop() is called
|
||||
void mainLoop();
|
||||
|
||||
// force mainLoop() to return
|
||||
void exitMainLoop();
|
||||
|
||||
// open the X display. calls onOpenDisplay() after opening the display,
|
||||
// getting the screen, its size, and root window. then it starts the
|
||||
// event thread.
|
||||
void openDisplay();
|
||||
|
||||
// destroy the window and close the display. calls onCloseDisplay()
|
||||
// after the event thread has been shut down but before the display
|
||||
// is closed.
|
||||
void closeDisplay();
|
||||
|
||||
// get the Display*. only use this when you know the display is
|
||||
// locked but don't have the CDisplayLock available.
|
||||
Display* getDisplay() const;
|
||||
|
||||
// get the opened screen and its root window. to get the display
|
||||
// create a CDisplayLock object passing this. while the object
|
||||
// exists no other threads may access the display. do not save
|
||||
// the Display* beyond the lifetime of the CDisplayLock.
|
||||
int getScreen() const;
|
||||
// get the root window of the screen
|
||||
Window getRoot() const;
|
||||
|
||||
// initialize the clipboards
|
||||
void initClipboards(Window);
|
||||
|
||||
// update screen size cache
|
||||
void updateScreenShape();
|
||||
|
||||
// get the shape of the screen
|
||||
void getScreenShape(SInt32& x, SInt32& y,
|
||||
SInt32& width, SInt32& height) const;
|
||||
|
||||
// get the current cursor position
|
||||
void getCursorPos(SInt32& x, SInt32& y) const;
|
||||
|
||||
// get the cursor center position
|
||||
void getCursorCenter(SInt32& x, SInt32& y) const;
|
||||
|
||||
// get a cursor that is transparent everywhere
|
||||
Cursor getBlankCursor() const;
|
||||
|
||||
// set the contents of the clipboard (i.e. primary selection)
|
||||
bool setDisplayClipboard(ClipboardID,
|
||||
const IClipboard* clipboard);
|
||||
|
||||
// copy the clipboard contents to clipboard
|
||||
bool getDisplayClipboard(ClipboardID,
|
||||
IClipboard* clipboard) const;
|
||||
|
||||
// get the screen saver object
|
||||
CXWindowsScreenSaver*
|
||||
getScreenSaver() const;
|
||||
|
||||
// called for each event before event translation and dispatch. return
|
||||
// true to skip translation and dispatch. subclasses should call the
|
||||
// superclass's version first and return true if it returns true.
|
||||
virtual bool onPreDispatch(const CEvent* event) = 0;
|
||||
|
||||
// called by mainLoop(). iff the event was handled return true and
|
||||
// store the result, if any, in m_result, which defaults to zero.
|
||||
virtual bool onEvent(CEvent* event) = 0;
|
||||
|
||||
// called if the display is unexpectedly closing. default does nothing.
|
||||
virtual void onUnexpectedClose();
|
||||
|
||||
// called when a clipboard is lost
|
||||
virtual void onLostClipboard(ClipboardID) = 0;
|
||||
// IScreen overrides
|
||||
void open();
|
||||
void mainLoop();
|
||||
void exitMainLoop();
|
||||
void close();
|
||||
bool setClipboard(ClipboardID, const IClipboard*);
|
||||
void checkClipboards();
|
||||
void openScreenSaver(bool notify);
|
||||
void closeScreenSaver();
|
||||
void screensaver(bool activate);
|
||||
void syncDesktop();
|
||||
bool getClipboard(ClipboardID, IClipboard*) const;
|
||||
void getShape(SInt32&, SInt32&, SInt32&, SInt32&) const;
|
||||
void getCursorPos(SInt32&, SInt32&) const;
|
||||
void getCursorCenter(SInt32&, SInt32&) const;
|
||||
|
||||
private:
|
||||
// update screen size cache
|
||||
void updateScreenShape();
|
||||
|
||||
// process events before dispatching to receiver
|
||||
bool onPreDispatch(CEvent* event);
|
||||
|
||||
// create the transparent cursor
|
||||
void createBlankCursor();
|
||||
|
||||
@@ -255,14 +203,23 @@ private:
|
||||
};
|
||||
|
||||
private:
|
||||
friend class CDisplayLock;
|
||||
|
||||
typedef CPriorityQueue<CTimer> CTimerPriorityQueue;
|
||||
|
||||
// X is not thread safe
|
||||
CMutex m_mutex;
|
||||
|
||||
Display* m_display;
|
||||
int m_screen;
|
||||
Window m_root;
|
||||
bool m_stop;
|
||||
|
||||
IScreenReceiver* m_receiver;
|
||||
IScreenEventHandler* m_eventHandler;
|
||||
Window m_window;
|
||||
|
||||
SInt32 m_x, m_y;
|
||||
SInt32 m_w, m_h;
|
||||
bool m_stop;
|
||||
|
||||
// clipboards
|
||||
CXWindowsClipboard* m_clipboard[kClipboardEnd];
|
||||
@@ -270,20 +227,31 @@ private:
|
||||
// the transparent cursor
|
||||
Cursor m_cursor;
|
||||
|
||||
// screen saver
|
||||
CXWindowsScreenSaver* m_screenSaver;
|
||||
// screen saver stuff
|
||||
CXWindowsScreenSaver* m_screensaver;
|
||||
bool m_screensaverNotify;
|
||||
Atom m_atomScreensaver;
|
||||
|
||||
// timers, the stopwatch used to time, and a mutex for the timers
|
||||
CTimerPriorityQueue m_timers;
|
||||
CStopwatch m_time;
|
||||
CMutex m_timersMutex;
|
||||
|
||||
// X is not thread safe
|
||||
CMutex m_mutex;
|
||||
|
||||
// pointer to (singleton) screen. this is only needed by
|
||||
// ioErrorHandler().
|
||||
static CXWindowsScreen* s_screen;
|
||||
};
|
||||
|
||||
class CDisplayLock {
|
||||
public:
|
||||
CDisplayLock(const CXWindowsScreen*);
|
||||
~CDisplayLock();
|
||||
|
||||
operator Display*() const;
|
||||
|
||||
private:
|
||||
const CMutex* m_mutex;
|
||||
Display* m_display;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user