2011-01-28 16:07:46 -08:00

816 lines
26 KiB
C++

// Copyright (C) 2002 Ultr@VNC Team Members. All Rights Reserved.
// Copyright (C) 2000-2002 Const Kaplinsky. All Rights Reserved.
//
// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
//
// This file is part of the VNC system.
//
// The VNC system 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 program 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 program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//
// If the source code for the VNC system is not available from the place
// whence you received this file, check http://www.uk.research.att.com/vnc or contact
// the authors on vnc@uk.research.att.com for information on obtaining it.
#ifndef CLIENTCONNECTION_H__
#define CLIENTCONNECTION_H__
#pragma once
#include "stdhdrs.h"
#ifdef UNDER_CE
#include "omnithreadce.h"
#else
#include "omnithread.h"
#endif
#include "VNCOptions.h"
#include "VNCviewerApp.h"
#include "KeyMap.h"
#include "rdr/types.h"
#include "zlib/zlib.h"
extern "C"
{
#include "libjpeg/jpeglib.h" // For Tight encoding
}
#include "FileTransfer.h" // sf@2002
#include "TextChat.h" // sf@2002
//#include "bmpflasher.h"
#include "MRU.h"
// #include <DSMPlugin/DSMPlugin.h> // sf@2002
#include "FullScreenTitleBar.h" //Added by: Lars Werner (http://lars.werner.no)
extern const UINT FileTransferSendPacketMessage;
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#define SETTINGS_KEY_NAME "Software\\ORL\\VNCviewer\\Settings"
#define MAX_HOST_NAME_LEN 250
#define ZLIBHEX_DECOMP_UNINITED (-1)
#define BZIP2HEX_DECOMP_UNINITED (-1)
// Messages used by VNCon - Copyright (C) 2001-2003 - Alastair Burr
#define WM_SETSCALING WM_USER+101
#define WM_SETVIEWONLY WM_USER+102
#define WM_GETSCALING WM_USER+103
#define TIGHT_ZLIB_BUFFER_SIZE 512 // Tight encoding
class ClientConnection;
class CDSMPlugin;
typedef void (ClientConnection:: *tightFilterFunc)(int);
struct mybool {
bool b0 : 1;
bool b1 : 1;
bool b2 : 1;
bool b3 : 1;
bool b4 : 1;
bool b5 : 1;
bool b6 : 1;
bool b7 : 1;
};
struct BitmapInfo {
BITMAPINFOHEADER bmiHeader;
union {
struct {
DWORD red;
DWORD green;
DWORD blue;
} mask;
RGBQUAD color[256];
};
};
namespace rdr { class InStream; class FdInStream; class ZlibInStream; }
class ClientConnection : public omni_thread
{
public:
HWND m_hSessionDialog;
int m_port;
int m_proxyport;
// int m_proxy;
bool saved_set;
TCHAR m_host[MAX_HOST_NAME_LEN];
TCHAR m_proxyhost[MAX_HOST_NAME_LEN];
bool m_fUseProxy;
// TCHAR m_remotehost[MAX_HOST_NAME_LEN];
int LoadConnection(char *fname, bool fFromDialog);
void HandleQuickOption();
void GTGBS_CreateDisplay(void);
void GTGBS_ScrollToolbar(int dx, int dy);
void CreateButtons(BOOL mini,BOOL ultra);
ClientConnection(VNCviewerApp *pApp);
ClientConnection(VNCviewerApp *pApp, SOCKET sock);
ClientConnection(VNCviewerApp *pApp, LPTSTR host, int port, LPTSTR pszUser, LPTSTR pszPassword, LPTSTR pszProxy, HWND rootHwnd, HWND* pHwndAppFrame);
ClientConnection(VNCviewerApp *pApp, LPTSTR configFile);
virtual ~ClientConnection();
void Run();
void KillThread();
// Exceptions
class UserCancelExc {};
class AuthenticationExc {};
class SocketExc {};
class ProtocolExc {};
class Fatal {};
HANDLE KillEvent;
bool IsDormant(){ return m_dormant;};
private:
static LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK WndProcTBwin(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK WndProchwnd(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
void DoBlit();
VNCviewerApp *m_pApp;
SOCKET m_sock;
bool m_serverInitiated;
HWND m_hwnd, m_hbands,m_hwndTB,m_hwndTBwin,m_hwndMain,m_hwndStatus,m_TrafficMonitor,m_logo_wnd,m_button_wnd;
HANDLE m_statusThread;
RECT m_TBr;
// bool m_ToolbarEnable;
bool m_remote_mouse_disable;
bool m_SWselect;
POINT m_SWpoint;
HCURSOR hNewCursor;
HCURSOR hOldCursor;
BOOL skipprompt2;
void Init(VNCviewerApp *pApp);
void CreateDisplay();
void GTGBS_CreateToolbar();
HWND GTGBS_ShowConnectWindow();
//DWORD WINAPI GTGBS_ShowStatusWindow(LPVOID lpParameter);
static LRESULT CALLBACK GTGBS_ShowStatusWindow(LPVOID lpParameter);
static LRESULT CALLBACK GTGBS_StatusProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK GTGBS_SendCustomKey_proc(HWND Dlg, UINT iMsg, WPARAM wParam, LPARAM lParam);
void LoadDSMPlugin(); // sf@2002 - DSM Plugin
void SetDSMPluginStuff();
void GetConnectDetails();
void Connect();
void ConnectProxy();
void SetSocketOptions();
void Authenticate();
// marscha@2006
void AuthMsLogon();
void NegotiateProtocolVersion();
void NegotiateProxy();
void ReadServerInit();
void SendClientInit();
void CreateLocalFramebuffer();
void SaveConnection();
void Save_Latest_Connection();
void SetupPixelFormat();
void SetFormatAndEncodings();
void SendSetPixelFormat(rfbPixelFormat newFormat);
void SendIncrementalFramebufferUpdateRequest();
void SendFullFramebufferUpdateRequest();
void SendAppropriateFramebufferUpdateRequest();
void SendFramebufferUpdateRequest(int x, int y, int w, int h, bool incremental);
void ProcessPointerEvent(int x, int y, DWORD keyflags, UINT msg);
void SubProcessPointerEvent(int x, int y, DWORD keyflags);
void ProcessMouseWheel(int delta); // RealVNC 335 method
void SendPointerEvent(int x, int y, int buttonMask);
#ifndef _ULTRAVNCAX_
void ProcessKeyEvent(int virtkey, DWORD keyData);
#else
public:
void ProcessKeyEvent(int virtkey, DWORD keyData);
#endif
void SendKeyEvent(CARD32 key, bool down);
void ReadScreenUpdate();
void Update(RECT *pRect);
void SizeWindow();
bool ScrollScreen(int dx, int dy);
void UpdateScrollbars();
void ReadRawRect(rfbFramebufferUpdateRectHeader *pfburh);
void ReadUltraRect(rfbFramebufferUpdateRectHeader *pfburh);
void ReadUltraZip(rfbFramebufferUpdateRectHeader *pfburh,HRGN *prgn);
void ReadCopyRect(rfbFramebufferUpdateRectHeader *pfburh);
void ReadRRERect(rfbFramebufferUpdateRectHeader *pfburh);
void ReadCoRRERect(rfbFramebufferUpdateRectHeader *pfburh);
void ReadHextileRect(rfbFramebufferUpdateRectHeader *pfburh);
void ReadZlibRect(rfbFramebufferUpdateRectHeader *pfburh,int XOR);
void ReadSolidRect(rfbFramebufferUpdateRectHeader *pfburh);
void HandleHextileEncoding8(int x, int y, int w, int h);
void HandleHextileEncoding16(int x, int y, int w, int h);
void HandleHextileEncoding32(int x, int y, int w, int h);
void ReadRBSRect(rfbFramebufferUpdateRectHeader *pfburh);
BOOL DrawRBSRect8(int x, int y, int w, int h, CARD8 **pptr);
BOOL DrawRBSRect16(int x, int y, int w, int h, CARD8 **pptr);
BOOL DrawRBSRect32(int x, int y, int w, int h, CARD8 **pptr);
// ClientConnectionFullScreen.cpp
void SetFullScreenMode(bool enable);
bool InFullScreenMode();
void RealiseFullScreenMode();
bool BumpScroll(int x, int y);
CTitleBar TitleBar; //Added by: Lars Werner (http://lars.werner.no)
//SINGLE WINDOW
void ReadNewFBSize(rfbFramebufferUpdateRectHeader *pfburh);
// Caching
void SaveArea(RECT &r);
void CleanCache(RECT &r);
void RestoreArea(RECT &r);
void ReadCacheRect(rfbFramebufferUpdateRectHeader *pfburh);
void ClearCache();
void ReadCacheZip(rfbFramebufferUpdateRectHeader *pfburh,HRGN *prgn);
void ReadSolMonoZip(rfbFramebufferUpdateRectHeader *pfburh,HRGN *prgn);
// ClientConnectionTight.cpp
void ReadTightRect(rfbFramebufferUpdateRectHeader *pfburh);
int ReadCompactLen();
int InitFilterCopy (int rw, int rh);
int InitFilterGradient (int rw, int rh);
int InitFilterPalette (int rw, int rh);
void FilterCopy8 (int numRows);
void FilterCopy16 (int numRows);
void FilterCopy24 (int numRows);
void FilterCopy32 (int numRows);
void FilterGradient8 (int numRows);
void FilterGradient16 (int numRows);
void FilterGradient24 (int numRows);
void FilterGradient32 (int numRows);
void FilterPalette (int numRows);
void DecompressJpegRect(int x, int y, int w, int h);
// Tight ClientConnectionCursor.cpp
bool prevCursorSet;
HDC m_hSavedAreaDC;
HBITMAP m_hSavedAreaBitmap;
COLORREF *rcSource;
bool *rcMask;
int rcHotX, rcHotY, rcWidth, rcHeight;
int rcCursorX, rcCursorY;
int rcLockX, rcLockY, rcLockWidth, rcLockHeight;
bool rcCursorHidden, rcLockSet;
void ReadCursorShape(rfbFramebufferUpdateRectHeader *pfburh);
// marscha PointerPos
void ReadCursorPos(rfbFramebufferUpdateRectHeader *pfburh);
void SoftCursorLockArea(int x, int y, int w, int h);
void SoftCursorUnlockScreen();
void SoftCursorMove(int x, int y);
void SoftCursorFree();
bool SoftCursorInLockedArea();
void SoftCursorSaveArea();
void SoftCursorRestoreArea();
void SoftCursorDraw();
void SoftCursorToScreen(RECT *screenArea, POINT *cursorOffset);
void InvalidateScreenRect(const RECT *pRect);
void InvalidateRegion(const RECT *pRect,HRGN *prgn);
// ClientConnectionZlibHex.cpp
void HandleZlibHexEncoding8(int x, int y, int w, int h);
void HandleZlibHexEncoding16(int x, int y, int w, int h);
void HandleZlibHexEncoding32(int x, int y, int w, int h);
void HandleZlibHexSubencodingStream8(int x, int y, int w, int h, int subencoding);
void HandleZlibHexSubencodingStream16(int x, int y, int w, int h, int subencoding);
void HandleZlibHexSubencodingStream32(int x, int y, int w, int h, int subencoding);
void HandleZlibHexSubencodingBuf8(int x, int y, int w, int h, int subencoding, unsigned char * buffer);
void HandleZlibHexSubencodingBuf16(int x, int y, int w, int h, int subencoding, unsigned char * buffer);
void HandleZlibHexSubencodingBuf32(int x, int y, int w, int h, int subencoding, unsigned char * buffer);
void ReadZlibHexRect(rfbFramebufferUpdateRectHeader *pfburh);
bool zlibDecompress(unsigned char *from_buf, unsigned char *to_buf, unsigned int count, unsigned int size, z_stream *decompressor);
// ClientConnectionClipboard.cpp
void ProcessLocalClipboardChange();
void UpdateLocalClipboard(char *buf, int len);
void SendClientCutText(char *str, int len);
void ReadServerCutText();
void ReadBell();
void SendRFBMsg(CARD8 msgType, void* data, int length);
void ReadExact(char *buf, int bytes);
void ReadExactProxy(char *buf, int bytes);
void ReadString(char *buf, int length);
void WriteExact(char *buf, int bytes);
void WriteExactProxy(char *buf, int bytes);
void WriteExact(char *buf, int bytes, CARD8 msgType); //sf@2002 - DSM Plugin
void GetFriendlySizeString(__int64 Size, char* szText);
void UpdateStatusFields(); // sf@2002
// This is what controls the thread
void * run_undetached(void* arg);
bool m_bKillThread;
// Modif sf@2002 - FileTransfer
friend class FileTransfer;
friend class TextChat;
// Modif sf@2002 - Server Scaling
bool SendServerScale(int nScale);
// Modif rdv@2002 - Server dis/enable input
bool SendServerInput(BOOL enabled);
bool SendSW(int x, int y);
// sf@2002 - DSM Plugin
void CheckNetRectBufferSize(int nBufSize);
void CheckZRLENetRectBufferSize(int nBufSize);
//
int EncodingStatusWindow,OldEncodingStatusWindow;
// Utilities
// These draw a solid rectangle of colour on the bitmap
// They assume the bitmap is already selected into the DC, and the
// DC is locked if necessary.
#ifndef UNDER_CE
// Normally this is an inline call to a GDI method.
inline void FillSolidRect(RECT *pRect, COLORREF color) {
COLORREF oldbgcol = SetBkColor(m_hBitmapDC, color);
// This is the call MFC uses for FillSolidRect. Who am I to argue?
::ExtTextOut(m_hBitmapDC, 0, 0, ETO_OPAQUE, pRect, NULL, 0, NULL);
};
#else
// Under WinCE this is a manual insert into a pixmap,
// and is a little too complicated for an inline.
void FillSolidRect(RECT *pRect, COLORREF color);
#endif // UNDER_CE
inline void FillSolidRect(int x, int y, int w, int h, COLORREF color) {
RECT r;
r.left = x; r.right = x + w;
r.top = y; r.bottom = y + h;
FillSolidRect(&r, color);
};
// how many other windows are owned by this process?
unsigned int CountProcessOtherWindows();
// Buffer for network operations
void CheckBufferSize(int bufsize);
char *m_netbuf;
int m_netbufsize;
omni_mutex m_bufferMutex, m_zlibBufferMutex,
m_bitmapdcMutex, m_clipMutex,
m_writeMutex, m_sockMutex,m_cursorMutex, m_readMutex ;
// Buffer for zlib decompression.
void CheckZlibBufferSize(int bufsize);
unsigned char *m_zlibbuf;
int m_zlibbufsize;
// zlib decompression state
bool m_decompStreamInited;
z_stream m_decompStream;
z_stream m_decompStreamRaw;
z_stream m_decompStreamEncoded;
void CheckZipBufferSize(int bufsize);
unsigned char *m_zipbuf;
int m_zipbufsize;
// sf@2002 - v1.1.0 - Buffer for zip decompression (FileTransfer)
void CheckFileZipBufferSize(int bufsize);
unsigned char *m_filezipbuf;
int m_filezipbufsize;
void CheckFileChunkBufferSize(int bufsize);
unsigned char *m_filechunkbuf;
int m_filechunkbufsize;
// Variables used by tight encoding:
// Separate buffer for tight-compressed data.
char m_tightbuf[TIGHT_ZLIB_BUFFER_SIZE];
// Four independent compression streams for zlib library.
z_stream m_tightZlibStream[4];
bool m_tightZlibStreamActive[4];
// Tight filter stuff. Should be initialized by filter initialization code.
tightFilterFunc m_tightCurrentFilter;
bool m_tightCutZeros;
int m_tightRectWidth, m_tightRectColors;
COLORREF m_tightPalette[256];
CARD8 m_tightPrevRow[2048*3*sizeof(CARD16)];
//
// Bitmap for local copy of screen, and DC for writing to it.
HBITMAP m_hBitmap;
HDC m_hBitmapDC;
HPALETTE m_hPalette;
// Bitmap for cache copy of screen, and DC for writing to it.
HBITMAP m_hCacheBitmap;
HDC m_hCacheBitmapDC;
#ifdef UNDER_CE
// Under WinCE this points to the DIB pixels.
BYTE* m_bits;
#endif
// Keyboard mapper
KeyMap m_keymap;
// RFB settings
VNCOptions m_opts;
FileTransfer *m_pFileTransfer; // Modif sf@2002 - FileTransfer
TextChat *m_pTextChat; // Modif sf@2002 - Text Chat
int m_nServerScale; // Modif sf@2002 - Server Scaling
// Modif sf@2002 - Data Stream Modification Plugin handling
int m_nTO;
CDSMPlugin *m_pDSMPlugin;
bool m_fUsePlugin;
BYTE* m_pNetRectBuf;
bool m_fReadFromNetRectBuf; //
int m_nNetRectBufOffset;
int m_nReadSize;
int m_nNetRectBufSize;
BYTE* m_pZRLENetRectBuf;
bool m_fReadFromZRLENetRectBuf; //
int m_nZRLENetRectBufOffset;
int m_nZRLEReadSize;
int m_nZRLENetRectBufSize;
omni_mutex m_NetRectBufferMutex;
omni_mutex m_ZRLENetRectBufferMutex;
omni_mutex m_ZipBufferMutex;
omni_mutex m_FileZipBufferMutex;
omni_mutex m_FileChunkBufferMutex;
omni_mutex m_ZlibBufferMutex;
TCHAR *m_desktopName;
unsigned char m_encPasswd[8];
unsigned char m_encPasswdMs[32];
char m_clearPasswd[256]; // Modif sf@2002
char m_strUserName[256];
char m_strPassword[256];
rfbServerInitMsg m_si;
rfbPixelFormat m_myFormat, m_pendingFormat;
// protocol version in use.
int m_majorVersion, m_minorVersion;
#ifndef _ULTRAVNCAX_
bool m_threadStarted, m_running;
#else
public:
bool m_threadStarted, m_running;
private:
#endif
// mid-connection format change requested
// sf@2002 - v1.1.0
bool m_pendingFormatChange;
bool m_pendingScaleChange;
bool m_pendingCacheInit;
// Display connection info;
void ShowConnInfo();
// Window may be scrollable - these control the scroll position
int m_hScrollPos, m_hScrollMax, m_vScrollPos, m_vScrollMax;
// The current window size
int m_winwidth, m_winheight;
__int64 m_BytesSend;
__int64 m_BytesRead;
HANDLE m_bitmapFRONT,m_bitmapBACK,m_bitmapNONE,m_logo_min;
// The size of the current client area
int m_cliwidth, m_cliheight;
// The size of a window needed to hold entire screen without scrollbars
int m_fullwinwidth, m_fullwinheight;
// The size of the CE CommandBar
int m_barheight;
// Dormant basically means minimized; updates will not be requested
// while dormant.
void SetDormant(bool newstate);
bool m_dormant;
// The number of bytes required to hold at least one pixel.
unsigned int m_minPixelBytes;
// Next window in clipboard chain
HWND m_hwndNextViewer;
bool m_initialClipboardSeen;
// Are we waiting on a timer for emulating three buttons?
bool m_waitingOnEmulateTimer;
// Or are we emulating the middle button now?
bool m_emulatingMiddleButton;
// Emulate 3 buttons mouse timer:
UINT m_emulate3ButtonsTimer;
// Buttons pressed, waiting for timer in emulating 3 buttons:
DWORD m_emulateKeyFlags;
int m_emulateButtonPressedX;
int m_emulateButtonPressedY;
// BmpFlasher *flash;
// ms logon
BOOL m_ms_logon;
char m_ad_passwd[256];
char m_ad_domain[256];
char m_ad_user[256];
// sf@2002 - FileTRansfer on server
BOOL m_fServerKnowsFileTransfer;
// sf@2002 - Auto mode
int m_nConfig;
// sf@2002 - Options Window flag
BOOL m_fOptionsOpen;
BOOL m_fStatusOpen;
int m_nStatusTimer;
// int m_FTtimer;
int oldPointerX, oldPointerY, oldButtonMask;
int kbitsPerSecond;
int m_lLastChangeTime; // sf@2003 - Last time the Auto mode has changed the encoding
public :
bool m_fScalingDone; // sf@2003 - Auto Scaling flag
private :
rdr::FdInStream* fis;
rdr::ZlibInStream* zis;
void zrleDecode(int x, int y, int w, int h);
void zrleDecode8(int x, int y, int w, int h, rdr::InStream* is,
rdr::ZlibInStream* zis, rdr::U8* buf);
void zrleDecode16(int x, int y, int w, int h, rdr::InStream* is,
rdr::ZlibInStream* zis, rdr::U16* buf);
void zrleDecode24A(int x, int y, int w, int h, rdr::InStream* is,
rdr::ZlibInStream* zis, rdr::U32* buf);
void zrleDecode24B(int x, int y, int w, int h, rdr::InStream* is,
rdr::ZlibInStream* zis, rdr::U32* buf);
void zrleDecode32(int x, int y, int w, int h, rdr::InStream* is,
rdr::ZlibInStream* zis, rdr::U32* buf);
//UltraFast
void ConvertAll(int width, int height, int xx, int yy,int bytes_per_pixel,BYTE* source,BYTE* dest,int framebufferWidth);
void SolidColor(int width, int height, int xx, int yy,int bytes_per_pixel,BYTE* source,BYTE* dest,int framebufferWidth);
HDC m_hmemdc;
HBITMAP m_membitmap;
VOID *m_DIBbits;
bool UltraFast;
void ClientConnection::Createdib();
bool Check_Rectangle_borders(int x,int y,int w,int h);
BOOL m_BigToolbar;
DWORD newtick;
DWORD oldtick;
bool Pressed_Cancel;
#ifdef _ULTRAVNCAX_
HWND m_hwndAx; // HWND of the currently initializing ActiveX window.
HWND* m_pHwndAppFrame; // HWND of the VNC APP main frame.
#endif
};
// Some handy classes for temporary GDI object selection
// These select objects when constructed and automatically release them when destructed.
class ObjectSelector {
public:
ObjectSelector(HDC hdc, HGDIOBJ hobj) { m_hdc = hdc; m_hOldObj = SelectObject(hdc, hobj); }
~ObjectSelector() { m_hOldObj = SelectObject(m_hdc, m_hOldObj); }
HGDIOBJ m_hOldObj;
HDC m_hdc;
};
class PaletteSelector {
public:
PaletteSelector(HDC hdc, HPALETTE hpal) {
m_hdc = hdc;
if (hpal)
{
m_hOldPal = SelectPalette(hdc, hpal, FALSE);
RealizePalette(hdc);
}
}
~PaletteSelector() {
if(m_hOldPal)
{
m_hOldPal = SelectPalette(m_hdc, m_hOldPal, FALSE);
RealizePalette(m_hdc);
}
}
HPALETTE m_hOldPal;
HDC m_hdc;
};
class TempDC {
public:
TempDC(HWND hwnd) { m_hdc = GetDC(hwnd); m_hwnd = hwnd; }
~TempDC() { ReleaseDC(m_hwnd, m_hdc); }
operator HDC() {return m_hdc;};
HDC m_hdc;
HWND m_hwnd;
};
// Colour decoding utility functions
// Define rs,rm, bs,bm, gs & gm before using, eg with the following:
// read a pixel from the given address, and return a color value
#define SETUP_COLOR_SHORTCUTS \
CARD8 rs = m_myFormat.redShift; CARD16 rm = m_myFormat.redMax; \
CARD8 gs = m_myFormat.greenShift; CARD16 gm = m_myFormat.greenMax; \
CARD8 bs = m_myFormat.blueShift; CARD16 bm = m_myFormat.blueMax; \
#define COLOR_FROM_PIXEL8_ADDRESS(p) (PALETTERGB( \
(int) (((*(CARD8 *)(p) >> rs) & rm) * 255 / rm), \
(int) (((*(CARD8 *)(p) >> gs) & gm) * 255 / gm), \
(int) (((*(CARD8 *)(p) >> bs) & bm) * 255 / bm) ))
#define COLOR_FROM_PIXEL16_ADDRESS(p) (PALETTERGB( \
(int) ((( *(CARD16 *)(p) >> rs) & rm) * 255 / rm), \
(int) ((( *(CARD16 *)(p) >> gs) & gm) * 255 / gm), \
(int) ((( *(CARD16 *)(p) >> bs) & bm) * 255 / bm) ))
#define COLOR_FROM_PIXEL24_ADDRESS(p) (PALETTERGB( \
(int) (((CARD8 *)(p))[0]), \
(int) (((CARD8 *)(p))[1]), \
(int) (((CARD8 *)(p))[2]) ))
#define COLOR_FROM_PIXEL32_ADDRESS(p) (PALETTERGB( \
(int) ((( *(CARD32 *)(p) >> rs) & rm) * 255 / rm), \
(int) ((( *(CARD32 *)(p) >> gs) & gm) * 255 / gm), \
(int) ((( *(CARD32 *)(p) >> bs) & bm) * 255 / bm) ))
// The following may be faster if you already have a pixel value of the appropriate size
#define COLOR_FROM_PIXEL8(p) (PALETTERGB( \
(int) (((p >> rs) & rm) * 255 / rm), \
(int) (((p >> gs) & gm) * 255 / gm), \
(int) (((p >> bs) & bm) * 255 / bm) ))
#define COLOR_FROM_PIXEL16(p) (PALETTERGB( \
(int) ((( p >> rs) & rm) * 255 / rm), \
(int) ((( p >> gs) & gm) * 255 / gm), \
(int) ((( p >> bs) & bm) * 255 / bm) ))
#define COLOR_FROM_PIXEL32(p) (PALETTERGB( \
(int) (((p >> rs) & rm) * 255 / rm), \
(int) (((p >> gs) & gm) * 255 / gm), \
(int) (((p >> bs) & bm) * 255 / bm) ))
#ifdef UNDER_CE
#define SETPIXEL(b,x,y,c) SetPixel((b),(x),(y),(c))
#else
#define SETPIXEL(b,x,y,c) SetPixelV((b),(x),(y),(c))
#endif
#define SETPIXELS(buffer, bpp, x, y, w, h) \
{ \
CARD##bpp *p = (CARD##bpp *) buffer; \
register CARD##bpp pix; \
for (int k = y; k < y+h; k++) { \
for (int j = x; j < x+w; j++) { \
pix = *p; \
SETPIXEL(m_hBitmapDC, j,k, COLOR_FROM_PIXEL##bpp##(pix)); \
p++; \
} \
} \
}
#define SETPIXELS_NOCONV(buffer, x, y, w, h) \
{ \
CARD32 *p = (CARD32 *) buffer; \
for (int k = y; k < y+h; k++) { \
for (int j = x; j < x+w; j++) { \
SETPIXEL(m_hBitmapDC, j,k, *p); \
p++; \
} \
} \
}
#define SETXORPIXELS(mask,buffer, bpp, x, y, w, h,aantal) \
{ \
CARD##bpp *p = (CARD##bpp *) buffer; \
register CARD##bpp pix; \
int i=0; \
bool result; \
for (int k = y; k < y+h; k++) { \
for (int j = x; j < x+w; j++) { \
MYMASK(mask,i,result); \
if (result) \
{ \
pix = *p; \
SETPIXEL(m_hBitmapDC, j,k, COLOR_FROM_PIXEL##bpp##(pix)); \
p++; \
aantal++; \
} \
i++; \
} \
} \
}
#define SETXORSOLPIXELS(mask,buffer, color, bpp, x, y, w, h) \
{ \
CARD##bpp *p = (CARD##bpp *) buffer; \
CARD##bpp *pc = (CARD##bpp *) color; \
register CARD##bpp pix; \
int i=0; \
bool result; \
for (int k = y; k < y+h; k++) { \
for (int j = x; j < x+w; j++) { \
MYMASK(mask,i,result); \
if (result) \
{ \
pix = *p; \
SETPIXEL(m_hBitmapDC, j,k, COLOR_FROM_PIXEL##bpp##(pix)); \
p++; \
} \
else \
{ \
pix = *pc; \
SETPIXEL(m_hBitmapDC, j,k, COLOR_FROM_PIXEL##bpp##(pix));\
} \
i++; \
} \
} \
}
#define SETXORMONOPIXELS(mask,color2, color, bpp, x, y, w, h) \
{ \
CARD##bpp *pc2 = (CARD##bpp *) color2; \
CARD##bpp *pc = (CARD##bpp *) color; \
register CARD##bpp pix; \
int i=0; \
bool result; \
for (int k = y; k < y+h; k++) { \
for (int j = x; j < x+w; j++) { \
MYMASK(mask,i,result); \
if (result) \
{ \
pix = *pc2; \
SETPIXEL(m_hBitmapDC, j,k, COLOR_FROM_PIXEL##bpp##(pix)); \
} \
else \
{ \
pix = *pc; \
SETPIXEL(m_hBitmapDC, j,k, COLOR_FROM_PIXEL##bpp##(pix));\
} \
i++; \
} \
} \
}
#define SETSOLPIXELS(color, bpp, x, y, w, h) \
{ \
CARD##bpp *pc = (CARD##bpp *) color; \
register CARD##bpp pix; \
int i=0; \
for (int k = y; k < y+h; k++) { \
for (int j = x; j < x+w; j++) { \
pix = *pc; \
SETPIXEL(m_hBitmapDC, j,k, COLOR_FROM_PIXEL##bpp##(pix));\
i++; \
} \
} \
}
#define MYMASK(mask,i,result) \
{ \
int byte_nr,bit_nr; \
byte_nr=i/8; \
bit_nr=i%8; \
if (bit_nr==0) result=mask[byte_nr].b0; \
if (bit_nr==1) result=mask[byte_nr].b1; \
if (bit_nr==2) result=mask[byte_nr].b2; \
if (bit_nr==3) result=mask[byte_nr].b3; \
if (bit_nr==4) result=mask[byte_nr].b4; \
if (bit_nr==5) result=mask[byte_nr].b5; \
if (bit_nr==6) result=mask[byte_nr].b6; \
if (bit_nr==7) result=mask[byte_nr].b7; \
}
#endif