📄 vncclient.cpp
字号:
m_client->m_copyrect_use = FALSE;
}
for (x = 0; x < msg.se.nEncodings; x++)
{
omni_mutex_lock l(m_client->m_regionLock);
CARD32 encoding;
// Read an encoding in
if (!m_socket->ReadExact((char *)&encoding, sizeof(encoding)))
{
connected = FALSE;
break;
}
// Is this the CopyRect encoding (a special case)?
if (Swap32IfLE(encoding) == rfbEncodingCopyRect)
{
// Client wants us to use CopyRect
m_client->m_copyrect_use = TRUE;
continue;
}
// Is this an XCursor encoding request?
if (Swap32IfLE(encoding) == rfbEncodingXCursor) {
m_client->m_buffer->EnableXCursor(TRUE);
shapeupdates_requested = TRUE;
vnclog.Print(LL_INTINFO, VNCLOG("X-style cursor shape updates enabled\n"));
continue;
}
// Is this a RichCursor encoding request?
if (Swap32IfLE(encoding) == rfbEncodingRichCursor) {
m_client->m_buffer->EnableRichCursor(TRUE);
shapeupdates_requested = TRUE;
vnclog.Print(LL_INTINFO, VNCLOG("Full-color cursor shape updates enabled\n"));
continue;
}
// Is this a CompressLevel encoding?
if ((Swap32IfLE(encoding) >= rfbEncodingCompressLevel0) &&
(Swap32IfLE(encoding) <= rfbEncodingCompressLevel9))
{
// Client specified encoding-specific compression level
int level = (int)(Swap32IfLE(encoding) - rfbEncodingCompressLevel0);
m_client->m_buffer->SetCompressLevel(level);
vnclog.Print(LL_INTINFO, VNCLOG("compression level requested: %d\n"), level);
continue;
}
// Is this a QualityLevel encoding?
if ((Swap32IfLE(encoding) >= rfbEncodingQualityLevel0) &&
(Swap32IfLE(encoding) <= rfbEncodingQualityLevel9))
{
// Client specified image quality level used for JPEG compression
int level = (int)(Swap32IfLE(encoding) - rfbEncodingQualityLevel0);
m_client->m_buffer->SetQualityLevel(level);
vnclog.Print(LL_INTINFO, VNCLOG("image quality level requested: %d\n"), level);
continue;
}
// Is this a PointerPos encoding request?
if (Swap32IfLE(encoding) == rfbEncodingPointerPos) {
pointerpos_requested = TRUE;
continue;
}
// Is this a LastRect encoding request?
if (Swap32IfLE(encoding) == rfbEncodingLastRect) {
m_client->m_buffer->EnableLastRect(TRUE);
vnclog.Print(LL_INTINFO, VNCLOG("LastRect protocol extension enabled\n"));
continue;
}
// Is this a NewFBSize encoding request?
if (Swap32IfLE(encoding) == rfbEncodingNewFBSize) {
m_client->m_use_NewFBSize = TRUE;
vnclog.Print(LL_INTINFO, VNCLOG("NewFBSize protocol extension enabled\n"));
continue;
}
// Have we already found a suitable encoding?
if (!encoding_set)
{
// omni_mutex_lock l(m_client->m_regionLock);
// No, so try the buffer to see if this encoding will work...
if (m_client->m_buffer->SetEncoding(Swap32IfLE(encoding))) {
encoding_set = TRUE;
}
}
}
// Enable CursorPos encoding only if cursor shape updates were
// requested by the client.
if (shapeupdates_requested && pointerpos_requested) {
m_client->m_use_PointerPos = TRUE;
m_client->SetCursorPosChanged();
vnclog.Print(LL_INTINFO, VNCLOG("PointerPos protocol extension enabled\n"));
}
// If no encoding worked then default to RAW!
// FIXME: Protocol extensions won't work in this case.
if (!encoding_set)
{
omni_mutex_lock l(m_client->m_regionLock);
vnclog.Print(LL_INTINFO, VNCLOG("defaulting to raw encoder\n"));
if (!m_client->m_buffer->SetEncoding(Swap32IfLE(rfbEncodingRaw)))
{
vnclog.Print(LL_INTERR, VNCLOG("failed to select raw encoder!\n"));
connected = FALSE;
}
}
}
break;
case rfbFramebufferUpdateRequest:
// Read the rest of the message:
if (!m_socket->ReadExact(((char *) &msg)+1, sz_rfbFramebufferUpdateRequestMsg-1))
{
connected = FALSE;
break;
}
{
RECT update;
RECT sharedRect;
{
omni_mutex_lock l(m_client->m_regionLock);
sharedRect = m_server->GetSharedRect();
// Get the specified rectangle as the region to send updates for.
update.left = Swap16IfLE(msg.fur.x)+ sharedRect.left;
update.top = Swap16IfLE(msg.fur.y)+ sharedRect.top;
update.right = update.left + Swap16IfLE(msg.fur.w);
_ASSERTE(Swap16IfLE(msg.fur.x) >= 0);
_ASSERTE(Swap16IfLE(msg.fur.y) >= 0);
//if (update.right > m_client->m_fullscreen.right)
// update.right = m_client->m_fullscreen.right;
if (update.right > sharedRect.right)
update.right = sharedRect.right;
if (update.left < sharedRect.left)
update.left = sharedRect.left;
update.bottom = update.top + Swap16IfLE(msg.fur.h);
//if (update.bottom > m_client->m_fullscreen.bottom)
// update.bottom = m_client->m_fullscreen.bottom;
if (update.bottom > sharedRect.bottom)
update.bottom = sharedRect.bottom;
if (update.top < sharedRect.top)
update.top = sharedRect.top;
// Set the update-wanted flag to true
m_client->m_updatewanted = TRUE;
// Clip the rectangle to the screen
if (IntersectRect(&update, &update, &sharedRect))
{
// Is this request for an incremental region?
if (msg.fur.incremental)
{
// Yes, so add it to the incremental region
m_client->m_incr_rgn.AddRect(update);
}
else
{
// No, so add it to the full update region
m_client->m_full_rgn.AddRect(update);
// Disable any pending CopyRect
m_client->m_copyrect_set = FALSE;
}
}
// Trigger an update
m_server->RequestUpdate();
}
}
break;
case rfbKeyEvent:
// Read the rest of the message:
if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbKeyEventMsg-1))
{
if (m_client->IsKeyboardEnabled() && !m_client->IsInputBlocked())
{
msg.ke.key = Swap32IfLE(msg.ke.key);
// Get the keymapper to do the work
vncKeymap::keyEvent(msg.ke.key, msg.ke.down != 0,
m_client->m_server);
m_client->m_remoteevent = TRUE;
}
}
break;
case rfbPointerEvent:
// Read the rest of the message:
if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbPointerEventMsg-1))
{
if (m_client->IsPointerEnabled() && !m_client->IsInputBlocked())
{
// Convert the coords to Big Endian
msg.pe.x = Swap16IfLE(msg.pe.x);
msg.pe.y = Swap16IfLE(msg.pe.y);
// Remember cursor position for this client
m_client->m_cursor_pos.x = msg.pe.x;
m_client->m_cursor_pos.y = msg.pe.y;
// if we share only one window...
RECT coord;
{
omni_mutex_lock l(m_client->m_regionLock);
coord = m_server->GetSharedRect();
}
// to put position relative to screen
msg.pe.x = (CARD16)(msg.pe.x + coord.left);
msg.pe.y = (CARD16)(msg.pe.y + coord.top);
// Work out the flags for this event
DWORD flags = MOUSEEVENTF_ABSOLUTE;
flags |= MOUSEEVENTF_MOVE;
m_server->SetMouseCounter(1, m_client->m_cursor_pos, false );
if ( (msg.pe.buttonMask & rfbButton1Mask) !=
(m_client->m_ptrevent.buttonMask & rfbButton1Mask) )
{
if (GetSystemMetrics(SM_SWAPBUTTON))
flags |= (msg.pe.buttonMask & rfbButton1Mask)
? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP;
else
flags |= (msg.pe.buttonMask & rfbButton1Mask)
? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
m_server->SetMouseCounter(1, m_client->m_cursor_pos, false);
}
if ( (msg.pe.buttonMask & rfbButton2Mask) !=
(m_client->m_ptrevent.buttonMask & rfbButton2Mask) )
{
flags |= (msg.pe.buttonMask & rfbButton2Mask)
? MOUSEEVENTF_MIDDLEDOWN : MOUSEEVENTF_MIDDLEUP;
m_server->SetMouseCounter(1, m_client->m_cursor_pos, false);
}
if ( (msg.pe.buttonMask & rfbButton3Mask) !=
(m_client->m_ptrevent.buttonMask & rfbButton3Mask) )
{
if (GetSystemMetrics(SM_SWAPBUTTON))
flags |= (msg.pe.buttonMask & rfbButton3Mask)
? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
else
flags |= (msg.pe.buttonMask & rfbButton3Mask)
? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP;
m_server->SetMouseCounter(1, m_client->m_cursor_pos, false);
}
// Treat buttons 4 and 5 presses as mouse wheel events
DWORD wheel_movement = 0;
if ((msg.pe.buttonMask & rfbButton4Mask) != 0 &&
(m_client->m_ptrevent.buttonMask & rfbButton4Mask) == 0)
{
flags |= MOUSEEVENTF_WHEEL;
wheel_movement = (DWORD)+120;
}
else if ((msg.pe.buttonMask & rfbButton5Mask) != 0 &&
(m_client->m_ptrevent.buttonMask & rfbButton5Mask) == 0)
{
flags |= MOUSEEVENTF_WHEEL;
wheel_movement = (DWORD)-120;
}
// Generate coordinate values
// PRB: should it be really only primary rect?
HWND temp = GetDesktopWindow();
GetWindowRect(temp,&coord);
unsigned long x = (msg.pe.x * 65535) / (coord.right - coord.left - 1);
unsigned long y = (msg.pe.y * 65535) / (coord.bottom - coord.top - 1);
// Do the pointer event
::mouse_event(flags, (DWORD)x, (DWORD)y, wheel_movement, 0);
// Save the old position
m_client->m_ptrevent = msg.pe;
// Flag that a remote event occurred
m_client->m_remoteevent = TRUE;
m_client->m_pointer_event_time = time(NULL);
// Flag that the mouse moved
// FIXME: It should not set m_cursor_pos_changed here.
m_client->UpdateMouse();
// Trigger an update
m_server->RequestUpdate();
}
}
break;
case rfbClientCutText:
// Read the rest of the message:
if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbClientCutTextMsg-1))
{
// Allocate storage for the text
const UINT length = Swap32IfLE(msg.cct.length);
char *text = new char [length+1];
if (text == NULL)
break;
text[length] = 0;
// Read in the text
if (!m_socket->ReadExact(text, length)) {
delete [] text;
break;
}
// Get the server to update the local clipboard
if (m_client->IsKeyboardEnabled() && m_client->IsPointerEnabled())
m_server->UpdateLocalClipText(text);
// Free the clip text we read
delete [] text;
}
break;
case rfbFileListRequest:
if (!m_server->FileTransfersEnabled() || !m_client->IsInputEnabled()) {
connected = FALSE;
break;
}
if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbFileListRequestMsg-1))
{
msg.flr.dirNameSize = Swap16IfLE(msg.flr.dirNameSize);
if (msg.flr.dirNameSize > 255) break;
char path[255 + 1];
m_socket->ReadExact(path, msg.flr.dirNameSize);
path[msg.flr.dirNameSize] = '\0';
ConvertPath(path);
FileTransferItemInfo ftii;
if (strlen(path) == 0) {
TCHAR szDrivesList[256];
if (GetLogicalDriveStrings(255, szDrivesList) == 0)
break;
int i = 0;
while (szDrivesList[i] != '\0') {
char *drive = strdup(&szDrivesList[i]);
char *backslash = strrchr(drive, '\\');
if (backslash != NULL)
*backslash = '\0';
ftii.Add(drive, -1, 0);
free(drive);
i += strcspn(&szDrivesList[i], "\0") + 1;
}
} else {
strcat(path, "\\*");
HANDLE FLRhandle;
WIN32_FIND_DATA FindFileData;
SetErrorMode(SEM_FAILCRITICALERRORS);
FLRhandle = FindFirstFile(path, &FindFileData);
DWORD LastError = GetLastError();
SetErrorMode(0);
if (FLRhandle != INVALID_HANDLE_VALUE) {
do {
if (strcmp(FindFileData.cFileName, ".") != 0 &&
strcmp(FindFileData.cFileName, "..") != 0) {
LARGE_INTEGER li;
li.LowPart = FindFileData.ftLastWriteTime.dwLowDateTime;
li.HighPart = FindFileData.ftLastWriteTime.dwHighDateTime;
li.QuadPart = (li.QuadPart - 1164444736000000000) / 10000000;
if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
ftii.Add(FindFileData.cFileName, -1, 0);
} else {
if (!(msg.flr.flags & 0x10))
ftii.Add(FindFileData.cFileName, FindFileData.nFileSizeLow, li.HighPart);
}
}
} while (FindNextFile(FLRhandle, &FindFileData));
} else {
if (LastError != ERROR_SUCCESS && LastError != ERROR_FILE_NOT_FOUND) {
omni_mutex_lock l(m_client->m_sendUpdateLock);
rfbFileListDataMsg fld;
fld.type = rfbFileListData;
fld.numFiles = Swap16IfLE(0);
fld.dataSize = Swap16IfLE(0);
fld.compressedSize = Swap16IfLE(0);
fld.flags = msg.flr.flags | 0x80;
m_socket->SendExact((char *)&fld, sz_rfbFileListDataMsg);
break;
}
}
FindClose(FLRhandle);
}
int dsSize = ftii.GetNumEntries() * 8;
int msgLen = sz_rfbFileListDataMsg + dsSize + ftii.GetSummaryNamesLength() + ftii.GetNumEntries();
char *pAllMessage = new char [msgLen];
rfbFileListDataMsg *pFLD = (rfbFileListDataMsg *) pAllMessage;
FTSIZEDATA *pftsd = (FTSIZEDATA *) &pAllMessage[sz_rfbFileListDataMsg];
char *pFilenames = &pAllMessage[sz_rfbFileListDataMsg + dsSize];
pFLD->type = rfbFileListData;
pFLD->flags = msg.flr.flags&0xF0;
pFLD->numFiles = Swap16IfLE(ftii.GetNumEntries());
pFLD->dataSize = Swap16IfLE(ftii.GetSummaryNamesLength() + ftii.GetNumEntries());
pFLD->compressedSize = pFLD->dataSize;
for (int i = 0; i < ftii.GetNumEntries(); i++) {
pftsd[i].size = Swap32IfLE(ftii.GetSizeAt(i));
pftsd[i].data = Swap32IfLE(ftii.GetDataAt(i));
strcpy(pFilenames, ftii.GetNameAt(i));
pFilenames = pFilenames + strlen(pFilenames) + 1;
}
omni_mutex_lock l(m_client->m_sendUpdateLock);
m_socket->SendExact(pAllMessage, msgLen);
}
break;
case rfbFileDownloadRequest:
if (!m_server->FileTransfersEnabled() || !m_client->IsInputEnabled()) {
connected = FALSE;
break;
}
if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbFileDownloadRequestMsg-1))
{
msg.fdr.fNameSize = Swap16IfLE(msg.fdr.fNameSize);
msg.fdr.position = Swap32IfLE(msg.fdr.position);
if (msg.fdr.fNameSize > 255) {
m_socket->ReadExact(NULL, msg.fdr.fNameSize);
char reason[] = "Path length exceeds 255 bytes";
int reasonLen = strlen(reason);
m_client->SendFileDownloadFailed(reasonLen, reason);
break;
}
char path_file[255];
m_socket->ReadExact(path_file, msg.fdr.fNameSize);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -