⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdisplay.cxx.svn-base

📁 wince下的VNC 控制。X86下的源码。完全来源于共享源码。调试OK。
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
* 
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* 
* This software 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.
* 
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
* USA.
*/

// -=- SDisplay.cxx
//
// The SDisplay class encapsulates a particular system display.

#include <rfb_wince/SDisplay.h>
#include <rfb_wince/Service.h>
#include <rfb_wince/TsSessions.h>
#include <rfb_wince/CleanDesktop.h>
#include <rfb_wince/CurrentUser.h>
#include <rfb_wince/DynamicFn.h>
#include <rfb_wince/MonitorInfo.h>
#include <rfb_wince/SDisplayCorePolling.h>
#include <rfb_wince/SDisplayCoreWMHooks.h>
#include <rfb_wince/SDisplayCoreDriver.h>
#include <rfb/Exception.h>
#include <rfb/LogWriter.h>


using namespace rdr;
using namespace rfb;
using namespace rfb::win32;

static LogWriter vlog("SDisplay");

#ifdef _WIN32
#define stricmp _stricmp
#endif
// - SDisplay-specific configuration options

IntParameter rfb::win32::SDisplay::updateMethod("UpdateMethod",
												"How to discover desktop updates; 0 - Polling, 1 - Application hooking, 2 - Driver hooking.", 1);
BoolParameter rfb::win32::SDisplay::disableLocalInputs("DisableLocalInputs",
													   "Disable local keyboard and pointer input while the server is in use", false);
StringParameter rfb::win32::SDisplay::disconnectAction("DisconnectAction",
													   "Action to perform when all clients have disconnected.  (None, Lock, Logoff)", "None");
StringParameter displayDevice("DisplayDevice",
							  "Display device name of the monitor to be remoted, or empty to export the whole desktop.", "");
BoolParameter rfb::win32::SDisplay::removeWallpaper("RemoveWallpaper",
													"Remove the desktop wallpaper when the server is in use.", false);
BoolParameter rfb::win32::SDisplay::removePattern("RemovePattern",
												  "Remove the desktop background pattern when the server is in use.", false);
BoolParameter rfb::win32::SDisplay::disableEffects("DisableEffects",
												   "Disable desktop user interface effects when the server is in use.", false);


//////////////////////////////////////////////////////////////////////////////
//
// SDisplay
//

typedef BOOL (WINAPI *_LockWorkStation_proto)();
DynamicFn<_LockWorkStation_proto> _LockWorkStation(_T("user32.dll"), "LockWorkStation");

// -=- Constructor/Destructor

SDisplay::SDisplay()
: server(0), pb(0), device(0),
core(0), ptr(0), kbd(0), clipboard(0),
inputs(0), monitor(0), cleanDesktop(0), cursor(0),
statusLocation(0)
{
	updateEvent.h = CreateEvent(0, TRUE, FALSE, 0);
}

SDisplay::~SDisplay()
{
	// XXX when the VNCServer has been deleted with clients active, stop()
	// doesn't get called - this ought to be fixed in VNCServerST.  In any event,
	// we should never call any methods on VNCServer once we're being deleted.
	// This is because it is supposed to be guaranteed that the SDesktop exists
	// throughout the lifetime of the VNCServer.  So if we're being deleted, then
	// the VNCServer ought not to exist and therefore we shouldn't invoke any
	// methods on it.  Setting server to zero here ensures that stop() doesn't
	// call setPixelBuffer(0) on the server.
	server = 0;
	if (core) stop();
}


// -=- SDesktop interface

void SDisplay::start(VNCServer* vs)
{
	vlog.debug("starting");
	
	// Try to make session zero the console session
	if (!inConsoleSession())
		setConsoleSession();
	
	// Start the SDisplay core
	server = vs;
	startCore();
	
	vlog.debug("started");
	
	if (statusLocation) *statusLocation = true;
}

