checkpoint. making win32 and X primary screen code more similar
in order to share code later.
This commit is contained in:
parent
feeb15a08d
commit
ef7fe1f283
|
@ -85,19 +85,46 @@ void
|
||||||
CXWindowsSecondaryScreen::open()
|
CXWindowsSecondaryScreen::open()
|
||||||
{
|
{
|
||||||
assert(m_receiver != NULL);
|
assert(m_receiver != NULL);
|
||||||
|
assert(m_window == None);
|
||||||
|
|
||||||
// open the display
|
// open the display
|
||||||
openDisplay();
|
openDisplay();
|
||||||
|
|
||||||
{
|
{
|
||||||
// verify the availability of the XTest extension
|
|
||||||
CDisplayLock display(this);
|
CDisplayLock display(this);
|
||||||
|
|
||||||
|
// verify the availability of the XTest extension
|
||||||
int majorOpcode, firstEvent, firstError;
|
int majorOpcode, firstEvent, firstError;
|
||||||
if (!XQueryExtension(display, XTestExtensionName,
|
if (!XQueryExtension(display, XTestExtensionName,
|
||||||
&majorOpcode, &firstEvent, &firstError)) {
|
&majorOpcode, &firstEvent, &firstError)) {
|
||||||
throw int(6); // FIXME -- make exception for this
|
throw int(6); // FIXME -- make exception for this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create the cursor hiding window. this window is used to hide the
|
||||||
|
// cursor when it's not on the screen. the window is hidden as soon
|
||||||
|
// as the cursor enters the screen or the display's real cursor is
|
||||||
|
// moved.
|
||||||
|
XSetWindowAttributes attr;
|
||||||
|
attr.event_mask = LeaveWindowMask;
|
||||||
|
attr.do_not_propagate_mask = 0;
|
||||||
|
attr.override_redirect = True;
|
||||||
|
attr.cursor = getBlankCursor();
|
||||||
|
m_window = XCreateWindow(display, getRoot(), 0, 0, 1, 1, 0, 0,
|
||||||
|
InputOnly, CopyFromParent,
|
||||||
|
CWDontPropagate | CWEventMask |
|
||||||
|
CWOverrideRedirect | CWCursor,
|
||||||
|
&attr);
|
||||||
|
log((CLOG_DEBUG "window is 0x%08x", m_window));
|
||||||
|
|
||||||
|
// become impervious to server grabs
|
||||||
|
XTestGrabControl(display, True);
|
||||||
|
|
||||||
|
// hide the cursor
|
||||||
|
leaveNoLock(display);
|
||||||
|
|
||||||
|
// initialize the clipboards
|
||||||
|
initClipboards(m_window);
|
||||||
|
|
||||||
// update key state
|
// update key state
|
||||||
updateKeys(display);
|
updateKeys(display);
|
||||||
updateKeycodeMap(display);
|
updateKeycodeMap(display);
|
||||||
|
@ -130,6 +157,18 @@ CXWindowsSecondaryScreen::close()
|
||||||
// restore the screen saver settings
|
// restore the screen saver settings
|
||||||
getScreenSaver()->enable();
|
getScreenSaver()->enable();
|
||||||
|
|
||||||
|
{
|
||||||
|
CDisplayLock display(this);
|
||||||
|
if (display != NULL) {
|
||||||
|
// no longer impervious to server grabs
|
||||||
|
XTestGrabControl(display, False);
|
||||||
|
|
||||||
|
// destroy window
|
||||||
|
XDestroyWindow(display, m_window);
|
||||||
|
}
|
||||||
|
m_window = None;
|
||||||
|
}
|
||||||
|
|
||||||
// close the display
|
// close the display
|
||||||
closeDisplay();
|
closeDisplay();
|
||||||
}
|
}
|
||||||
|
@ -304,13 +343,7 @@ void
|
||||||
CXWindowsSecondaryScreen::getMousePos(SInt32& x, SInt32& y) const
|
CXWindowsSecondaryScreen::getMousePos(SInt32& x, SInt32& y) const
|
||||||
{
|
{
|
||||||
CDisplayLock display(this);
|
CDisplayLock display(this);
|
||||||
int xTmp, yTmp, dummy;
|
getCursorPos(x, y);
|
||||||
unsigned int dummyMask;
|
|
||||||
Window dummyWindow;
|
|
||||||
XQueryPointer(display, getRoot(), &dummyWindow, &dummyWindow,
|
|
||||||
&xTmp, &yTmp, &dummy, &dummy, &dummyMask);
|
|
||||||
x = xTmp;
|
|
||||||
y = yTmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -333,56 +366,6 @@ CXWindowsSecondaryScreen::getClipboard(ClipboardID id,
|
||||||
getDisplayClipboard(id, clipboard);
|
getDisplayClipboard(id, clipboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CXWindowsSecondaryScreen::onOpenDisplay(Display* display)
|
|
||||||
{
|
|
||||||
assert(m_window == None);
|
|
||||||
|
|
||||||
// create the cursor hiding window. this window is used to hide the
|
|
||||||
// cursor when it's not on the screen. the window is hidden as soon
|
|
||||||
// as the cursor enters the screen or the display's real cursor is
|
|
||||||
// moved.
|
|
||||||
XSetWindowAttributes attr;
|
|
||||||
attr.event_mask = LeaveWindowMask;
|
|
||||||
attr.do_not_propagate_mask = 0;
|
|
||||||
attr.override_redirect = True;
|
|
||||||
attr.cursor = createBlankCursor();
|
|
||||||
m_window = XCreateWindow(display, getRoot(), 0, 0, 1, 1, 0, 0,
|
|
||||||
InputOnly, CopyFromParent,
|
|
||||||
CWDontPropagate | CWEventMask |
|
|
||||||
CWOverrideRedirect | CWCursor,
|
|
||||||
&attr);
|
|
||||||
log((CLOG_DEBUG "window is 0x%08x", m_window));
|
|
||||||
|
|
||||||
// become impervious to server grabs
|
|
||||||
XTestGrabControl(display, True);
|
|
||||||
|
|
||||||
// hide the cursor
|
|
||||||
leaveNoLock(display);
|
|
||||||
}
|
|
||||||
|
|
||||||
CXWindowsClipboard*
|
|
||||||
CXWindowsSecondaryScreen::createClipboard(ClipboardID id)
|
|
||||||
{
|
|
||||||
CDisplayLock display(this);
|
|
||||||
return new CXWindowsClipboard(display, m_window, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CXWindowsSecondaryScreen::onCloseDisplay(Display* display)
|
|
||||||
{
|
|
||||||
assert(m_window != None);
|
|
||||||
|
|
||||||
if (display != NULL) {
|
|
||||||
// no longer impervious to server grabs
|
|
||||||
XTestGrabControl(display, False);
|
|
||||||
|
|
||||||
// destroy window
|
|
||||||
XDestroyWindow(display, m_window);
|
|
||||||
}
|
|
||||||
m_window = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CXWindowsSecondaryScreen::onLostClipboard(ClipboardID id)
|
CXWindowsSecondaryScreen::onLostClipboard(ClipboardID id)
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,10 +39,6 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// CXWindowsScreen overrides
|
// CXWindowsScreen overrides
|
||||||
virtual void onOpenDisplay(Display*);
|
|
||||||
virtual CXWindowsClipboard*
|
|
||||||
createClipboard(ClipboardID);
|
|
||||||
virtual void onCloseDisplay(Display*);
|
|
||||||
virtual void onLostClipboard(ClipboardID);
|
virtual void onLostClipboard(ClipboardID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -84,16 +84,8 @@ CMSWindowsScreen::openDisplay()
|
||||||
assert(s_instance != NULL);
|
assert(s_instance != NULL);
|
||||||
assert(m_class == 0);
|
assert(m_class == 0);
|
||||||
|
|
||||||
// create a transparent cursor
|
// create the transparent cursor
|
||||||
int cw = GetSystemMetrics(SM_CXCURSOR);
|
createBlankCursor();
|
||||||
int ch = GetSystemMetrics(SM_CYCURSOR);
|
|
||||||
UInt8* cursorAND = new UInt8[ch * ((cw + 31) >> 2)];
|
|
||||||
UInt8* cursorXOR = new UInt8[ch * ((cw + 31) >> 2)];
|
|
||||||
memset(cursorAND, 0xff, ch * ((cw + 31) >> 2));
|
|
||||||
memset(cursorXOR, 0x00, ch * ((cw + 31) >> 2));
|
|
||||||
m_cursor = CreateCursor(s_instance, 0, 0, cw, ch, cursorAND, cursorXOR);
|
|
||||||
delete[] cursorXOR;
|
|
||||||
delete[] cursorAND;
|
|
||||||
|
|
||||||
// register a window class
|
// register a window class
|
||||||
WNDCLASSEX classInfo;
|
WNDCLASSEX classInfo;
|
||||||
|
@ -114,9 +106,6 @@ CMSWindowsScreen::openDisplay()
|
||||||
// get screen shape
|
// get screen shape
|
||||||
updateScreenShape();
|
updateScreenShape();
|
||||||
|
|
||||||
// let subclass prep display
|
|
||||||
onOpenDisplay();
|
|
||||||
|
|
||||||
// initialize the screen saver
|
// initialize the screen saver
|
||||||
m_screenSaver = new CMSWindowsScreenSaver();
|
m_screenSaver = new CMSWindowsScreenSaver();
|
||||||
}
|
}
|
||||||
|
@ -125,22 +114,22 @@ void
|
||||||
CMSWindowsScreen::closeDisplay()
|
CMSWindowsScreen::closeDisplay()
|
||||||
{
|
{
|
||||||
assert(s_instance != NULL);
|
assert(s_instance != NULL);
|
||||||
assert(m_class != 0);
|
|
||||||
|
|
||||||
// done with screen saver
|
// done with screen saver
|
||||||
delete m_screenSaver;
|
delete m_screenSaver;
|
||||||
m_screenSaver = NULL;
|
m_screenSaver = NULL;
|
||||||
|
|
||||||
// let subclass close down display
|
|
||||||
onCloseDisplay();
|
|
||||||
|
|
||||||
// unregister the window class
|
// unregister the window class
|
||||||
|
if (m_class != 0) {
|
||||||
UnregisterClass((LPCTSTR)m_class, s_instance);
|
UnregisterClass((LPCTSTR)m_class, s_instance);
|
||||||
m_class = 0;
|
m_class = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// delete resources
|
// delete resources
|
||||||
|
if (m_cursor != NULL) {
|
||||||
DestroyCursor(m_cursor);
|
DestroyCursor(m_cursor);
|
||||||
m_cursor = NULL;
|
m_cursor = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
log((CLOG_DEBUG "closed display"));
|
log((CLOG_DEBUG "closed display"));
|
||||||
}
|
}
|
||||||
|
@ -168,8 +157,8 @@ CMSWindowsScreen::updateScreenShape()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CMSWindowsScreen::getScreenShape(
|
CMSWindowsScreen::getScreenShape(SInt32& x, SInt32& y,
|
||||||
SInt32& x, SInt32& y, SInt32& w, SInt32& h) const
|
SInt32& w, SInt32& h) const
|
||||||
{
|
{
|
||||||
assert(m_class != 0);
|
assert(m_class != 0);
|
||||||
|
|
||||||
|
@ -179,6 +168,43 @@ CMSWindowsScreen::getScreenShape(
|
||||||
h = m_h;
|
h = m_h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsScreen::getCursorPos(SInt32& x, SInt32& y) const
|
||||||
|
{
|
||||||
|
POINT pos;
|
||||||
|
GetCursorPos(&pos);
|
||||||
|
x = pos.x;
|
||||||
|
y = pos.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsScreen::getCursorCenter(SInt32& x, SInt32& y) const
|
||||||
|
{
|
||||||
|
x = GetSystemMetrics(SM_CXSCREEN) >> 1;
|
||||||
|
y = GetSystemMetrics(SM_CYSCREEN) >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HCURSOR
|
||||||
|
CMSWindowsScreen::getBlankCursor() const
|
||||||
|
{
|
||||||
|
return m_cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsScreen::createBlankCursor()
|
||||||
|
{
|
||||||
|
// create a transparent cursor
|
||||||
|
int cw = GetSystemMetrics(SM_CXCURSOR);
|
||||||
|
int ch = GetSystemMetrics(SM_CYCURSOR);
|
||||||
|
UInt8* cursorAND = new UInt8[ch * ((cw + 31) >> 2)];
|
||||||
|
UInt8* cursorXOR = new UInt8[ch * ((cw + 31) >> 2)];
|
||||||
|
memset(cursorAND, 0xff, ch * ((cw + 31) >> 2));
|
||||||
|
memset(cursorXOR, 0x00, ch * ((cw + 31) >> 2));
|
||||||
|
m_cursor = CreateCursor(s_instance, 0, 0, cw, ch, cursorAND, cursorXOR);
|
||||||
|
delete[] cursorXOR;
|
||||||
|
delete[] cursorAND;
|
||||||
|
}
|
||||||
|
|
||||||
HDESK
|
HDESK
|
||||||
CMSWindowsScreen::openInputDesktop() const
|
CMSWindowsScreen::openInputDesktop() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,6 +51,12 @@ protected:
|
||||||
void getScreenShape(SInt32& x, SInt32& y,
|
void getScreenShape(SInt32& x, SInt32& y,
|
||||||
SInt32& width, SInt32& height) const;
|
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 the input desktop. caller must CloseDesktop() the result.
|
// get the input desktop. caller must CloseDesktop() the result.
|
||||||
// do not call under windows 95/98/me.
|
// do not call under windows 95/98/me.
|
||||||
HDESK openInputDesktop() const;
|
HDESK openInputDesktop() const;
|
||||||
|
@ -76,16 +82,13 @@ protected:
|
||||||
// called by window proc. subclass must call DefWindowProc() if necessary
|
// called by window proc. subclass must call DefWindowProc() if necessary
|
||||||
virtual LRESULT onEvent(HWND, UINT, WPARAM, LPARAM) = 0;
|
virtual LRESULT onEvent(HWND, UINT, WPARAM, LPARAM) = 0;
|
||||||
|
|
||||||
// called by openDisplay() to allow subclasses to prepare the display
|
|
||||||
virtual void onOpenDisplay() = 0;
|
|
||||||
|
|
||||||
// called by closeDisplay() to
|
|
||||||
virtual void onCloseDisplay() = 0;
|
|
||||||
|
|
||||||
// called by isCurrentDesktop() to get the current desktop name
|
// called by isCurrentDesktop() to get the current desktop name
|
||||||
virtual CString getCurrentDesktopName() const = 0;
|
virtual CString getCurrentDesktopName() const = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// create the transparent cursor
|
||||||
|
void createBlankCursor();
|
||||||
|
|
||||||
static LRESULT CALLBACK wndProc(HWND, UINT, WPARAM, LPARAM);
|
static LRESULT CALLBACK wndProc(HWND, UINT, WPARAM, LPARAM);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -141,27 +141,15 @@ CXWindowsScreen::openDisplay()
|
||||||
throw XScreenOpenFailure();
|
throw XScreenOpenFailure();
|
||||||
}
|
}
|
||||||
|
|
||||||
// get default screen
|
// get default screen and root window
|
||||||
m_screen = DefaultScreen(m_display);
|
m_screen = DefaultScreen(m_display);
|
||||||
Screen* screen = ScreenOfDisplay(m_display, m_screen);
|
|
||||||
|
|
||||||
// get screen shape
|
|
||||||
m_x = 0;
|
|
||||||
m_y = 0;
|
|
||||||
m_w = WidthOfScreen(screen);
|
|
||||||
m_h = HeightOfScreen(screen);
|
|
||||||
log((CLOG_INFO "screen shape: %d,%d %dx%d", m_x, m_y, m_w, m_h));
|
|
||||||
|
|
||||||
// get the root window
|
|
||||||
m_root = RootWindow(m_display, m_screen);
|
m_root = RootWindow(m_display, m_screen);
|
||||||
|
|
||||||
// let subclass prep display
|
// create the transparent cursor
|
||||||
onOpenDisplay(m_display);
|
createBlankCursor();
|
||||||
|
|
||||||
// initialize clipboards
|
// get screen shape
|
||||||
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
updateScreenShape();
|
||||||
m_clipboard[id] = createClipboard(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize the screen saver
|
// initialize the screen saver
|
||||||
m_screenSaver = new CXWindowsScreenSaver(this, m_display);
|
m_screenSaver = new CXWindowsScreenSaver(this, m_display);
|
||||||
|
@ -172,9 +160,6 @@ CXWindowsScreen::closeDisplay()
|
||||||
{
|
{
|
||||||
CLock lock(&m_mutex);
|
CLock lock(&m_mutex);
|
||||||
|
|
||||||
// let subclass close down display
|
|
||||||
onCloseDisplay(m_display);
|
|
||||||
|
|
||||||
// done with screen saver
|
// done with screen saver
|
||||||
delete m_screenSaver;
|
delete m_screenSaver;
|
||||||
m_screenSaver = NULL;
|
m_screenSaver = NULL;
|
||||||
|
@ -209,8 +194,30 @@ CXWindowsScreen::getRoot() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CXWindowsScreen::getScreenShape(
|
CXWindowsScreen::initClipboards(Window window)
|
||||||
SInt32& x, SInt32& y, SInt32& w, SInt32& h) const
|
{
|
||||||
|
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);
|
assert(m_display != NULL);
|
||||||
|
|
||||||
|
@ -220,8 +227,35 @@ CXWindowsScreen::getScreenShape(
|
||||||
h = m_h;
|
h = m_h;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cursor
|
void
|
||||||
CXWindowsScreen::createBlankCursor() const
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsScreen::createBlankCursor()
|
||||||
{
|
{
|
||||||
// this seems just a bit more complicated than really necessary
|
// this seems just a bit more complicated than really necessary
|
||||||
|
|
||||||
|
@ -246,14 +280,18 @@ CXWindowsScreen::createBlankCursor() const
|
||||||
color.flags = DoRed | DoGreen | DoBlue;
|
color.flags = DoRed | DoGreen | DoBlue;
|
||||||
|
|
||||||
// make cursor from bitmap
|
// make cursor from bitmap
|
||||||
Cursor cursor = XCreatePixmapCursor(m_display, bitmap, bitmap,
|
m_cursor = XCreatePixmapCursor(m_display, bitmap, bitmap,
|
||||||
&color, &color, 0, 0);
|
&color, &color, 0, 0);
|
||||||
|
|
||||||
// don't need bitmap or the data anymore
|
// don't need bitmap or the data anymore
|
||||||
delete[] data;
|
delete[] data;
|
||||||
XFreePixmap(m_display, bitmap);
|
XFreePixmap(m_display, bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
return cursor;
|
Cursor
|
||||||
|
CXWindowsScreen::getBlankCursor() const
|
||||||
|
{
|
||||||
|
return m_cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -57,17 +57,31 @@ protected:
|
||||||
// is closed.
|
// is closed.
|
||||||
void closeDisplay();
|
void closeDisplay();
|
||||||
|
|
||||||
// get the opened screen, its shape, its root window. to get the
|
// get the opened screen and its root window. to get the display
|
||||||
// display create a CDisplayLock object passing this. while the
|
// create a CDisplayLock object passing this. while the object
|
||||||
// object exists no other threads may access the display. do not
|
// exists no other threads may access the display. do not save
|
||||||
// save the Display* beyond the lifetime of the CDisplayLock.
|
// the Display* beyond the lifetime of the CDisplayLock.
|
||||||
int getScreen() const;
|
int getScreen() const;
|
||||||
void getScreenShape(
|
|
||||||
SInt32& x, SInt32& y, SInt32& w, SInt32& h) const;
|
|
||||||
Window getRoot() const;
|
Window getRoot() const;
|
||||||
|
|
||||||
// create a cursor that is transparent everywhere
|
// initialize the clipboards
|
||||||
Cursor createBlankCursor() const;
|
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;
|
||||||
|
|
||||||
// wait for and get the next X event. cancellable.
|
// wait for and get the next X event. cancellable.
|
||||||
bool getEvent(XEvent*) const;
|
bool getEvent(XEvent*) const;
|
||||||
|
@ -88,19 +102,6 @@ protected:
|
||||||
CXWindowsScreenSaver*
|
CXWindowsScreenSaver*
|
||||||
getScreenSaver() const;
|
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;
|
|
||||||
|
|
||||||
// called by openDisplay() after onOpenDisplay() to create each clipboard
|
|
||||||
virtual CXWindowsClipboard*
|
|
||||||
createClipboard(ClipboardID) = 0;
|
|
||||||
|
|
||||||
// called by closeDisplay() to allow subclasses to clean up the display.
|
|
||||||
// the display is locked and passed to the subclass. note that the
|
|
||||||
// display may be NULL if the display has unexpectedly disconnected.
|
|
||||||
virtual void onCloseDisplay(Display*) = 0;
|
|
||||||
|
|
||||||
// called if the display is unexpectedly closing. default does nothing.
|
// called if the display is unexpectedly closing. default does nothing.
|
||||||
virtual void onUnexpectedClose();
|
virtual void onUnexpectedClose();
|
||||||
|
|
||||||
|
@ -108,6 +109,9 @@ protected:
|
||||||
virtual void onLostClipboard(ClipboardID) = 0;
|
virtual void onLostClipboard(ClipboardID) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// create the transparent cursor
|
||||||
|
void createBlankCursor();
|
||||||
|
|
||||||
// remove a timer without locking
|
// remove a timer without locking
|
||||||
void removeTimerNoLock(IJob*);
|
void removeTimerNoLock(IJob*);
|
||||||
|
|
||||||
|
@ -248,6 +252,9 @@ private:
|
||||||
// clipboards
|
// clipboards
|
||||||
CXWindowsClipboard* m_clipboard[kClipboardEnd];
|
CXWindowsClipboard* m_clipboard[kClipboardEnd];
|
||||||
|
|
||||||
|
// the transparent cursor
|
||||||
|
Cursor m_cursor;
|
||||||
|
|
||||||
// screen saver
|
// screen saver
|
||||||
CXWindowsScreenSaver* m_screenSaver;
|
CXWindowsScreenSaver* m_screenSaver;
|
||||||
|
|
||||||
|
|
|
@ -82,11 +82,6 @@ CMSWindowsPrimaryScreen::~CMSWindowsPrimaryScreen()
|
||||||
assert(m_hookLibrary != NULL);
|
assert(m_hookLibrary != NULL);
|
||||||
assert(m_window == NULL);
|
assert(m_window == NULL);
|
||||||
|
|
||||||
// uninstall screen saver hook
|
|
||||||
if (m_uninstallScreenSaver != NULL) {
|
|
||||||
m_uninstallScreenSaver();
|
|
||||||
}
|
|
||||||
|
|
||||||
// done with hook library
|
// done with hook library
|
||||||
FreeLibrary(m_hookLibrary);
|
FreeLibrary(m_hookLibrary);
|
||||||
}
|
}
|
||||||
|
@ -127,54 +122,74 @@ CMSWindowsPrimaryScreen::stop()
|
||||||
void
|
void
|
||||||
CMSWindowsPrimaryScreen::open()
|
CMSWindowsPrimaryScreen::open()
|
||||||
{
|
{
|
||||||
|
assert(m_window == NULL);
|
||||||
|
|
||||||
|
CClientInfo info;
|
||||||
|
try {
|
||||||
|
// initialize hook library
|
||||||
|
m_threadID = GetCurrentThreadId();
|
||||||
|
m_init(m_threadID);
|
||||||
|
|
||||||
// open the display
|
// open the display
|
||||||
openDisplay();
|
openDisplay();
|
||||||
|
|
||||||
|
// create and prepare our window
|
||||||
|
createWindow();
|
||||||
|
|
||||||
|
// set jump zones
|
||||||
|
m_setZone(info.m_x, info.m_y, info.m_w, info.m_h, info.m_zoneSize);
|
||||||
|
|
||||||
// initialize marks
|
// initialize marks
|
||||||
m_mark = 0;
|
m_mark = 0;
|
||||||
m_markReceived = 0;
|
m_markReceived = 0;
|
||||||
nextMark();
|
nextMark();
|
||||||
|
|
||||||
// save cursor pos
|
// collect screen info
|
||||||
POINT pos;
|
|
||||||
GetCursorPos(&pos);
|
|
||||||
m_x = pos.x;
|
|
||||||
m_y = pos.y;
|
|
||||||
|
|
||||||
// send screen info
|
|
||||||
CClientInfo info;
|
|
||||||
getScreenShape(info.m_x, info.m_y, info.m_w, info.m_h);
|
getScreenShape(info.m_x, info.m_y, info.m_w, info.m_h);
|
||||||
|
getCursorPos(info.m_mx, info.m_my);
|
||||||
info.m_zoneSize = getJumpZoneSize();
|
info.m_zoneSize = getJumpZoneSize();
|
||||||
info.m_mx = m_x;
|
|
||||||
info.m_my = m_y;
|
// save mouse position
|
||||||
m_receiver->onInfoChanged(info);
|
m_x = info.m_mx;
|
||||||
|
m_y = info.m_my;
|
||||||
|
|
||||||
// compute center pixel of primary screen
|
// compute center pixel of primary screen
|
||||||
m_xCenter = GetSystemMetrics(SM_CXSCREEN) >> 1;
|
getCursorCenter(m_xCenter, m_yCenter);
|
||||||
m_yCenter = GetSystemMetrics(SM_CYSCREEN) >> 1;
|
|
||||||
|
|
||||||
// get keyboard state
|
// get keyboard state
|
||||||
updateKeys();
|
updateKeys();
|
||||||
|
|
||||||
// set jump zones
|
// get notified of screen saver activation/deactivation
|
||||||
m_setZone(info.m_x, info.m_y, info.m_w, info.m_h, info.m_zoneSize);
|
installScreenSaver();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
close();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
// enter the screen
|
// enter the screen
|
||||||
enterNoWarp();
|
enterNoWarp();
|
||||||
|
|
||||||
|
// send screen info
|
||||||
|
m_receiver->onInfoChanged(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CMSWindowsPrimaryScreen::close()
|
CMSWindowsPrimaryScreen::close()
|
||||||
{
|
{
|
||||||
// close the display
|
uninstallScreenSaver();
|
||||||
|
destroyWindow();
|
||||||
closeDisplay();
|
closeDisplay();
|
||||||
|
m_cleanup();
|
||||||
|
m_threadID = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CMSWindowsPrimaryScreen::enter(SInt32 x, SInt32 y, bool forScreenSaver)
|
CMSWindowsPrimaryScreen::enter(SInt32 x, SInt32 y, bool forScreenSaver)
|
||||||
{
|
{
|
||||||
log((CLOG_INFO "entering primary at %d,%d", x, y));
|
log((CLOG_INFO "entering primary at %d,%d%s", x, y, forScreenSaver ? " for screen saver" : ""));
|
||||||
assert(m_active == true);
|
assert(m_active == true);
|
||||||
|
assert(m_window != NULL);
|
||||||
|
|
||||||
// enter the screen
|
// enter the screen
|
||||||
enterNoWarp();
|
enterNoWarp();
|
||||||
|
@ -190,12 +205,13 @@ CMSWindowsPrimaryScreen::leave()
|
||||||
{
|
{
|
||||||
log((CLOG_INFO "leaving primary"));
|
log((CLOG_INFO "leaving primary"));
|
||||||
assert(m_active == false);
|
assert(m_active == false);
|
||||||
|
assert(m_window != NULL);
|
||||||
|
|
||||||
// all messages prior to now are invalid
|
// all messages prior to now are invalid
|
||||||
nextMark();
|
nextMark();
|
||||||
|
|
||||||
// save active window, show ours, and grab mouse/keyboard
|
// show our window
|
||||||
if (!onLeave()) {
|
if (!showWindow()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,6 +245,48 @@ CMSWindowsPrimaryScreen::leave()
|
||||||
// local client now active
|
// local client now active
|
||||||
m_active = true;
|
m_active = true;
|
||||||
|
|
||||||
|
// make sure our idea of clipboard ownership is correct
|
||||||
|
checkClipboard();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsPrimaryScreen::reconfigure(UInt32 activeSides)
|
||||||
|
{
|
||||||
|
m_setSides(activeSides);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsPrimaryScreen::warpCursor(SInt32 x, SInt32 y)
|
||||||
|
{
|
||||||
|
// set the cursor position without generating an event
|
||||||
|
// FIXME -- doesn't this generate an event anyway?
|
||||||
|
SetCursorPos(x, y);
|
||||||
|
|
||||||
|
// save position as last position
|
||||||
|
m_x = x;
|
||||||
|
m_y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsPrimaryScreen::warpCursorToCenter()
|
||||||
|
{
|
||||||
|
// warp to center. the extra info tells the hook DLL to send
|
||||||
|
// SYNERGY_MSG_POST_WARP instead of SYNERGY_MSG_MOUSE_MOVE.
|
||||||
|
SInt32 x, y, w, h;
|
||||||
|
getScreenShape(x, y, w, h);
|
||||||
|
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE,
|
||||||
|
(DWORD)((65535.99 * (m_xCenter - x)) / (w - 1)),
|
||||||
|
(DWORD)((65535.99 * (m_yCenter - y)) / (h - 1)),
|
||||||
|
0,
|
||||||
|
0x12345678);
|
||||||
|
// FIXME -- ignore mouse until we get warp notification?
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsPrimaryScreen::checkClipboard()
|
||||||
|
{
|
||||||
// if we think we own the clipboard but we don't then somebody
|
// if we think we own the clipboard but we don't then somebody
|
||||||
// grabbed the clipboard on this screen without us knowing.
|
// grabbed the clipboard on this screen without us knowing.
|
||||||
// tell the server that this screen grabbed the clipboard.
|
// tell the server that this screen grabbed the clipboard.
|
||||||
|
@ -253,45 +311,13 @@ CMSWindowsPrimaryScreen::leave()
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CMSWindowsPrimaryScreen::reconfigure(UInt32 activeSides)
|
|
||||||
{
|
|
||||||
m_setSides(activeSides);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CMSWindowsPrimaryScreen::warpCursor(SInt32 x, SInt32 y)
|
|
||||||
{
|
|
||||||
// set the cursor position without generating an event
|
|
||||||
SetCursorPos(x, y);
|
|
||||||
|
|
||||||
// save position as last position
|
|
||||||
m_x = x;
|
|
||||||
m_y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CMSWindowsPrimaryScreen::warpCursorToCenter()
|
|
||||||
{
|
|
||||||
// warp to center. the extra info tells the hook DLL to send
|
|
||||||
// SYNERGY_MSG_POST_WARP instead of SYNERGY_MSG_MOUSE_MOVE.
|
|
||||||
SInt32 x, y, w, h;
|
|
||||||
getScreenShape(x, y, w, h);
|
|
||||||
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE,
|
|
||||||
(DWORD)((65535.99 * (m_xCenter - x)) / (w - 1)),
|
|
||||||
(DWORD)((65535.99 * (m_yCenter - y)) / (h - 1)),
|
|
||||||
0,
|
|
||||||
0x12345678);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CMSWindowsPrimaryScreen::setClipboard(ClipboardID /*id*/,
|
CMSWindowsPrimaryScreen::setClipboard(ClipboardID /*id*/,
|
||||||
const IClipboard* src)
|
const IClipboard* src)
|
||||||
{
|
{
|
||||||
|
// FIXME -- this is identical to CMSWindowsSecondaryScreen's code
|
||||||
assert(m_window != NULL);
|
assert(m_window != NULL);
|
||||||
|
|
||||||
CMSWindowsClipboard dst(m_window);
|
CMSWindowsClipboard dst(m_window);
|
||||||
|
@ -301,10 +327,12 @@ CMSWindowsPrimaryScreen::setClipboard(ClipboardID /*id*/,
|
||||||
void
|
void
|
||||||
CMSWindowsPrimaryScreen::grabClipboard(ClipboardID /*id*/)
|
CMSWindowsPrimaryScreen::grabClipboard(ClipboardID /*id*/)
|
||||||
{
|
{
|
||||||
|
// FIXME -- this is identical to CMSWindowsSecondaryScreen's code
|
||||||
assert(m_window != NULL);
|
assert(m_window != NULL);
|
||||||
|
|
||||||
CMSWindowsClipboard clipboard(m_window);
|
CMSWindowsClipboard clipboard(m_window);
|
||||||
if (clipboard.open(0)) {
|
if (clipboard.open(0)) {
|
||||||
|
// FIXME -- don't we need to empty it?
|
||||||
clipboard.close();
|
clipboard.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,6 +341,7 @@ void
|
||||||
CMSWindowsPrimaryScreen::getClipboard(ClipboardID /*id*/,
|
CMSWindowsPrimaryScreen::getClipboard(ClipboardID /*id*/,
|
||||||
IClipboard* dst) const
|
IClipboard* dst) const
|
||||||
{
|
{
|
||||||
|
// FIXME -- this is identical to CMSWindowsSecondaryScreen's code
|
||||||
assert(m_window != NULL);
|
assert(m_window != NULL);
|
||||||
|
|
||||||
CMSWindowsClipboard src(m_window);
|
CMSWindowsClipboard src(m_window);
|
||||||
|
@ -378,67 +407,6 @@ CMSWindowsPrimaryScreen::isLockedToScreen() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CMSWindowsPrimaryScreen::onOpenDisplay()
|
|
||||||
{
|
|
||||||
assert(m_window == NULL);
|
|
||||||
|
|
||||||
// save thread id. we'll need to pass this to the hook library.
|
|
||||||
m_threadID = GetCurrentThreadId();
|
|
||||||
|
|
||||||
// initialize hook library
|
|
||||||
m_init(m_threadID);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// install the screen saver hook
|
|
||||||
if (m_installScreenSaver != NULL) {
|
|
||||||
m_installScreenSaver();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the input desktop and switch to it
|
|
||||||
if (m_is95Family) {
|
|
||||||
if (!openDesktop()) {
|
|
||||||
throw XScreenOpenFailure();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!switchDesktop(openInputDesktop())) {
|
|
||||||
throw XScreenOpenFailure();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
m_cleanup();
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CMSWindowsPrimaryScreen::onCloseDisplay()
|
|
||||||
{
|
|
||||||
// disconnect from desktop
|
|
||||||
if (m_is95Family) {
|
|
||||||
closeDesktop();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
switchDesktop(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// uninstall the screen saver hook
|
|
||||||
if (m_uninstallScreenSaver != NULL) {
|
|
||||||
m_uninstallScreenSaver();
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleanup hook library
|
|
||||||
m_cleanup();
|
|
||||||
|
|
||||||
// clear thread id
|
|
||||||
m_threadID = 0;
|
|
||||||
|
|
||||||
assert(m_window == NULL);
|
|
||||||
assert(m_desk == NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CMSWindowsPrimaryScreen::onPreTranslate(MSG* msg)
|
CMSWindowsPrimaryScreen::onPreTranslate(MSG* msg)
|
||||||
{
|
{
|
||||||
|
@ -667,8 +635,7 @@ CMSWindowsPrimaryScreen::onEvent(HWND hwnd, UINT msg,
|
||||||
// do nothing if resolution hasn't changed
|
// do nothing if resolution hasn't changed
|
||||||
if (x != xOld || y != yOld || w != wOld || h != hOld) {
|
if (x != xOld || y != yOld || w != wOld || h != hOld) {
|
||||||
// recompute center pixel of primary screen
|
// recompute center pixel of primary screen
|
||||||
m_xCenter = GetSystemMetrics(SM_CXSCREEN) >> 1;
|
getCursorCenter(m_xCenter, m_yCenter);
|
||||||
m_yCenter = GetSystemMetrics(SM_CYSCREEN) >> 1;
|
|
||||||
|
|
||||||
// warp mouse to center if active
|
// warp mouse to center if active
|
||||||
if (m_active) {
|
if (m_active) {
|
||||||
|
@ -720,33 +687,14 @@ CMSWindowsPrimaryScreen::enterNoWarp()
|
||||||
m_setRelay(false);
|
m_setRelay(false);
|
||||||
|
|
||||||
// restore active window and hide our window
|
// restore active window and hide our window
|
||||||
onEnter();
|
hideWindow();
|
||||||
|
|
||||||
// all messages prior to now are invalid
|
// all messages prior to now are invalid
|
||||||
nextMark();
|
nextMark();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CMSWindowsPrimaryScreen::onEnter()
|
|
||||||
{
|
|
||||||
// restore the active window and hide our window. we can only set
|
|
||||||
// the active window for another thread if we first attach our input
|
|
||||||
// to that thread.
|
|
||||||
ReleaseCapture();
|
|
||||||
if (m_lastActiveWindow != NULL) {
|
|
||||||
DWORD myThread = GetCurrentThreadId();
|
|
||||||
if (AttachThreadInput(myThread, m_lastActiveThread, TRUE)) {
|
|
||||||
// FIXME -- shouldn't raise window if X-Mouse is enabled
|
|
||||||
// but i have no idea how to do that or check if enabled.
|
|
||||||
SetActiveWindow(m_lastActiveWindow);
|
|
||||||
AttachThreadInput(myThread, m_lastActiveThread, FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ShowWindow(m_window, SW_HIDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CMSWindowsPrimaryScreen::onLeave()
|
CMSWindowsPrimaryScreen::showWindow()
|
||||||
{
|
{
|
||||||
// remember the active window before we leave. GetActiveWindow()
|
// remember the active window before we leave. GetActiveWindow()
|
||||||
// will only return the active window for the thread's queue (i.e.
|
// will only return the active window for the thread's queue (i.e.
|
||||||
|
@ -776,6 +724,25 @@ CMSWindowsPrimaryScreen::onLeave()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsPrimaryScreen::hideWindow()
|
||||||
|
{
|
||||||
|
// restore the active window and hide our window. we can only set
|
||||||
|
// the active window for another thread if we first attach our input
|
||||||
|
// to that thread.
|
||||||
|
ReleaseCapture();
|
||||||
|
if (m_lastActiveWindow != NULL) {
|
||||||
|
DWORD myThread = GetCurrentThreadId();
|
||||||
|
if (AttachThreadInput(myThread, m_lastActiveThread, TRUE)) {
|
||||||
|
// FIXME -- shouldn't raise window if X-Mouse is enabled
|
||||||
|
// but i have no idea how to do that or check if enabled.
|
||||||
|
SetActiveWindow(m_lastActiveWindow);
|
||||||
|
AttachThreadInput(myThread, m_lastActiveThread, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ShowWindow(m_window, SW_HIDE);
|
||||||
|
}
|
||||||
|
|
||||||
SInt32
|
SInt32
|
||||||
CMSWindowsPrimaryScreen::getJumpZoneSize() const
|
CMSWindowsPrimaryScreen::getJumpZoneSize() const
|
||||||
{
|
{
|
||||||
|
@ -792,6 +759,55 @@ CMSWindowsPrimaryScreen::nextMark()
|
||||||
PostThreadMessage(m_threadID, SYNERGY_MSG_MARK, m_mark, 0);
|
PostThreadMessage(m_threadID, SYNERGY_MSG_MARK, m_mark, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsPrimaryScreen::createWindow()
|
||||||
|
{
|
||||||
|
// get the input desktop and switch to it
|
||||||
|
if (m_is95Family) {
|
||||||
|
if (!openDesktop()) {
|
||||||
|
throw XScreenOpenFailure();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!switchDesktop(openInputDesktop())) {
|
||||||
|
throw XScreenOpenFailure();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsPrimaryScreen::destroyWindow()
|
||||||
|
{
|
||||||
|
// disconnect from desktop
|
||||||
|
if (m_is95Family) {
|
||||||
|
closeDesktop();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switchDesktop(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(m_window == NULL);
|
||||||
|
assert(m_desk == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsPrimaryScreen::installScreenSaver()
|
||||||
|
{
|
||||||
|
// install the screen saver hook
|
||||||
|
if (m_installScreenSaver != NULL) {
|
||||||
|
m_installScreenSaver();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CMSWindowsPrimaryScreen::uninstallScreenSaver()
|
||||||
|
{
|
||||||
|
// uninstall the screen saver hook
|
||||||
|
if (m_uninstallScreenSaver != NULL) {
|
||||||
|
m_uninstallScreenSaver();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CMSWindowsPrimaryScreen::openDesktop()
|
CMSWindowsPrimaryScreen::openDesktop()
|
||||||
{
|
{
|
||||||
|
@ -835,7 +851,7 @@ CMSWindowsPrimaryScreen::closeDesktop()
|
||||||
if (m_window != NULL) {
|
if (m_window != NULL) {
|
||||||
// restore active window and hide ours
|
// restore active window and hide ours
|
||||||
if (m_active) {
|
if (m_active) {
|
||||||
onEnter();
|
hideWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
// first remove clipboard snooper
|
// first remove clipboard snooper
|
||||||
|
@ -866,7 +882,7 @@ CMSWindowsPrimaryScreen::switchDesktop(HDESK desk)
|
||||||
if (m_window != NULL) {
|
if (m_window != NULL) {
|
||||||
// restore active window and hide ours
|
// restore active window and hide ours
|
||||||
if (m_active) {
|
if (m_active) {
|
||||||
onEnter();
|
hideWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
// first remove clipboard snooper
|
// first remove clipboard snooper
|
||||||
|
@ -948,7 +964,7 @@ CMSWindowsPrimaryScreen::switchDesktop(HDESK desk)
|
||||||
|
|
||||||
// get active window and show ours
|
// get active window and show ours
|
||||||
if (m_active) {
|
if (m_active) {
|
||||||
onLeave();
|
showWindow();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// watch jump zones
|
// watch jump zones
|
||||||
|
|
|
@ -42,8 +42,8 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void enterNoWarp();
|
void enterNoWarp();
|
||||||
void onEnter();
|
bool showWindow();
|
||||||
bool onLeave();
|
void hideWindow();
|
||||||
|
|
||||||
SInt32 getJumpZoneSize() const;
|
SInt32 getJumpZoneSize() const;
|
||||||
|
|
||||||
|
@ -51,9 +51,23 @@ private:
|
||||||
// motion deltas while mouse is on secondary screen).
|
// motion deltas while mouse is on secondary screen).
|
||||||
void warpCursorToCenter();
|
void warpCursorToCenter();
|
||||||
|
|
||||||
|
// check clipboard ownership and, if necessary, tell the receiver
|
||||||
|
// of a grab.
|
||||||
|
void checkClipboard();
|
||||||
|
|
||||||
// discard posted messages
|
// discard posted messages
|
||||||
void nextMark();
|
void nextMark();
|
||||||
|
|
||||||
|
// create/destroy window
|
||||||
|
// also attach to desktop; this destroys and recreates the window
|
||||||
|
// as necessary.
|
||||||
|
void createWindow();
|
||||||
|
void destroyWindow();
|
||||||
|
|
||||||
|
// start/stop watch for screen saver changes
|
||||||
|
void installScreenSaver();
|
||||||
|
void uninstallScreenSaver();
|
||||||
|
|
||||||
// open/close desktop (for windows 95/98/me)
|
// open/close desktop (for windows 95/98/me)
|
||||||
bool openDesktop();
|
bool openDesktop();
|
||||||
void closeDesktop();
|
void closeDesktop();
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "CXWindowsUtil.h"
|
#include "CXWindowsUtil.h"
|
||||||
#include "CClipboard.h"
|
#include "CClipboard.h"
|
||||||
#include "ProtocolTypes.h"
|
#include "ProtocolTypes.h"
|
||||||
|
#include "XScreen.h"
|
||||||
#include "CThread.h"
|
#include "CThread.h"
|
||||||
#include "CLog.h"
|
#include "CLog.h"
|
||||||
#include "CStopwatch.h"
|
#include "CStopwatch.h"
|
||||||
|
@ -179,9 +180,9 @@ CXWindowsPrimaryScreen::run()
|
||||||
if (xevent.xmotion.send_event) {
|
if (xevent.xmotion.send_event) {
|
||||||
// we warped the mouse. discard events until we
|
// we warped the mouse. discard events until we
|
||||||
// find the matching sent event. see
|
// find the matching sent event. see
|
||||||
// warpCursorNoLockNoFlush() for where the events
|
// warpCursorNoFlush() for where the events are
|
||||||
// are sent. we discard the matching sent event
|
// sent. we discard the matching sent event and
|
||||||
// and can be sure we've skipped the warp event.
|
// can be sure we've skipped the warp event.
|
||||||
CDisplayLock display(this);
|
CDisplayLock display(this);
|
||||||
do {
|
do {
|
||||||
XMaskEvent(display, PointerMotionMask, &xevent);
|
XMaskEvent(display, PointerMotionMask, &xevent);
|
||||||
|
@ -210,7 +211,7 @@ CXWindowsPrimaryScreen::run()
|
||||||
xevent.xmotion.y_root - m_yCenter < -s_size ||
|
xevent.xmotion.y_root - m_yCenter < -s_size ||
|
||||||
xevent.xmotion.y_root - m_yCenter > s_size) {
|
xevent.xmotion.y_root - m_yCenter > s_size) {
|
||||||
CDisplayLock display(this);
|
CDisplayLock display(this);
|
||||||
warpCursorNoLockNoFlush(display, m_xCenter, m_yCenter);
|
warpCursorNoFlush(display, m_xCenter, m_yCenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// send event if mouse moved. do this after warping
|
// send event if mouse moved. do this after warping
|
||||||
|
@ -239,9 +240,25 @@ CXWindowsPrimaryScreen::stop()
|
||||||
void
|
void
|
||||||
CXWindowsPrimaryScreen::open()
|
CXWindowsPrimaryScreen::open()
|
||||||
{
|
{
|
||||||
|
assert(m_window == None);
|
||||||
|
|
||||||
|
CClientInfo info;
|
||||||
|
try {
|
||||||
// open the display
|
// open the display
|
||||||
openDisplay();
|
openDisplay();
|
||||||
|
|
||||||
|
// create and prepare our window
|
||||||
|
createWindow();
|
||||||
|
|
||||||
|
// get the display
|
||||||
|
CDisplayLock display(this);
|
||||||
|
|
||||||
|
// initialize the clipboards
|
||||||
|
initClipboards(m_window);
|
||||||
|
|
||||||
|
// miscellaneous initialization
|
||||||
|
m_atomScreenSaver = XInternAtom(display, "SCREENSAVER", False);
|
||||||
|
|
||||||
// check for peculiarities
|
// check for peculiarities
|
||||||
// FIXME -- may have to get these from some database
|
// FIXME -- may have to get these from some database
|
||||||
m_numLockHalfDuplex = false;
|
m_numLockHalfDuplex = false;
|
||||||
|
@ -249,59 +266,41 @@ CXWindowsPrimaryScreen::open()
|
||||||
// m_numLockHalfDuplex = true;
|
// m_numLockHalfDuplex = true;
|
||||||
// m_capsLockHalfDuplex = true;
|
// m_capsLockHalfDuplex = true;
|
||||||
|
|
||||||
// get screen shape
|
// collect screen info
|
||||||
SInt32 x, y, w, h;
|
getScreenShape(info.m_x, info.m_y, info.m_w, info.m_h);
|
||||||
getScreenShape(x, y, w, h);
|
getCursorPos(info.m_mx, info.m_my);
|
||||||
|
info.m_zoneSize = getJumpZoneSize();
|
||||||
|
|
||||||
{
|
// save mouse position
|
||||||
CDisplayLock display(this);
|
m_x = info.m_mx;
|
||||||
|
m_y = info.m_my;
|
||||||
|
|
||||||
// get notified of screen saver activation/deactivation
|
// compute center pixel of primary screen
|
||||||
m_atomScreenSaver = XInternAtom(display, "SCREENSAVER", False);
|
getCursorCenter(m_xCenter, m_yCenter);
|
||||||
getScreenSaver()->setNotify(m_window);
|
|
||||||
|
|
||||||
// update key state
|
// update key state
|
||||||
updateModifierMap(display);
|
updateModifierMap(display);
|
||||||
|
|
||||||
// get mouse position
|
// get notified of screen saver activation/deactivation
|
||||||
Window root, window;
|
installScreenSaver();
|
||||||
int mx, my, xWindow, yWindow;
|
}
|
||||||
unsigned int mask;
|
catch (...) {
|
||||||
if (!XQueryPointer(display, m_window, &root, &window,
|
close();
|
||||||
&mx, &my, &xWindow, &yWindow, &mask)) {
|
throw;
|
||||||
mx = w >> 1;
|
|
||||||
my = h >> 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// save mouse position
|
// enter the screen
|
||||||
m_x = mx;
|
enterNoWarp();
|
||||||
m_y = my;
|
|
||||||
}
|
|
||||||
|
|
||||||
// save position of center of screen
|
|
||||||
m_xCenter = x + (w >> 1);
|
|
||||||
m_yCenter = y + (h >> 1);
|
|
||||||
|
|
||||||
// send screen info
|
// send screen info
|
||||||
CClientInfo info;
|
|
||||||
info.m_x = x;
|
|
||||||
info.m_y = y;
|
|
||||||
info.m_w = w;
|
|
||||||
info.m_h = h;
|
|
||||||
info.m_zoneSize = 1;
|
|
||||||
info.m_mx = m_x;
|
|
||||||
info.m_my = m_y;
|
|
||||||
m_receiver->onInfoChanged(info);
|
m_receiver->onInfoChanged(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CXWindowsPrimaryScreen::close()
|
CXWindowsPrimaryScreen::close()
|
||||||
{
|
{
|
||||||
// stop being notified of screen saver activation/deactivation
|
uninstallScreenSaver();
|
||||||
getScreenSaver()->setNotify(None);
|
destroyWindow();
|
||||||
m_atomScreenSaver = None;
|
|
||||||
|
|
||||||
// close the display
|
|
||||||
closeDisplay();
|
closeDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,24 +311,20 @@ CXWindowsPrimaryScreen::enter(SInt32 x, SInt32 y, bool forScreenSaver)
|
||||||
assert(m_active == true);
|
assert(m_active == true);
|
||||||
assert(m_window != None);
|
assert(m_window != None);
|
||||||
|
|
||||||
CDisplayLock display(this);
|
// enter the screen
|
||||||
|
enterNoWarp();
|
||||||
// unmap the grab window. this also ungrabs the mouse and keyboard.
|
|
||||||
XUnmapWindow(display, m_window);
|
|
||||||
|
|
||||||
// warp to requested location
|
// warp to requested location
|
||||||
if (!forScreenSaver) {
|
if (!forScreenSaver) {
|
||||||
warpCursorNoLock(display, x, y);
|
warpCursor(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// redirect input to root window. do not warp the mouse because
|
// redirect input to root window. do not warp the mouse because
|
||||||
// that will deactivate the screen saver.
|
// that will deactivate the screen saver.
|
||||||
else {
|
else {
|
||||||
|
CDisplayLock display(this);
|
||||||
XSetInputFocus(display, PointerRoot, PointerRoot, CurrentTime);
|
XSetInputFocus(display, PointerRoot, PointerRoot, CurrentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// not active anymore
|
|
||||||
m_active = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -339,6 +334,116 @@ CXWindowsPrimaryScreen::leave()
|
||||||
assert(m_active == false);
|
assert(m_active == false);
|
||||||
assert(m_window != None);
|
assert(m_window != None);
|
||||||
|
|
||||||
|
// show our window
|
||||||
|
if (!showWindow()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// warp mouse to center
|
||||||
|
warpCursorToCenter();
|
||||||
|
// FIXME -- this doesn't match the win32 version. that just does
|
||||||
|
// the warp while we flush the input queue until we find the warp
|
||||||
|
// and we discard that too. would prefer to at least match our
|
||||||
|
// own warping when we receive MotionNotify; that just does the
|
||||||
|
// warp. however, the win32 version sometimes stutters when
|
||||||
|
// leaving and perhaps this is why. hmm, win32 does ignore the
|
||||||
|
// events until after the warp (via the mark).
|
||||||
|
|
||||||
|
// local client now active
|
||||||
|
m_active = true;
|
||||||
|
|
||||||
|
// make sure our idea of clipboard ownership is correct
|
||||||
|
checkClipboard();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsPrimaryScreen::reconfigure(UInt32)
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsPrimaryScreen::warpCursor(SInt32 x, SInt32 y)
|
||||||
|
{
|
||||||
|
CDisplayLock display(this);
|
||||||
|
|
||||||
|
// warp mouse
|
||||||
|
warpCursorNoFlush(display, x, y);
|
||||||
|
|
||||||
|
// remove all input events before and including warp
|
||||||
|
XEvent event;
|
||||||
|
while (XCheckMaskEvent(display, PointerMotionMask |
|
||||||
|
ButtonPressMask | ButtonReleaseMask |
|
||||||
|
KeyPressMask | KeyReleaseMask |
|
||||||
|
KeymapStateMask,
|
||||||
|
&event)) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
// save position as last position
|
||||||
|
m_x = x;
|
||||||
|
m_y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsPrimaryScreen::warpCursorToCenter()
|
||||||
|
{
|
||||||
|
warpCursor(m_xCenter, m_yCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsPrimaryScreen::warpCursorNoFlush(
|
||||||
|
Display* display, SInt32 x, SInt32 y)
|
||||||
|
{
|
||||||
|
assert(display != NULL);
|
||||||
|
assert(m_window != None);
|
||||||
|
|
||||||
|
// send an event that we can recognize before the mouse warp
|
||||||
|
XEvent eventBefore;
|
||||||
|
eventBefore.type = MotionNotify;
|
||||||
|
eventBefore.xmotion.display = display;
|
||||||
|
eventBefore.xmotion.window = m_window;
|
||||||
|
eventBefore.xmotion.root = getRoot();
|
||||||
|
eventBefore.xmotion.subwindow = m_window;
|
||||||
|
eventBefore.xmotion.time = CurrentTime;
|
||||||
|
eventBefore.xmotion.x = x;
|
||||||
|
eventBefore.xmotion.y = y;
|
||||||
|
eventBefore.xmotion.x_root = x;
|
||||||
|
eventBefore.xmotion.y_root = y;
|
||||||
|
eventBefore.xmotion.state = 0;
|
||||||
|
eventBefore.xmotion.is_hint = False;
|
||||||
|
eventBefore.xmotion.same_screen = True;
|
||||||
|
XEvent eventAfter = eventBefore;
|
||||||
|
XSendEvent(display, m_window, False, 0, &eventBefore);
|
||||||
|
|
||||||
|
// warp mouse
|
||||||
|
XWarpPointer(display, None, getRoot(), 0, 0, 0, 0, x, y);
|
||||||
|
|
||||||
|
// send an event that we can recognize after the mouse warp
|
||||||
|
XSendEvent(display, m_window, False, 0, &eventAfter);
|
||||||
|
XSync(display, False);
|
||||||
|
|
||||||
|
log((CLOG_DEBUG2 "warped to %d,%d", x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsPrimaryScreen::checkClipboard()
|
||||||
|
{
|
||||||
|
// do nothing, we're always up to date
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CXWindowsPrimaryScreen::enterNoWarp()
|
||||||
|
{
|
||||||
|
m_active = false;
|
||||||
|
hideWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CXWindowsPrimaryScreen::showWindow()
|
||||||
|
{
|
||||||
CDisplayLock display(this);
|
CDisplayLock display(this);
|
||||||
|
|
||||||
// raise and show the input window
|
// raise and show the input window
|
||||||
|
@ -387,82 +492,89 @@ CXWindowsPrimaryScreen::leave()
|
||||||
} while (result != GrabSuccess);
|
} while (result != GrabSuccess);
|
||||||
log((CLOG_DEBUG1 "grabbed pointer and keyboard"));
|
log((CLOG_DEBUG1 "grabbed pointer and keyboard"));
|
||||||
|
|
||||||
// warp mouse to center
|
|
||||||
warpCursorNoLock(display, m_xCenter, m_yCenter);
|
|
||||||
|
|
||||||
// local client now active
|
|
||||||
m_active = true;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CXWindowsPrimaryScreen::reconfigure(UInt32)
|
CXWindowsPrimaryScreen::hideWindow()
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CXWindowsPrimaryScreen::warpCursor(SInt32 x, SInt32 y)
|
|
||||||
{
|
{
|
||||||
CDisplayLock display(this);
|
CDisplayLock display(this);
|
||||||
warpCursorNoLock(display, x, y);
|
|
||||||
|
// unmap the grab window. this also ungrabs the mouse and keyboard.
|
||||||
|
XUnmapWindow(display, m_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
SInt32
|
||||||
|
CXWindowsPrimaryScreen::getJumpZoneSize() const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CXWindowsPrimaryScreen::warpCursorNoLock(Display* display, SInt32 x, SInt32 y)
|
CXWindowsPrimaryScreen::createWindow()
|
||||||
{
|
{
|
||||||
// warp mouse
|
assert(m_window == None);
|
||||||
warpCursorNoLockNoFlush(display, x, y);
|
|
||||||
|
|
||||||
// remove all input events before and including warp
|
// get size of screen
|
||||||
XEvent event;
|
SInt32 x, y, w, h;
|
||||||
while (XCheckMaskEvent(display, PointerMotionMask |
|
getScreenShape(x, y, w, h);
|
||||||
|
|
||||||
|
// grab window attributes. this window is used to capture user
|
||||||
|
// input when the user is focused on another client. don't let
|
||||||
|
// the window manager mess with it.
|
||||||
|
XSetWindowAttributes attr;
|
||||||
|
attr.event_mask = PointerMotionMask |
|
||||||
ButtonPressMask | ButtonReleaseMask |
|
ButtonPressMask | ButtonReleaseMask |
|
||||||
KeyPressMask | KeyReleaseMask |
|
KeyPressMask | KeyReleaseMask |
|
||||||
KeymapStateMask,
|
KeymapStateMask | PropertyChangeMask;
|
||||||
&event)) {
|
attr.do_not_propagate_mask = 0;
|
||||||
// do nothing
|
attr.override_redirect = True;
|
||||||
}
|
attr.cursor = getBlankCursor();
|
||||||
|
|
||||||
// save position as last position
|
// create the grab window
|
||||||
m_x = x;
|
CDisplayLock display(this);
|
||||||
m_y = y;
|
m_window = XCreateWindow(display, getRoot(),
|
||||||
|
x, y, w, h, 0, 0,
|
||||||
|
InputOnly, CopyFromParent,
|
||||||
|
CWDontPropagate | CWEventMask |
|
||||||
|
CWOverrideRedirect | CWCursor,
|
||||||
|
&attr);
|
||||||
|
if (m_window == None) {
|
||||||
|
throw XScreenOpenFailure();
|
||||||
|
}
|
||||||
|
log((CLOG_DEBUG "window is 0x%08x", m_window));
|
||||||
|
|
||||||
|
// start watching for events on other windows
|
||||||
|
selectEvents(display, getRoot());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CXWindowsPrimaryScreen::warpCursorNoLockNoFlush(
|
CXWindowsPrimaryScreen::destroyWindow()
|
||||||
Display* display, SInt32 x, SInt32 y)
|
|
||||||
{
|
{
|
||||||
assert(display != NULL);
|
// display can be NULL if the server unexpectedly disconnected
|
||||||
assert(m_window != None);
|
CDisplayLock display(this);
|
||||||
|
if (display != NULL && m_window != None) {
|
||||||
|
XDestroyWindow(display, m_window);
|
||||||
|
}
|
||||||
|
m_window = None;
|
||||||
|
}
|
||||||
|
|
||||||
// send an event that we can recognize before the mouse warp
|
void
|
||||||
XEvent eventBefore;
|
CXWindowsPrimaryScreen::installScreenSaver()
|
||||||
eventBefore.type = MotionNotify;
|
{
|
||||||
eventBefore.xmotion.display = display;
|
assert(getScreenSaver() != NULL);
|
||||||
eventBefore.xmotion.window = m_window;
|
|
||||||
eventBefore.xmotion.root = getRoot();
|
|
||||||
eventBefore.xmotion.subwindow = m_window;
|
|
||||||
eventBefore.xmotion.time = CurrentTime;
|
|
||||||
eventBefore.xmotion.x = x;
|
|
||||||
eventBefore.xmotion.y = y;
|
|
||||||
eventBefore.xmotion.x_root = x;
|
|
||||||
eventBefore.xmotion.y_root = y;
|
|
||||||
eventBefore.xmotion.state = 0;
|
|
||||||
eventBefore.xmotion.is_hint = False;
|
|
||||||
eventBefore.xmotion.same_screen = True;
|
|
||||||
XEvent eventAfter = eventBefore;
|
|
||||||
XSendEvent(display, m_window, False, 0, &eventBefore);
|
|
||||||
|
|
||||||
// warp mouse
|
getScreenSaver()->setNotify(m_window);
|
||||||
XWarpPointer(display, None, getRoot(), 0, 0, 0, 0, x, y);
|
}
|
||||||
|
|
||||||
// send an event that we can recognize after the mouse warp
|
void
|
||||||
XSendEvent(display, m_window, False, 0, &eventAfter);
|
CXWindowsPrimaryScreen::uninstallScreenSaver()
|
||||||
XSync(display, False);
|
{
|
||||||
|
// stop being notified of screen saver activation/deactivation
|
||||||
log((CLOG_DEBUG2 "warped to %d,%d", x, y));
|
if (getScreenSaver() != NULL) {
|
||||||
|
getScreenSaver()->setNotify(None);
|
||||||
|
}
|
||||||
|
m_atomScreenSaver = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -491,7 +603,6 @@ CXWindowsPrimaryScreen::getToggleMask() const
|
||||||
CDisplayLock display(this);
|
CDisplayLock display(this);
|
||||||
|
|
||||||
// query the pointer to get the keyboard state
|
// query the pointer to get the keyboard state
|
||||||
// FIXME -- is there a better way to do this?
|
|
||||||
Window root, window;
|
Window root, window;
|
||||||
int xRoot, yRoot, xWindow, yWindow;
|
int xRoot, yRoot, xWindow, yWindow;
|
||||||
unsigned int state;
|
unsigned int state;
|
||||||
|
@ -548,56 +659,6 @@ CXWindowsPrimaryScreen::isLockedToScreen() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CXWindowsPrimaryScreen::onOpenDisplay(Display* display)
|
|
||||||
{
|
|
||||||
assert(m_window == None);
|
|
||||||
|
|
||||||
// get size of screen
|
|
||||||
SInt32 x, y, w, h;
|
|
||||||
getScreenShape(x, y, w, h);
|
|
||||||
|
|
||||||
// create the grab window. this window is used to capture user
|
|
||||||
// input when the user is focussed on another client. don't let
|
|
||||||
// the window manager mess with it.
|
|
||||||
XSetWindowAttributes attr;
|
|
||||||
attr.event_mask = PointerMotionMask |// PointerMotionHintMask |
|
|
||||||
ButtonPressMask | ButtonReleaseMask |
|
|
||||||
KeyPressMask | KeyReleaseMask |
|
|
||||||
KeymapStateMask | PropertyChangeMask;
|
|
||||||
attr.do_not_propagate_mask = 0;
|
|
||||||
attr.override_redirect = True;
|
|
||||||
attr.cursor = createBlankCursor();
|
|
||||||
m_window = XCreateWindow(display, getRoot(), x, y, w, h, 0, 0,
|
|
||||||
InputOnly, CopyFromParent,
|
|
||||||
CWDontPropagate | CWEventMask |
|
|
||||||
CWOverrideRedirect | CWCursor,
|
|
||||||
&attr);
|
|
||||||
log((CLOG_DEBUG "window is 0x%08x", m_window));
|
|
||||||
|
|
||||||
// start watching for events on other windows
|
|
||||||
selectEvents(display, getRoot());
|
|
||||||
}
|
|
||||||
|
|
||||||
CXWindowsClipboard*
|
|
||||||
CXWindowsPrimaryScreen::createClipboard(ClipboardID id)
|
|
||||||
{
|
|
||||||
CDisplayLock display(this);
|
|
||||||
return new CXWindowsClipboard(display, m_window, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CXWindowsPrimaryScreen::onCloseDisplay(Display* display)
|
|
||||||
{
|
|
||||||
assert(m_window != None);
|
|
||||||
|
|
||||||
// destroy window
|
|
||||||
if (display != NULL) {
|
|
||||||
XDestroyWindow(display, m_window);
|
|
||||||
}
|
|
||||||
m_window = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CXWindowsPrimaryScreen::onUnexpectedClose()
|
CXWindowsPrimaryScreen::onUnexpectedClose()
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,21 +30,35 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// CXWindowsScreen overrides
|
// CXWindowsScreen overrides
|
||||||
virtual void onOpenDisplay(Display*);
|
|
||||||
virtual CXWindowsClipboard*
|
|
||||||
createClipboard(ClipboardID);
|
|
||||||
virtual void onCloseDisplay(Display*);
|
|
||||||
virtual void onUnexpectedClose();
|
virtual void onUnexpectedClose();
|
||||||
virtual void onLostClipboard(ClipboardID);
|
virtual void onLostClipboard(ClipboardID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void selectEvents(Display*, Window) const;
|
void selectEvents(Display*, Window) const;
|
||||||
void doSelectEvents(Display*, Window) const;
|
void doSelectEvents(Display*, Window) const;
|
||||||
void warpCursorNoLock(Display*,
|
|
||||||
SInt32 xAbsolute, SInt32 yAbsolute);
|
void enterNoWarp();
|
||||||
void warpCursorNoLockNoFlush(Display*,
|
bool showWindow();
|
||||||
|
void hideWindow();
|
||||||
|
|
||||||
|
SInt32 getJumpZoneSize() const;
|
||||||
|
|
||||||
|
void warpCursorToCenter();
|
||||||
|
void warpCursorNoFlush(Display*,
|
||||||
SInt32 xAbsolute, SInt32 yAbsolute);
|
SInt32 xAbsolute, SInt32 yAbsolute);
|
||||||
|
|
||||||
|
// check clipboard ownership and, if necessary, tell the receiver
|
||||||
|
// of a grab.
|
||||||
|
void checkClipboard();
|
||||||
|
|
||||||
|
// create/destroy window
|
||||||
|
void createWindow();
|
||||||
|
void destroyWindow();
|
||||||
|
|
||||||
|
// start/stop watch for screen saver changes
|
||||||
|
void installScreenSaver();
|
||||||
|
void uninstallScreenSaver();
|
||||||
|
|
||||||
KeyModifierMask mapModifier(unsigned int state) const;
|
KeyModifierMask mapModifier(unsigned int state) const;
|
||||||
KeyID mapKey(XKeyEvent*) const;
|
KeyID mapKey(XKeyEvent*) const;
|
||||||
ButtonID mapButton(unsigned int button) const;
|
ButtonID mapButton(unsigned int button) const;
|
||||||
|
|
Loading…
Reference in New Issue