2002-08-02 19:57:46 +00:00
|
|
|
/*
|
|
|
|
* synergy -- mouse and keyboard sharing utility
|
|
|
|
* Copyright (C) 2002 Chris Schoeneman
|
|
|
|
*
|
|
|
|
* This package is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* found in the file COPYING that should have accompanied this file.
|
|
|
|
*
|
|
|
|
* This package is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*/
|
|
|
|
|
2001-11-19 00:33:36 +00:00
|
|
|
#include "CMSWindowsScreen.h"
|
2002-07-15 15:01:36 +00:00
|
|
|
#include "CMSWindowsClipboard.h"
|
2002-06-23 21:53:31 +00:00
|
|
|
#include "CMSWindowsScreenSaver.h"
|
2002-07-15 15:01:36 +00:00
|
|
|
#include "CClipboard.h"
|
|
|
|
#include "IMSWindowsScreenEventHandler.h"
|
|
|
|
#include "IScreenReceiver.h"
|
2001-11-19 00:33:36 +00:00
|
|
|
#include "CThread.h"
|
|
|
|
#include "CLock.h"
|
|
|
|
#include "TMethodJob.h"
|
|
|
|
#include "CLog.h"
|
|
|
|
#include "CString.h"
|
2003-01-04 22:01:32 +00:00
|
|
|
#include "CStringUtil.h"
|
|
|
|
#include "CArchMiscWindows.h"
|
2002-06-10 22:06:45 +00:00
|
|
|
#include <cstring>
|
2003-02-16 19:50:36 +00:00
|
|
|
#include <malloc.h>
|
|
|
|
#include <tchar.h>
|
2001-11-19 00:33:36 +00:00
|
|
|
|
2002-06-19 17:03:29 +00:00
|
|
|
//
|
2002-07-15 15:01:36 +00:00
|
|
|
// add backwards compatible multihead support (and suppress bogus warning)
|
2002-06-19 17:03:29 +00:00
|
|
|
//
|
|
|
|
#pragma warning(push)
|
|
|
|
#pragma warning(disable: 4706) // assignment within conditional
|
|
|
|
#define COMPILE_MULTIMON_STUBS
|
|
|
|
#include <multimon.h>
|
|
|
|
#pragma warning(pop)
|
|
|
|
|
2001-11-19 00:33:36 +00:00
|
|
|
//
|
|
|
|
// CMSWindowsScreen
|
|
|
|
//
|
|
|
|
|
|
|
|
HINSTANCE CMSWindowsScreen::s_instance = NULL;
|
2001-11-25 18:32:41 +00:00
|
|
|
CMSWindowsScreen* CMSWindowsScreen::s_screen = NULL;
|
2001-11-19 00:33:36 +00:00
|
|
|
|
2002-07-15 15:01:36 +00:00
|
|
|
CMSWindowsScreen::CMSWindowsScreen(IScreenReceiver* receiver,
|
|
|
|
IMSWindowsScreenEventHandler* eventHandler) :
|
|
|
|
m_receiver(receiver),
|
|
|
|
m_eventHandler(eventHandler),
|
|
|
|
m_class(NULL),
|
|
|
|
m_icon(NULL),
|
2002-06-10 22:06:45 +00:00
|
|
|
m_cursor(NULL),
|
2003-01-04 22:01:32 +00:00
|
|
|
m_is95Family(CArchMiscWindows::isWindows95Family()),
|
2002-07-15 15:01:36 +00:00
|
|
|
m_window(NULL),
|
2002-06-19 17:03:29 +00:00
|
|
|
m_x(0), m_y(0),
|
2002-06-10 22:06:45 +00:00
|
|
|
m_w(0), m_h(0),
|
2002-07-15 15:01:36 +00:00
|
|
|
m_multimon(false),
|
|
|
|
m_threadID(0),
|
|
|
|
m_lastThreadID(0),
|
|
|
|
m_nextClipboardWindow(NULL),
|
Fixed several win32 bugs. First, synergy wasn't forwarding mouse
events to other hook functions, which broke some tools like objectbar.
Second, windows key processing was fixed. Previously pressing and
release the key would only send a press event, locking the user onto
the client window; also, the win32 server treated as a Meta modifier
instead of a Super modifier, which broke any use of it as any kind of
modifier key. Third, added hacks to support several key combinations
on windows 95/98/me that are treated specially by windows, including
Alt+Tab, Alt+Shift+Tab, Alt+Esc, Alt+Shift+Esc, Ctrl+Esc, and any
combination using the windows key like Win+E and Win+F but not
Ctrl+Alt+Del. Fourth, scroll lock only locking to the client (which
only happened when using a synergy server on windows) has been fixed;
unfortunately the solution causes a lot of screen redraws for some
reason. Finally, there's been a fix to clipboard handling that may
or may not fix a problem where the clipboard would stop transferring
between systems after a little while. I can't be sure if it fixes
the problem because I can't reproduce the problem.
2003-04-13 14:59:53 +00:00
|
|
|
m_ownClipboard(false),
|
2002-07-15 15:01:36 +00:00
|
|
|
m_timer(0),
|
|
|
|
m_desk(NULL),
|
|
|
|
m_deskName(),
|
|
|
|
m_hookLibrary(NULL),
|
|
|
|
m_installScreensaver(NULL),
|
|
|
|
m_uninstallScreensaver(NULL),
|
|
|
|
m_screensaver(NULL),
|
2003-05-17 20:58:27 +00:00
|
|
|
m_screensaverNotify(false),
|
|
|
|
m_inaccessibleDesktop(false)
|
2001-11-19 00:33:36 +00:00
|
|
|
{
|
2002-07-15 15:01:36 +00:00
|
|
|
assert(s_screen == NULL);
|
|
|
|
assert(m_receiver != NULL);
|
|
|
|
assert(m_eventHandler != NULL);
|
|
|
|
|
2001-11-25 18:32:41 +00:00
|
|
|
s_screen = this;
|
2002-07-15 15:01:36 +00:00
|
|
|
|
|
|
|
// make sure this thread has a message queue
|
|
|
|
MSG dummy;
|
|
|
|
PeekMessage(&dummy, NULL, WM_USER, WM_USER, PM_NOREMOVE);
|
2001-11-19 00:33:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CMSWindowsScreen::~CMSWindowsScreen()
|
|
|
|
{
|
2002-07-15 15:01:36 +00:00
|
|
|
assert(s_screen != NULL);
|
|
|
|
assert(m_class == 0);
|
|
|
|
|
2001-11-25 18:32:41 +00:00
|
|
|
s_screen = NULL;
|
2001-11-19 00:33:36 +00:00
|
|
|
}
|
|
|
|
|
2002-06-10 22:06:45 +00:00
|
|
|
void
|
2002-06-17 13:31:21 +00:00
|
|
|
CMSWindowsScreen::init(HINSTANCE instance)
|
2001-11-19 00:33:36 +00:00
|
|
|
{
|
|
|
|
s_instance = instance;
|
|
|
|
}
|
|
|
|
|
2002-07-15 15:01:36 +00:00
|
|
|
HWND
|
|
|
|
CMSWindowsScreen::openDesktop()
|
2001-11-19 00:33:36 +00:00
|
|
|
{
|
2002-07-15 15:01:36 +00:00
|
|
|
// save thread id
|
|
|
|
m_threadID = GetCurrentThreadId();
|
2002-05-22 17:08:37 +00:00
|
|
|
|
2002-07-15 15:01:36 +00:00
|
|
|
// get the input desktop and switch to it
|
|
|
|
if (!switchDesktop(openInputDesktop())) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2001-11-19 00:33:36 +00:00
|
|
|
|
2002-07-15 15:01:36 +00:00
|
|
|
// poll input desktop to see if it changes (onPreDispatch()
|
Fixed several win32 bugs. First, synergy wasn't forwarding mouse
events to other hook functions, which broke some tools like objectbar.
Second, windows key processing was fixed. Previously pressing and
release the key would only send a press event, locking the user onto
the client window; also, the win32 server treated as a Meta modifier
instead of a Super modifier, which broke any use of it as any kind of
modifier key. Third, added hacks to support several key combinations
on windows 95/98/me that are treated specially by windows, including
Alt+Tab, Alt+Shift+Tab, Alt+Esc, Alt+Shift+Esc, Ctrl+Esc, and any
combination using the windows key like Win+E and Win+F but not
Ctrl+Alt+Del. Fourth, scroll lock only locking to the client (which
only happened when using a synergy server on windows) has been fixed;
unfortunately the solution causes a lot of screen redraws for some
reason. Finally, there's been a fix to clipboard handling that may
or may not fix a problem where the clipboard would stop transferring
between systems after a little while. I can't be sure if it fixes
the problem because I can't reproduce the problem.
2003-04-13 14:59:53 +00:00
|
|
|
// handles WM_TIMER). this is also used for polling other
|
|
|
|
// stuff.
|
|
|
|
m_timer = SetTimer(NULL, 0, 200, NULL);
|
2002-07-15 15:01:36 +00:00
|
|
|
|
|
|
|
return m_window;
|
2001-11-19 00:33:36 +00:00
|
|
|
}
|
|
|
|
|
2002-06-10 22:06:45 +00:00
|
|
|
void
|
2002-07-15 15:01:36 +00:00
|
|
|
CMSWindowsScreen::closeDesktop()
|
2001-11-19 00:33:36 +00:00
|
|
|
{
|
2002-07-15 15:01:36 +00:00
|
|
|
// remove timer
|
|
|
|
if (m_timer != 0) {
|
|
|
|
KillTimer(NULL, m_timer);
|
2003-03-12 22:34:07 +00:00
|
|
|
m_timer = 0;
|
|
|
|
}
|
|
|
|
if (m_oneShotTimer != 0) {
|
|
|
|
KillTimer(NULL, m_oneShotTimer);
|
|
|
|
m_oneShotTimer = 0;
|
2002-07-15 15:01:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// disconnect from desktop
|
|
|
|
switchDesktop(NULL);
|
|
|
|
|
|
|
|
// clear thread id
|
|
|
|
m_threadID = 0;
|
|
|
|
|
|
|
|
assert(m_window == NULL);
|
|
|
|
assert(m_desk == NULL);
|
2001-11-19 00:33:36 +00:00
|
|
|
}
|
|
|
|
|
2003-03-12 22:34:07 +00:00
|
|
|
UInt32
|
|
|
|
CMSWindowsScreen::addOneShotTimer(double timeout)
|
|
|
|
{
|
|
|
|
// FIXME -- support multiple one-shot timers
|
|
|
|
if (m_oneShotTimer != 0) {
|
|
|
|
KillTimer(NULL, m_oneShotTimer);
|
|
|
|
}
|
|
|
|
m_oneShotTimer = SetTimer(NULL, 0,
|
|
|
|
static_cast<UINT>(1000.0 * timeout), NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-07-12 20:41:23 +00:00
|
|
|
bool
|
2002-07-15 15:01:36 +00:00
|
|
|
CMSWindowsScreen::isMultimon() const
|
|
|
|
{
|
|
|
|
return m_multimon;
|
|
|
|
}
|
|
|
|
|
|
|
|
HINSTANCE
|
|
|
|
CMSWindowsScreen::getInstance()
|
2002-07-12 20:41:23 +00:00
|
|
|
{
|
2002-07-15 15:01:36 +00:00
|
|
|
return s_instance;
|
2002-07-12 20:41:23 +00:00
|
|
|
}
|
|
|
|
|
2002-06-10 22:06:45 +00:00
|
|
|
void
|
2002-07-15 15:01:36 +00:00
|
|
|
CMSWindowsScreen::open()
|
2001-11-19 00:33:36 +00:00
|
|
|
{
|
|
|
|
assert(s_instance != NULL);
|
|
|
|
assert(m_class == 0);
|
|
|
|
|
2002-10-15 21:29:44 +00:00
|
|
|
LOG((CLOG_DEBUG "opening display"));
|
2002-07-15 15:01:36 +00:00
|
|
|
|
2002-07-11 18:58:49 +00:00
|
|
|
// create the transparent cursor
|
|
|
|
createBlankCursor();
|
2001-11-19 00:33:36 +00:00
|
|
|
|
|
|
|
// register a window class
|
|
|
|
WNDCLASSEX classInfo;
|
|
|
|
classInfo.cbSize = sizeof(classInfo);
|
|
|
|
classInfo.style = CS_DBLCLKS | CS_NOCLOSE;
|
|
|
|
classInfo.lpfnWndProc = &CMSWindowsScreen::wndProc;
|
|
|
|
classInfo.cbClsExtra = 0;
|
|
|
|
classInfo.cbWndExtra = 0;
|
|
|
|
classInfo.hInstance = s_instance;
|
|
|
|
classInfo.hIcon = NULL;
|
|
|
|
classInfo.hCursor = m_cursor;
|
|
|
|
classInfo.hbrBackground = NULL;
|
|
|
|
classInfo.lpszMenuName = NULL;
|
|
|
|
classInfo.lpszClassName = "Synergy";
|
|
|
|
classInfo.hIconSm = NULL;
|
2002-07-11 18:58:49 +00:00
|
|
|
m_class = RegisterClassEx(&classInfo);
|
2001-11-19 00:33:36 +00:00
|
|
|
|
2002-06-19 17:03:29 +00:00
|
|
|
// get screen shape
|
|
|
|
updateScreenShape();
|
2001-11-19 00:33:36 +00:00
|
|
|
|
2002-06-23 21:53:31 +00:00
|
|
|
// initialize the screen saver
|
2002-07-15 15:01:36 +00:00
|
|
|
m_screensaver = new CMSWindowsScreenSaver();
|
|
|
|
|
|
|
|
// load the hook library and get the screen saver functions
|
|
|
|
m_hookLibrary = LoadLibrary("synrgyhk");
|
|
|
|
if (m_hookLibrary != NULL) {
|
|
|
|
m_installScreensaver = (InstallScreenSaverFunc)GetProcAddress(
|
|
|
|
m_hookLibrary, "installScreenSaver");
|
|
|
|
m_uninstallScreensaver = (UninstallScreenSaverFunc)GetProcAddress(
|
|
|
|
m_hookLibrary, "uninstallScreenSaver");
|
|
|
|
if (m_installScreensaver == NULL || m_uninstallScreensaver == NULL) {
|
|
|
|
// disable if either install or uninstall is unavailable
|
|
|
|
m_installScreensaver = NULL;
|
|
|
|
m_uninstallScreensaver = NULL;
|
|
|
|
}
|
|
|
|
}
|
2001-11-19 00:33:36 +00:00
|
|
|
}
|
|
|
|
|
2002-06-10 22:06:45 +00:00
|
|
|
void
|
2002-07-15 15:01:36 +00:00
|
|
|
CMSWindowsScreen::mainLoop()
|
|
|
|
{
|
|
|
|
// must call mainLoop() from same thread as openDesktop()
|
|
|
|
assert(m_threadID == GetCurrentThreadId());
|
|
|
|
|
|
|
|
// event loop
|
|
|
|
CEvent event;
|
|
|
|
event.m_result = 0;
|
|
|
|
for (;;) {
|
|
|
|
// wait for an event in a cancellable way
|
2003-03-12 22:34:07 +00:00
|
|
|
if (CThread::getCurrentThread().waitForEvent(-1.0) != CThread::kEvent) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!PeekMessage(&event.m_msg, NULL, 0, 0, PM_REMOVE)) {
|
|
|
|
continue;
|
|
|
|
}
|
2002-07-15 15:01:36 +00:00
|
|
|
|
|
|
|
// handle quit message
|
|
|
|
if (event.m_msg.message == WM_QUIT) {
|
2002-12-15 19:58:41 +00:00
|
|
|
if (event.m_msg.wParam == 0) {
|
|
|
|
// force termination
|
|
|
|
CThread::getCurrentThread().cancel();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// just exit the main loop
|
|
|
|
break;
|
|
|
|
}
|
2002-07-15 15:01:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// dispatch message
|
|
|
|
if (!onPreDispatch(&event)) {
|
|
|
|
TranslateMessage(&event.m_msg);
|
|
|
|
DispatchMessage(&event.m_msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CMSWindowsScreen::exitMainLoop()
|
|
|
|
{
|
2002-12-15 19:58:41 +00:00
|
|
|
// close down cleanly
|
|
|
|
PostThreadMessage(m_threadID, WM_QUIT, 1, 0);
|
2002-07-15 15:01:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CMSWindowsScreen::close()
|
2001-11-19 00:33:36 +00:00
|
|
|
{
|
2002-06-23 21:53:31 +00:00
|
|
|
assert(s_instance != NULL);
|
|
|
|
|
2002-07-15 15:01:36 +00:00
|
|
|
// done with hook library
|
|
|
|
if (m_hookLibrary != NULL) {
|
|
|
|
FreeLibrary(m_hookLibrary);
|
|
|
|
m_installScreensaver = NULL;
|
|
|
|
m_uninstallScreensaver = NULL;
|
|
|
|
m_hookLibrary = NULL;
|
|
|
|
}
|
|
|
|
|
2002-06-23 21:53:31 +00:00
|
|
|
// done with screen saver
|
2002-07-15 15:01:36 +00:00
|
|
|
delete m_screensaver;
|
|
|
|
m_screensaver = NULL;
|
2001-11-19 00:33:36 +00:00
|
|
|
|
|
|
|
// unregister the window class
|
2002-07-11 18:58:49 +00:00
|
|
|
if (m_class != 0) {
|
|
|
|
UnregisterClass((LPCTSTR)m_class, s_instance);
|
|
|
|
m_class = 0;
|
|
|
|
}
|
2001-11-19 00:33:36 +00:00
|
|
|
|
|
|
|
// delete resources
|
2002-07-11 18:58:49 +00:00
|
|
|
if (m_cursor != NULL) {
|
|
|
|
DestroyCursor(m_cursor);
|
|
|
|
m_cursor = NULL;
|
|
|
|
}
|
2001-11-19 00:33:36 +00:00
|
|
|
|
2002-10-15 21:29:44 +00:00
|
|
|
LOG((CLOG_DEBUG "closed display"));
|
2001-11-19 00:33:36 +00:00
|
|
|
}
|
|
|
|
|
2002-07-15 15:01:36 +00:00
|
|
|
bool
|
|
|
|
CMSWindowsScreen::setClipboard(ClipboardID, const IClipboard* src)
|
2001-11-19 00:33:36 +00:00
|
|
|
{
|
2002-07-15 15:01:36 +00:00
|
|
|
CMSWindowsClipboard dst(m_window);
|
|
|
|
if (src != NULL) {
|
|
|
|
// save clipboard data
|
|
|
|
return CClipboard::copy(&dst, src);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// assert clipboard ownership
|
|
|
|
if (!dst.open(0)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
dst.empty();
|
|
|
|
dst.close();
|
|
|
|
return true;
|
|
|
|
}
|
2001-11-19 00:33:36 +00:00
|
|
|
}
|
|
|
|
|
2002-07-15 15:01:36 +00:00
|
|
|
void
|
|
|
|
CMSWindowsScreen::checkClipboards()
|
2001-11-19 00:33:36 +00:00
|
|
|
{
|
2002-07-15 15:01:36 +00:00
|
|
|
// if we think we own the clipboard but we don't then somebody
|
|
|
|
// grabbed the clipboard on this screen without us knowing.
|
|
|
|
// tell the server that this screen grabbed the clipboard.
|
|
|
|
//
|
|
|
|
// this works around bugs in the clipboard viewer chain.
|
|
|
|
// sometimes NT will simply never send WM_DRAWCLIPBOARD
|
|
|
|
// messages for no apparent reason and rebooting fixes the
|
|
|
|
// problem. since we don't want a broken clipboard until the
|
|
|
|
// next reboot we do this double check. clipboard ownership
|
|
|
|
// won't be reflected on other screens until we leave but at
|
|
|
|
// least the clipboard itself will work.
|
Fixed several win32 bugs. First, synergy wasn't forwarding mouse
events to other hook functions, which broke some tools like objectbar.
Second, windows key processing was fixed. Previously pressing and
release the key would only send a press event, locking the user onto
the client window; also, the win32 server treated as a Meta modifier
instead of a Super modifier, which broke any use of it as any kind of
modifier key. Third, added hacks to support several key combinations
on windows 95/98/me that are treated specially by windows, including
Alt+Tab, Alt+Shift+Tab, Alt+Esc, Alt+Shift+Esc, Ctrl+Esc, and any
combination using the windows key like Win+E and Win+F but not
Ctrl+Alt+Del. Fourth, scroll lock only locking to the client (which
only happened when using a synergy server on windows) has been fixed;
unfortunately the solution causes a lot of screen redraws for some
reason. Finally, there's been a fix to clipboard handling that may
or may not fix a problem where the clipboard would stop transferring
between systems after a little while. I can't be sure if it fixes
the problem because I can't reproduce the problem.
2003-04-13 14:59:53 +00:00
|
|
|
if (m_ownClipboard && !CMSWindowsClipboard::isOwnedBySynergy()) {
|
|
|
|
m_ownClipboard = false;
|
|
|
|
m_receiver->onGrabClipboard(kClipboardClipboard);
|
|
|
|
m_receiver->onGrabClipboard(kClipboardSelection);
|
2002-07-15 15:01:36 +00:00
|
|
|
}
|
2001-11-19 00:33:36 +00:00
|
|
|
}
|
|
|
|
|
2002-06-10 22:06:45 +00:00
|
|
|
void
|
2002-07-15 15:01:36 +00:00
|
|
|
CMSWindowsScreen::openScreensaver(bool notify)
|
2002-05-24 17:54:28 +00:00
|
|
|
{
|
2002-07-15 15:01:36 +00:00
|
|
|
assert(m_screensaver != NULL);
|
|
|
|
|
|
|
|
m_screensaverNotify = notify;
|
|
|
|
if (m_screensaverNotify) {
|
|
|
|
if (m_installScreensaver != NULL) {
|
|
|
|
m_installScreensaver();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_screensaver->disable();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CMSWindowsScreen::closeScreensaver()
|
|
|
|
{
|
|
|
|
if (m_screensaver != NULL) {
|
|
|
|
if (m_screensaverNotify) {
|
|
|
|
if (m_uninstallScreensaver != NULL) {
|
|
|
|
m_uninstallScreensaver();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_screensaver->enable();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_screensaverNotify = false;
|
2002-05-24 17:54:28 +00:00
|
|
|
}
|
|
|
|
|
2002-06-10 22:06:45 +00:00
|
|
|
void
|
2002-07-15 15:01:36 +00:00
|
|
|
CMSWindowsScreen::screensaver(bool activate)
|
|
|
|
{
|
|
|
|
assert(m_screensaver != NULL);
|
|
|
|
if (activate) {
|
|
|
|
m_screensaver->activate();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_screensaver->deactivate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CMSWindowsScreen::syncDesktop()
|
|
|
|
{
|
|
|
|
// change calling thread's desktop
|
|
|
|
if (!m_is95Family) {
|
|
|
|
if (SetThreadDesktop(m_desk) == 0) {
|
2002-10-15 21:29:44 +00:00
|
|
|
// LOG((CLOG_WARN "failed to set desktop: %d", GetLastError()));
|
2002-07-15 15:01:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// attach input queues if not already attached. this has a habit
|
|
|
|
// of sucking up more and more CPU each time it's called (even if
|
|
|
|
// the threads are already attached). since we only expect one
|
|
|
|
// thread to call this more than once we can save just the last
|
2003-05-17 20:58:27 +00:00
|
|
|
// attached thread.
|
2002-07-15 15:01:36 +00:00
|
|
|
DWORD threadID = GetCurrentThreadId();
|
|
|
|
if (threadID != m_lastThreadID && threadID != m_threadID) {
|
|
|
|
m_lastThreadID = threadID;
|
|
|
|
AttachThreadInput(threadID, m_threadID, TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CMSWindowsScreen::getClipboard(ClipboardID, IClipboard* dst) const
|
|
|
|
{
|
|
|
|
CMSWindowsClipboard src(m_window);
|
|
|
|
CClipboard::copy(dst, &src);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CMSWindowsScreen::getShape(SInt32& x, SInt32& y,
|
2002-07-11 18:58:49 +00:00
|
|
|
SInt32& w, SInt32& h) const
|
2001-11-19 00:33:36 +00:00
|
|
|
{
|
|
|
|
assert(m_class != 0);
|
|
|
|
|
2002-06-19 17:03:29 +00:00
|
|
|
x = m_x;
|
|
|
|
y = m_y;
|
|
|
|
w = m_w;
|
|
|
|
h = m_h;
|
2001-11-19 00:33:36 +00:00
|
|
|
}
|
|
|
|
|
2002-07-11 18:58:49 +00:00
|
|
|
void
|
|
|
|
CMSWindowsScreen::getCursorPos(SInt32& x, SInt32& y) const
|
|
|
|
{
|
|
|
|
POINT pos;
|
2002-07-12 20:41:23 +00:00
|
|
|
if (GetCursorPos(&pos)) {
|
|
|
|
x = pos.x;
|
|
|
|
y = pos.y;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
getCursorCenter(x, y);
|
|
|
|
}
|
2002-07-11 18:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CMSWindowsScreen::getCursorCenter(SInt32& x, SInt32& y) const
|
|
|
|
{
|
|
|
|
x = GetSystemMetrics(SM_CXSCREEN) >> 1;
|
|
|
|
y = GetSystemMetrics(SM_CYSCREEN) >> 1;
|
|
|
|
}
|
|
|
|
|
2002-07-15 15:01:36 +00:00
|
|
|
void
|
|
|
|
CMSWindowsScreen::updateScreenShape()
|
2002-07-11 18:58:49 +00:00
|
|
|
{
|
2002-07-15 15:01:36 +00:00
|
|
|
// get shape
|
|
|
|
m_x = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
|
|
|
m_y = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
|
|
|
m_w = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
|
|
|
m_h = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
2002-10-15 21:29:44 +00:00
|
|
|
LOG((CLOG_INFO "screen shape: %d,%d %dx%d", m_x, m_y, m_w, m_h));
|
2002-07-15 15:01:36 +00:00
|
|
|
|
|
|
|
// check for multiple monitors
|
|
|
|
m_multimon = (m_w != GetSystemMetrics(SM_CXSCREEN) ||
|
|
|
|
m_h != GetSystemMetrics(SM_CYSCREEN));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CMSWindowsScreen::onPreDispatch(const CEvent* event)
|
|
|
|
{
|
|
|
|
// handle event
|
|
|
|
const MSG* msg = &event->m_msg;
|
|
|
|
switch (msg->message) {
|
|
|
|
case SYNERGY_MSG_SCREEN_SAVER:
|
2002-07-18 16:58:08 +00:00
|
|
|
{
|
|
|
|
// activating or deactivating?
|
|
|
|
bool activate = (msg->wParam != 0);
|
|
|
|
|
|
|
|
// ignore this message if there are any other screen saver
|
|
|
|
// messages already in the queue. this is important because
|
|
|
|
// our checkStarted() function has a deliberate delay, so it
|
|
|
|
// can't respond to events at full CPU speed and will fall
|
|
|
|
// behind if a lot of screen saver events are generated.
|
|
|
|
// that can easily happen because windows will continually
|
|
|
|
// send SC_SCREENSAVE until the screen saver starts, even if
|
|
|
|
// the screen saver is disabled!
|
|
|
|
MSG msg;
|
|
|
|
if (!PeekMessage(&msg, NULL, SYNERGY_MSG_SCREEN_SAVER,
|
|
|
|
SYNERGY_MSG_SCREEN_SAVER, PM_NOREMOVE)) {
|
|
|
|
if (activate) {
|
|
|
|
if (m_screensaver->checkStarted(
|
|
|
|
SYNERGY_MSG_SCREEN_SAVER, FALSE, 0)) {
|
|
|
|
m_eventHandler->onScreensaver(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_eventHandler->onScreensaver(false);
|
|
|
|
}
|
2002-07-15 15:01:36 +00:00
|
|
|
}
|
2002-07-18 16:58:08 +00:00
|
|
|
return true;
|
2002-07-15 15:01:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
case WM_TIMER:
|
2003-03-12 22:34:07 +00:00
|
|
|
if (msg->wParam == m_timer) {
|
|
|
|
// if current desktop is not the input desktop then switch to it.
|
|
|
|
// windows 95 doesn't support multiple desktops so don't bother
|
|
|
|
// to check under it.
|
|
|
|
if (!m_is95Family) {
|
|
|
|
HDESK desk = openInputDesktop();
|
|
|
|
if (desk != NULL) {
|
|
|
|
if (isCurrentDesktop(desk)) {
|
|
|
|
CloseDesktop(desk);
|
|
|
|
}
|
2003-05-17 20:58:27 +00:00
|
|
|
else if (m_screensaver->isActive()) {
|
2003-03-12 22:34:07 +00:00
|
|
|
// don't switch desktops when the screensaver is
|
|
|
|
// active. we'd most likely switch to the
|
|
|
|
// screensaver desktop which would have the side
|
|
|
|
// effect of forcing the screensaver to stop.
|
2003-05-17 20:58:27 +00:00
|
|
|
CloseDesktop(desk);
|
2003-03-12 22:34:07 +00:00
|
|
|
}
|
|
|
|
else {
|
2003-05-17 20:58:27 +00:00
|
|
|
switchDesktop(desk);
|
2003-03-12 22:34:07 +00:00
|
|
|
}
|
2003-05-17 20:58:27 +00:00
|
|
|
|
|
|
|
// if the desktop was inaccessible then notify the
|
|
|
|
// event handler of that.
|
|
|
|
if (m_inaccessibleDesktop) {
|
2003-05-26 09:46:52 +00:00
|
|
|
LOG((CLOG_INFO "desktop is now accessible"));
|
2003-05-17 20:58:27 +00:00
|
|
|
m_inaccessibleDesktop = false;
|
|
|
|
m_eventHandler->onAccessibleDesktop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!m_inaccessibleDesktop) {
|
|
|
|
// the desktop has become inaccessible
|
|
|
|
m_inaccessibleDesktop = true;
|
2003-05-26 09:46:52 +00:00
|
|
|
LOG((CLOG_INFO "desktop is now inaccessible"));
|
2002-12-25 18:44:54 +00:00
|
|
|
}
|
2002-07-15 15:01:36 +00:00
|
|
|
}
|
Fixed several win32 bugs. First, synergy wasn't forwarding mouse
events to other hook functions, which broke some tools like objectbar.
Second, windows key processing was fixed. Previously pressing and
release the key would only send a press event, locking the user onto
the client window; also, the win32 server treated as a Meta modifier
instead of a Super modifier, which broke any use of it as any kind of
modifier key. Third, added hacks to support several key combinations
on windows 95/98/me that are treated specially by windows, including
Alt+Tab, Alt+Shift+Tab, Alt+Esc, Alt+Shift+Esc, Ctrl+Esc, and any
combination using the windows key like Win+E and Win+F but not
Ctrl+Alt+Del. Fourth, scroll lock only locking to the client (which
only happened when using a synergy server on windows) has been fixed;
unfortunately the solution causes a lot of screen redraws for some
reason. Finally, there's been a fix to clipboard handling that may
or may not fix a problem where the clipboard would stop transferring
between systems after a little while. I can't be sure if it fixes
the problem because I can't reproduce the problem.
2003-04-13 14:59:53 +00:00
|
|
|
|
|
|
|
// let client do timer related stuff. ignore the return
|
|
|
|
// value though since the event has been handled here.
|
|
|
|
m_eventHandler->onPreDispatch(event);
|
2002-07-15 15:01:36 +00:00
|
|
|
}
|
2003-03-12 22:34:07 +00:00
|
|
|
else if (msg->wParam == m_oneShotTimer) {
|
|
|
|
// one shot timer expired
|
|
|
|
KillTimer(NULL, m_oneShotTimer);
|
|
|
|
m_oneShotTimer = 0;
|
|
|
|
m_eventHandler->onOneShotTimerExpired(0);
|
|
|
|
}
|
Fixed several win32 bugs. First, synergy wasn't forwarding mouse
events to other hook functions, which broke some tools like objectbar.
Second, windows key processing was fixed. Previously pressing and
release the key would only send a press event, locking the user onto
the client window; also, the win32 server treated as a Meta modifier
instead of a Super modifier, which broke any use of it as any kind of
modifier key. Third, added hacks to support several key combinations
on windows 95/98/me that are treated specially by windows, including
Alt+Tab, Alt+Shift+Tab, Alt+Esc, Alt+Shift+Esc, Ctrl+Esc, and any
combination using the windows key like Win+E and Win+F but not
Ctrl+Alt+Del. Fourth, scroll lock only locking to the client (which
only happened when using a synergy server on windows) has been fixed;
unfortunately the solution causes a lot of screen redraws for some
reason. Finally, there's been a fix to clipboard handling that may
or may not fix a problem where the clipboard would stop transferring
between systems after a little while. I can't be sure if it fixes
the problem because I can't reproduce the problem.
2003-04-13 14:59:53 +00:00
|
|
|
|
2002-07-15 15:01:36 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
Fixed several win32 bugs. First, synergy wasn't forwarding mouse
events to other hook functions, which broke some tools like objectbar.
Second, windows key processing was fixed. Previously pressing and
release the key would only send a press event, locking the user onto
the client window; also, the win32 server treated as a Meta modifier
instead of a Super modifier, which broke any use of it as any kind of
modifier key. Third, added hacks to support several key combinations
on windows 95/98/me that are treated specially by windows, including
Alt+Tab, Alt+Shift+Tab, Alt+Esc, Alt+Shift+Esc, Ctrl+Esc, and any
combination using the windows key like Win+E and Win+F but not
Ctrl+Alt+Del. Fourth, scroll lock only locking to the client (which
only happened when using a synergy server on windows) has been fixed;
unfortunately the solution causes a lot of screen redraws for some
reason. Finally, there's been a fix to clipboard handling that may
or may not fix a problem where the clipboard would stop transferring
between systems after a little while. I can't be sure if it fixes
the problem because I can't reproduce the problem.
2003-04-13 14:59:53 +00:00
|
|
|
// let client handle the event
|
2002-07-15 15:01:36 +00:00
|
|
|
return m_eventHandler->onPreDispatch(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CMSWindowsScreen::onEvent(CEvent* event)
|
|
|
|
{
|
|
|
|
assert(event != NULL);
|
|
|
|
|
|
|
|
const MSG& msg = event->m_msg;
|
|
|
|
switch (msg.message) {
|
|
|
|
case WM_QUERYENDSESSION:
|
|
|
|
if (m_is95Family) {
|
|
|
|
event->m_result = TRUE;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_ENDSESSION:
|
|
|
|
if (m_is95Family) {
|
|
|
|
if (msg.wParam == TRUE && msg.lParam == 0) {
|
|
|
|
exitMainLoop();
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_PAINT:
|
|
|
|
ValidateRect(msg.hwnd, NULL);
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case WM_DRAWCLIPBOARD:
|
2002-10-15 21:29:44 +00:00
|
|
|
LOG((CLOG_DEBUG "clipboard was taken"));
|
2002-07-15 15:01:36 +00:00
|
|
|
|
|
|
|
// first pass it on
|
|
|
|
if (m_nextClipboardWindow != NULL) {
|
|
|
|
SendMessage(m_nextClipboardWindow,
|
|
|
|
msg.message, msg.wParam, msg.lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
// now notify client that somebody changed the clipboard (unless
|
Fixed several win32 bugs. First, synergy wasn't forwarding mouse
events to other hook functions, which broke some tools like objectbar.
Second, windows key processing was fixed. Previously pressing and
release the key would only send a press event, locking the user onto
the client window; also, the win32 server treated as a Meta modifier
instead of a Super modifier, which broke any use of it as any kind of
modifier key. Third, added hacks to support several key combinations
on windows 95/98/me that are treated specially by windows, including
Alt+Tab, Alt+Shift+Tab, Alt+Esc, Alt+Shift+Esc, Ctrl+Esc, and any
combination using the windows key like Win+E and Win+F but not
Ctrl+Alt+Del. Fourth, scroll lock only locking to the client (which
only happened when using a synergy server on windows) has been fixed;
unfortunately the solution causes a lot of screen redraws for some
reason. Finally, there's been a fix to clipboard handling that may
or may not fix a problem where the clipboard would stop transferring
between systems after a little while. I can't be sure if it fixes
the problem because I can't reproduce the problem.
2003-04-13 14:59:53 +00:00
|
|
|
// we're the owner).
|
|
|
|
if (!CMSWindowsClipboard::isOwnedBySynergy()) {
|
|
|
|
if (m_ownClipboard) {
|
|
|
|
m_ownClipboard = false;
|
|
|
|
m_receiver->onGrabClipboard(kClipboardClipboard);
|
|
|
|
m_receiver->onGrabClipboard(kClipboardSelection);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_ownClipboard = true;
|
2002-07-15 15:01:36 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case WM_CHANGECBCHAIN:
|
|
|
|
if (m_nextClipboardWindow == (HWND)msg.wParam) {
|
|
|
|
m_nextClipboardWindow = (HWND)msg.lParam;
|
|
|
|
}
|
|
|
|
else if (m_nextClipboardWindow != NULL) {
|
|
|
|
SendMessage(m_nextClipboardWindow,
|
|
|
|
msg.message, msg.wParam, msg.lParam);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case WM_DISPLAYCHANGE:
|
|
|
|
{
|
|
|
|
// screen resolution may have changed. get old shape.
|
|
|
|
SInt32 xOld, yOld, wOld, hOld;
|
|
|
|
getShape(xOld, yOld, wOld, hOld);
|
|
|
|
|
|
|
|
// update shape
|
|
|
|
updateScreenShape();
|
|
|
|
|
|
|
|
// collect new screen info
|
|
|
|
CClientInfo info;
|
|
|
|
getShape(info.m_x, info.m_y, info.m_w, info.m_h);
|
|
|
|
getCursorPos(info.m_mx, info.m_my);
|
|
|
|
info.m_zoneSize = m_eventHandler->getJumpZoneSize();
|
|
|
|
|
|
|
|
// do nothing if resolution hasn't changed
|
|
|
|
if (info.m_x != xOld || info.m_y != yOld ||
|
|
|
|
info.m_w != wOld || info.m_h != hOld) {
|
|
|
|
// forward event
|
|
|
|
m_eventHandler->onEvent(event);
|
|
|
|
|
|
|
|
// send new screen info
|
|
|
|
m_receiver->onInfoChanged(info);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_eventHandler->onEvent(event);
|
2002-07-11 18:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2002-07-15 15:01:36 +00:00
|
|
|
bool
|
|
|
|
CMSWindowsScreen::switchDesktop(HDESK desk)
|
|
|
|
{
|
Fixed several win32 bugs. First, synergy wasn't forwarding mouse
events to other hook functions, which broke some tools like objectbar.
Second, windows key processing was fixed. Previously pressing and
release the key would only send a press event, locking the user onto
the client window; also, the win32 server treated as a Meta modifier
instead of a Super modifier, which broke any use of it as any kind of
modifier key. Third, added hacks to support several key combinations
on windows 95/98/me that are treated specially by windows, including
Alt+Tab, Alt+Shift+Tab, Alt+Esc, Alt+Shift+Esc, Ctrl+Esc, and any
combination using the windows key like Win+E and Win+F but not
Ctrl+Alt+Del. Fourth, scroll lock only locking to the client (which
only happened when using a synergy server on windows) has been fixed;
unfortunately the solution causes a lot of screen redraws for some
reason. Finally, there's been a fix to clipboard handling that may
or may not fix a problem where the clipboard would stop transferring
between systems after a little while. I can't be sure if it fixes
the problem because I can't reproduce the problem.
2003-04-13 14:59:53 +00:00
|
|
|
// assume we don't own the clipboard until later
|
|
|
|
m_ownClipboard = false;
|
2002-07-15 15:01:36 +00:00
|
|
|
|
|
|
|
// destroy old window
|
|
|
|
if (m_window != NULL) {
|
|
|
|
// first remove clipboard snooper
|
|
|
|
ChangeClipboardChain(m_window, m_nextClipboardWindow);
|
|
|
|
m_nextClipboardWindow = NULL;
|
|
|
|
|
|
|
|
// let client clean up before we destroy the window
|
|
|
|
m_eventHandler->preDestroyWindow(m_window);
|
|
|
|
|
|
|
|
// now destroy window
|
|
|
|
DestroyWindow(m_window);
|
|
|
|
m_window = NULL;
|
|
|
|
|
|
|
|
// done with desk
|
|
|
|
if (!m_is95Family) {
|
|
|
|
CloseDesktop(m_desk);
|
|
|
|
}
|
|
|
|
m_desk = NULL;
|
|
|
|
m_deskName = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
// if no new desktop then we're done
|
|
|
|
if (desk == NULL) {
|
2002-10-15 21:29:44 +00:00
|
|
|
LOG((CLOG_INFO "disconnecting desktop"));
|
2002-07-15 15:01:36 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// uninstall screen saver hooks
|
|
|
|
if (m_screensaverNotify) {
|
|
|
|
if (m_uninstallScreensaver != NULL) {
|
|
|
|
m_uninstallScreensaver();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// set the desktop. can only do this when there are no windows
|
|
|
|
// and hooks on the current desktop owned by this thread.
|
|
|
|
if (SetThreadDesktop(desk) == 0) {
|
2002-10-15 21:29:44 +00:00
|
|
|
LOG((CLOG_ERR "failed to set desktop: %d", GetLastError()));
|
2002-07-15 15:01:36 +00:00
|
|
|
if (!m_is95Family) {
|
|
|
|
CloseDesktop(desk);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// create the window
|
|
|
|
m_window = CreateWindowEx(WS_EX_TOPMOST |
|
|
|
|
WS_EX_TRANSPARENT |
|
|
|
|
WS_EX_TOOLWINDOW,
|
|
|
|
(LPCTSTR)m_class,
|
|
|
|
"Synergy",
|
|
|
|
WS_POPUP,
|
|
|
|
0, 0, 1, 1,
|
|
|
|
NULL, NULL,
|
|
|
|
getInstance(),
|
|
|
|
NULL);
|
|
|
|
if (m_window == NULL) {
|
2002-10-15 21:29:44 +00:00
|
|
|
LOG((CLOG_ERR "failed to create window: %d", GetLastError()));
|
2002-07-15 15:01:36 +00:00
|
|
|
if (!m_is95Family) {
|
|
|
|
CloseDesktop(desk);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// reinstall screen saver hooks
|
|
|
|
if (m_screensaverNotify) {
|
|
|
|
if (m_installScreensaver != NULL) {
|
|
|
|
m_installScreensaver();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// install our clipboard snooper
|
|
|
|
m_nextClipboardWindow = SetClipboardViewer(m_window);
|
|
|
|
|
Fixed several win32 bugs. First, synergy wasn't forwarding mouse
events to other hook functions, which broke some tools like objectbar.
Second, windows key processing was fixed. Previously pressing and
release the key would only send a press event, locking the user onto
the client window; also, the win32 server treated as a Meta modifier
instead of a Super modifier, which broke any use of it as any kind of
modifier key. Third, added hacks to support several key combinations
on windows 95/98/me that are treated specially by windows, including
Alt+Tab, Alt+Shift+Tab, Alt+Esc, Alt+Shift+Esc, Ctrl+Esc, and any
combination using the windows key like Win+E and Win+F but not
Ctrl+Alt+Del. Fourth, scroll lock only locking to the client (which
only happened when using a synergy server on windows) has been fixed;
unfortunately the solution causes a lot of screen redraws for some
reason. Finally, there's been a fix to clipboard handling that may
or may not fix a problem where the clipboard would stop transferring
between systems after a little while. I can't be sure if it fixes
the problem because I can't reproduce the problem.
2003-04-13 14:59:53 +00:00
|
|
|
// check if we own the clipboard
|
|
|
|
m_ownClipboard = CMSWindowsClipboard::isOwnedBySynergy();
|
2002-07-15 15:01:36 +00:00
|
|
|
|
|
|
|
// save new desktop
|
|
|
|
m_desk = desk;
|
|
|
|
m_deskName = getDesktopName(m_desk);
|
2002-10-15 21:29:44 +00:00
|
|
|
LOG((CLOG_INFO "switched to desktop \"%s\"", m_deskName.c_str()));
|
2002-07-15 15:01:36 +00:00
|
|
|
|
|
|
|
// let client prepare the window
|
|
|
|
m_eventHandler->postCreateWindow(m_window);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2002-06-10 22:06:45 +00:00
|
|
|
HDESK
|
|
|
|
CMSWindowsScreen::openInputDesktop() const
|
2002-06-08 21:48:00 +00:00
|
|
|
{
|
2002-07-15 15:01:36 +00:00
|
|
|
if (m_is95Family) {
|
|
|
|
// there's only one desktop on windows 95 et al.
|
|
|
|
return GetThreadDesktop(GetCurrentThreadId());
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK, TRUE,
|
2002-06-08 21:48:00 +00:00
|
|
|
DESKTOP_CREATEWINDOW |
|
|
|
|
DESKTOP_HOOKCONTROL |
|
|
|
|
GENERIC_WRITE);
|
2002-07-15 15:01:36 +00:00
|
|
|
}
|
2002-06-08 21:48:00 +00:00
|
|
|
}
|
|
|
|
|
2002-06-10 22:06:45 +00:00
|
|
|
CString
|
2002-06-17 13:31:21 +00:00
|
|
|
CMSWindowsScreen::getDesktopName(HDESK desk) const
|
2002-06-08 21:48:00 +00:00
|
|
|
{
|
|
|
|
if (desk == NULL) {
|
|
|
|
return CString();
|
|
|
|
}
|
2002-07-15 15:01:36 +00:00
|
|
|
else if (m_is95Family) {
|
|
|
|
return "desktop";
|
|
|
|
}
|
2002-06-08 21:48:00 +00:00
|
|
|
else {
|
|
|
|
DWORD size;
|
|
|
|
GetUserObjectInformation(desk, UOI_NAME, NULL, 0, &size);
|
2003-02-16 19:50:36 +00:00
|
|
|
TCHAR* name = (TCHAR*)alloca(size + sizeof(TCHAR));
|
2002-06-08 21:48:00 +00:00
|
|
|
GetUserObjectInformation(desk, UOI_NAME, name, size, &size);
|
|
|
|
CString result(name);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-10 22:06:45 +00:00
|
|
|
bool
|
2002-06-17 13:31:21 +00:00
|
|
|
CMSWindowsScreen::isCurrentDesktop(HDESK desk) const
|
2002-06-08 21:48:00 +00:00
|
|
|
{
|
2003-02-16 19:50:36 +00:00
|
|
|
// don't allocate space for current desktop name on heap since
|
|
|
|
// we do this a lot and we never save the name.
|
|
|
|
TCHAR* name;
|
|
|
|
if (desk == NULL) {
|
|
|
|
name = _T("");
|
|
|
|
}
|
|
|
|
else if (m_is95Family) {
|
|
|
|
name = _T("desktop");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
DWORD size;
|
|
|
|
GetUserObjectInformation(desk, UOI_NAME, NULL, 0, &size);
|
|
|
|
name = (TCHAR*)alloca(size + sizeof(TCHAR));
|
|
|
|
GetUserObjectInformation(desk, UOI_NAME, name, size, &size);
|
|
|
|
}
|
|
|
|
return (_tcsicmp(name, m_deskName.c_str()) == 0);
|
2002-06-23 21:53:31 +00:00
|
|
|
}
|
|
|
|
|
2002-06-10 22:06:45 +00:00
|
|
|
LRESULT CALLBACK
|
2002-06-17 13:31:21 +00:00
|
|
|
CMSWindowsScreen::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
2001-11-19 00:33:36 +00:00
|
|
|
{
|
2001-11-25 18:32:41 +00:00
|
|
|
assert(s_screen != NULL);
|
2002-07-12 20:41:23 +00:00
|
|
|
|
|
|
|
CEvent event;
|
|
|
|
event.m_msg.hwnd = hwnd;
|
|
|
|
event.m_msg.message = msg;
|
|
|
|
event.m_msg.wParam = wParam;
|
|
|
|
event.m_msg.lParam = lParam;
|
|
|
|
event.m_result = 0;
|
|
|
|
|
|
|
|
if (s_screen->onEvent(&event)) {
|
|
|
|
return event.m_result;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
|
|
}
|
2001-11-19 00:33:36 +00:00
|
|
|
}
|