void SDisplay::stop()
{
	vlog.debug("stopping");
	
	// If we successfully start()ed then perform the DisconnectAction
	/* Peica Cut
	if (core) {
    CurrentUserToken cut;    
    CharArray action = disconnectAction.getData();
    if (stricmp(action.buf, "Logoff") == 0) {
	if (!cut.h)
	vlog.info("ignoring DisconnectAction=Logoff - no current user");
	else
	ExitWindowsEx(EWX_LOGOFF, 0);
    } else if (stricmp(action.buf, "Lock") == 0) {
	if (!cut.h) {
	vlog.info("ignoring DisconnectAction=Lock - no current user");
	} else {
	if (_LockWorkStation.isValid())
	(*_LockWorkStation)();
	else
	ExitWindowsEx(EWX_LOGOFF, 0);
	}
    }
	}
	*/
	
	// Stop the SDisplayCore
	if (server)
		server->setPixelBuffer(0);
	stopCore();
	server = 0;
	
	vlog.debug("stopped");
	
	if (statusLocation) *statusLocation = false;
}


void SDisplay::startCore() {
	
	// Currently, we just check whether we're in the console session, and
	//   fail if not
	if (!inConsoleSession())
		throw rdr::Exception("Console is not session zero - oreconnect to restore Console sessin");
	
	// Switch to the current input desktop
	
	if (rfb::win32::desktopChangeRequired()) {
		if (!rfb::win32::changeDesktop())
			throw rdr::Exception("unable to switch into input desktop");
	}
	
	
	// Initialise the change tracker and clipper
	updates.clear();
	clipper.setUpdateTracker(server);
	
	// Create the framebuffer object
	recreatePixelBuffer(true);
	
	// Create the SDisplayCore
	updateMethod_ = updateMethod;
	int tryMethod = updateMethod_;
	while (!core) {
		try {
			if (tryMethod == 2) {	
				core = new SDisplayCoreDriver(this, &updates);
			}
			else if (tryMethod == 1) {
				core = new SDisplayCoreWMHooks(this, &updates);
			}
			else {
				// NB by Peica:
				// SDisplayCorePolling may cause the high CPU load issue, so we 
				// must set the suitable polling interval. The better choose is 
				// to use the WMHook method.
				core = new SDisplayCorePolling(this, &updates, 240);
			}
			core->setScreenRect(screenRect);
		} catch (rdr::Exception& e) {
			delete core; core = 0;
			if (tryMethod == 0)
				throw rdr::Exception("unable to access desktop");
			tryMethod--;
			vlog.error(e.str());
		}
	}
	vlog.info("Started %s", core->methodName());
	
	// Start display monitor, clipboard handler and input handlers
	monitor = new WMMonitor;
	monitor->setNotifier(this);
	clipboard = new Clipboard;
	clipboard->setNotifier(this);
	ptr = new SPointer;
	kbd = new SKeyboard;
	inputs = new WMBlockInput;
	cursor = new WMCursor;
	
	// Apply desktop optimisations
	cleanDesktop = new CleanDesktop;
	if (removePattern)
		cleanDesktop->disablePattern();
	if (removeWallpaper)
		cleanDesktop->disableWallpaper();
	if (disableEffects)
		cleanDesktop->disableEffects();
	isWallpaperRemoved = removeWallpaper;
	isPatternRemoved = removePattern;
	areEffectsDisabled = disableEffects;
}

void SDisplay::stopCore() {
	if (core)
		vlog.info("Stopping %s", core->methodName());
	delete core; core = 0;
	delete pb; pb = 0;
	delete device; device = 0;
	delete monitor; monitor = 0;
	delete clipboard; clipboard = 0;
	delete inputs; inputs = 0;
	delete ptr; ptr = 0;
	delete kbd; kbd = 0;
	delete cleanDesktop; cleanDesktop = 0;
	delete cursor; cursor = 0;
	ResetEvent(updateEvent);
}


bool SDisplay::areHooksAvailable() {
	return WMHooks::areAvailable();
}

bool SDisplay::isDriverAvailable() {
	return SDisplayCoreDriver::isAvailable();
}


bool SDisplay::isRestartRequired() {
	// - We must restart the SDesktop if:
	// 1. We are no longer in the input desktop.
	// 2. The any setting has changed.
	
	// - Check that our session is the Console
	if (!inConsoleSession())
		return true;
	
	// - Check that we are in the input desktop
	
	if (rfb::win32::desktopChangeRequired())
		return true;
	
	
	// - Check that the update method setting hasn't changed

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -