COLORREF CGetColor::GetPixel(int nXPos, int nYPos) { COLORREF cr = {0}; RECT rcScreen; rcScreen.left = nXPos; rcScreen.top = nYPos; rcScreen.right = nXPos + 1; rcScreen.bottom = nYPos + 1; if(CopyScreenToData(&rcScreen)) { BYTE* pData; DWORD dwLen; GetDataSource(&pData, &dwLen); DWORD dwBitCount = GetBitCount(); DWORD dwPaletteSize = 0; if (dwBitCount <= 8) dwPaletteSize = (1 << dwBitCount) * sizeof(RGBQUAD); BITMAPFILEHEADER bmpFileHred; BITMAPINFOHEADER bi; memcpy(&bmpFileHred, pData, sizeof(BITMAPFILEHEADER)); memcpy(&bi, pData + sizeof(BITMAPFILEHEADER), sizeof(BITMAPINFOHEADER)); if(dwBitCount == 8) { DWORD DataSizePerLine = ((bi.biWidth * dwBitCount + 31) / 32) * 4; BYTE* pColor = pData + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + DataSizePerLine * ( bi.biHeight - 1) + 0; BYTE bColor; memcpy(&bColor, pColor, sizeof(BYTE)); int nColor = (int)bColor; RGBQUAD rgb; memcpy(&rgb, pData + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD)*nColor) , sizeof(RGBQUAD)); cr = RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue); } if(dwBitCount == 24) { DWORD DataSizePerLine = ((bi.biWidth * dwBitCount + 31) / 32) * 4; BYTE* pColor = pData + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 0 + DataSizePerLine * ( bi.biHeight - 1) + 0; // BYTE bColor; memcpy(&bColor, pColor, sizeof(BYTE)); // int nColor = (int)bColor; RGBQUAD rgb; memcpy(&rgb, pColor , sizeof(RGBQUAD)); cr = RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue); } LockData(false); } return cr; }
Bool HandleRFBServerMessage() { rfbServerToClientMsg msg; if (!ReadFromRFBServer((char *)&msg, 1)) return False; switch (msg.type) { case rfbSetColourMapEntries: { fprintf(stderr, "Received unsupported rfbSetColourMapEntries\n"); return False; /* unsupported */ } case rfbFramebufferUpdate: { rfbFramebufferUpdateRectHeader rect; int linesToRead; int bytesPerLine; int i; if (!ReadFromRFBServer(((char *)&msg.fu) + 1, sz_rfbFramebufferUpdateMsg - 1)) return False; msg.fu.nRects = Swap16IfLE(msg.fu.nRects); for (i = 0; i < msg.fu.nRects; i++) { if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader)) return False; rect.r.x = Swap16IfLE(rect.r.x); rect.r.y = Swap16IfLE(rect.r.y); rect.r.w = Swap16IfLE(rect.r.w); rect.r.h = Swap16IfLE(rect.r.h); rect.encoding = Swap32IfLE(rect.encoding); if (rect.encoding == rfbEncodingXCursor) { if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h, rfbEncodingXCursor)) { return False; } continue; } if (rect.encoding == rfbEncodingRichCursor) { if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h, rfbEncodingRichCursor)) { return False; } continue; } if (rect.encoding == rfbEncodingPointerPos) { if (!HandleCursorPos(rect.r.x, rect.r.y)) { return False; } appData.gotCursorPos = 1; continue; } if ((rect.r.x + rect.r.w > si.framebufferWidth) || (rect.r.y + rect.r.h > si.framebufferHeight)) { fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y); return False; } if ((rect.r.h * rect.r.w) == 0) { fprintf(stderr,"Zero size rect - ignoring\n"); continue; } /* If RichCursor encoding is used, we should prevent collisions between framebuffer updates and cursor drawing operations. */ SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h); switch (rect.encoding) { case rfbEncodingRaw: bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8; linesToRead = BUFFER_SIZE / bytesPerLine; while (rect.r.h > 0) { if (linesToRead > rect.r.h) linesToRead = rect.r.h; if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead)) return False; CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w, linesToRead); rect.r.h -= linesToRead; rect.r.y += linesToRead; } break; case rfbEncodingCopyRect: { rfbCopyRect cr; char *buffer; if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect)) return False; if (!BufferWritten()) { /* Ignore attempts to do copy-rect when we have nothing to * copy from. */ break; } cr.srcX = Swap16IfLE(cr.srcX); cr.srcY = Swap16IfLE(cr.srcY); /* If RichCursor encoding is used, we should extend our "cursor lock area" (previously set to destination rectangle) to the source rectangle as well. */ SoftCursorLockArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h); buffer = CopyScreenToData(cr.srcX, cr.srcY, rect.r.w, rect.r.h); CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w, rect.r.h); free(buffer); break; } case rfbEncodingRRE: { if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; } case rfbEncodingCoRRE: { if (!HandleCoRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; } case rfbEncodingHextile: { if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; } case rfbEncodingZlib: { if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; } case rfbEncodingTight: { if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; } case rfbEncodingZRLE: if (!zrleDecode(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) return False; break; default: fprintf(stderr,"Unknown rect encoding %d\n", (int)rect.encoding); return False; } /* Now we may discard "soft cursor locks". */ SoftCursorUnlockScreen(); /* Done. Save the screen image. */ } /* RealVNC sometimes returns an initial black screen. */ if (BufferIsBlank() && appData.ignoreBlank) { if (!appData.quiet && appData.ignoreBlank != 1) { /* user did not specify either -quiet or -ignoreblank */ fprintf(stderr, "Warning: discarding received blank screen (use -allowblank to accept,\n or -ignoreblank to suppress this message)\n"); appData.ignoreBlank = 1; } RequestNewUpdate(); } else { return False; } break; } case rfbBell: /* ignore */ break; case rfbServerCutText: { if (!ReadFromRFBServer(((char *)&msg) + 1, sz_rfbServerCutTextMsg - 1)) return False; msg.sct.length = Swap32IfLE(msg.sct.length); if (serverCutText) free(serverCutText); serverCutText = malloc(msg.sct.length+1); if (!ReadFromRFBServer(serverCutText, msg.sct.length)) return False; serverCutText[msg.sct.length] = 0; newServerCutText = True; break; } default: fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type); return False; } return True; }