The "rfb_win32" library merged with VNC 4.1.1 code.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/branches/merge-with-vnc-4.1.1@523 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/rfb_win32/Win32Util.cxx b/rfb_win32/Win32Util.cxx
index 28fae2e..ef8039a 100644
--- a/rfb_win32/Win32Util.cxx
+++ b/rfb_win32/Win32Util.cxx
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
- *
+/* 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
@@ -18,221 +18,30 @@
// Win32Util.cxx
+#include <rfb_win32/ModuleFileName.h>
#include <rfb_win32/Win32Util.h>
-#include <rdr/Exception.h>
+#include <rfb_win32/MonitorInfo.h>
+#include <rfb_win32/Handle.h>
#include <rdr/HexOutStream.h>
-
+#include <rdr/Exception.h>
namespace rfb {
namespace win32 {
-LogicalPalette::LogicalPalette() : palette(0), numEntries(0) {
- BYTE buf[sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY)];
- LOGPALETTE* logpal = (LOGPALETTE*)buf;
- logpal->palVersion = 0x300;
- logpal->palNumEntries = 256;
- for (int i=0; i<256;i++) {
- logpal->palPalEntry[i].peRed = 0;
- logpal->palPalEntry[i].peGreen = 0;
- logpal->palPalEntry[i].peBlue = 0;
- logpal->palPalEntry[i].peFlags = 0;
- }
- palette = CreatePalette(logpal);
- if (!palette)
- throw rdr::SystemException("failed to CreatePalette", GetLastError());
-}
-
-LogicalPalette::~LogicalPalette() {
- if (palette)
- if (!DeleteObject(palette))
- throw rdr::SystemException("del palette failed", GetLastError());
-}
-
-void LogicalPalette::setEntries(int start, int count, const Colour* cols) {
- if (numEntries < count) {
- ResizePalette(palette, start+count);
- numEntries = start+count;
- }
- PALETTEENTRY* logpal = new PALETTEENTRY[count];
- for (int i=0; i<count; i++) {
- logpal[i].peRed = cols[i].r >> 8;
- logpal[i].peGreen = cols[i].g >> 8;
- logpal[i].peBlue = cols[i].b >> 8;
- logpal[i].peFlags = 0;
- }
- UnrealizeObject(palette);
- SetPaletteEntries(palette, start, count, logpal);
- delete [] logpal;
-}
-
-
-static LogWriter dcLog("DeviceContext");
-
-PixelFormat DeviceContext::getPF() const {
- return getPF(dc);
-}
-
-PixelFormat DeviceContext::getPF(HDC dc) {
- PixelFormat format;
- CompatibleBitmap bitmap(dc, 1, 1);
-
- // -=- Get the bitmap format information
- BitmapInfo bi;
- memset(&bi, 0, sizeof(bi));
- bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bi.bmiHeader.biBitCount = 0;
-
- if (!::GetDIBits(dc, bitmap, 0, 1, NULL, (BITMAPINFO*)&bi, DIB_RGB_COLORS)) {
- throw rdr::SystemException("unable to determine device pixel format", GetLastError());
- }
- if (!::GetDIBits(dc, bitmap, 0, 1, NULL, (BITMAPINFO*)&bi, DIB_RGB_COLORS)) {
- throw rdr::SystemException("unable to determine pixel shifts/palette", GetLastError());
- }
-
- // -=- Munge the bitmap info here
- switch (bi.bmiHeader.biBitCount) {
- case 1:
- case 4:
- bi.bmiHeader.biBitCount = 8;
- break;
- case 24:
- bi.bmiHeader.biBitCount = 32;
- break;
- }
- bi.bmiHeader.biPlanes = 1;
-
- format.trueColour = bi.bmiHeader.biBitCount > 8;
- format.bigEndian = 0;
- format.bpp = format.depth = bi.bmiHeader.biBitCount;
-
- if (format.trueColour) {
- DWORD rMask=0, gMask=0, bMask=0;
-
- // Which true colour format is the DIB section using?
- switch (bi.bmiHeader.biCompression) {
- case BI_RGB:
- // Default RGB layout
- switch (bi.bmiHeader.biBitCount) {
- case 16:
- // RGB 555 - High Colour
- dcLog.info("16-bit High Color");
- rMask = 0x7c00;
- bMask = 0x001f;
- gMask = 0x03e0;
- format.depth = 15;
- break;
- case 24:
- case 32:
- // RGB 888 - True Colour
- dcLog.info("24/32-bit High Color");
- rMask = 0xff0000;
- gMask = 0x00ff00;
- bMask = 0x0000ff;
- format.depth = 24;
- break;
- default:
- dcLog.error("bits per pixel %u not supported", bi.bmiHeader.biBitCount);
- throw rdr::Exception("unknown bits per pixel specified");
- };
- break;
- case BI_BITFIELDS:
- // Custom RGB layout
- rMask = bi.mask.red;
- gMask = bi.mask.green;
- bMask = bi.mask.blue;
- dcLog.info("BitFields format: %lu, (%lx, %lx, %lx)",
- bi.bmiHeader.biBitCount, rMask, gMask, bMask);
- if (format.bpp == 32)
- format.depth = 24; // ...probably
- break;
- };
-
- // Convert the data we just retrieved
- initMaxAndShift(rMask, &format.redMax, &format.redShift);
- initMaxAndShift(gMask, &format.greenMax, &format.greenShift);
- initMaxAndShift(bMask, &format.blueMax, &format.blueShift);
- }
-
- return format;
-}
-
-
-WindowDC::WindowDC(HWND wnd) : hwnd(wnd) {
- dc = GetDC(wnd);
- if (!dc)
- throw rdr::SystemException("GetDC failed", GetLastError());
-}
-WindowDC::~WindowDC() {
- if (dc)
- ReleaseDC(hwnd, dc);
-}
-
-
-CompatibleDC::CompatibleDC(HDC existing) {
- dc = CreateCompatibleDC(existing);
- if (!dc)
- throw rdr::SystemException("CreateCompatibleDC failed", GetLastError());
-}
-CompatibleDC::~CompatibleDC() {
- if (dc)
- DeleteDC(dc);
-}
-
-
-BitmapDC::BitmapDC(HDC hdc, HBITMAP hbitmap) : CompatibleDC(hdc){
- oldBitmap = (HBITMAP)SelectObject(dc, hbitmap);
- if (!oldBitmap)
- throw rdr::SystemException("SelectObject to CompatibleDC failed",
- GetLastError());
-}
-BitmapDC::~BitmapDC() {
- SelectObject(dc, oldBitmap);
-}
-
-
-CompatibleBitmap::CompatibleBitmap(HDC hdc, int width, int height) {
- hbmp = CreateCompatibleBitmap(hdc, width, height);
- if (!hbmp)
- throw rdr::SystemException("CreateCompatibleBitmap() failed",
- GetLastError());
-}
-CompatibleBitmap::~CompatibleBitmap() {
- if (hbmp) DeleteObject(hbmp);
-}
-
-
-PaletteSelector::PaletteSelector(HDC dc, HPALETTE pal) : device(dc), redrawRequired(false) {
- oldPal = SelectPalette(dc, pal, FALSE);
- redrawRequired = RealizePalette(dc) > 0;
-}
-PaletteSelector::~PaletteSelector() {
- if (oldPal) SelectPalette(device, oldPal, TRUE);
-}
-
-
-IconInfo::IconInfo(HICON icon) {
- if (!GetIconInfo(icon, this))
- throw rdr::SystemException("GetIconInfo() failed", GetLastError());
-}
-IconInfo::~IconInfo() {
- if (hbmColor)
- DeleteObject(hbmColor);
- if (hbmMask)
- DeleteObject(hbmMask);
-}
-
-
-ModuleFileName::ModuleFileName(HMODULE module) : TCharArray(MAX_PATH) {
- if (!module) module = GetModuleHandle(0);
- if (!GetModuleFileName(module, buf, MAX_PATH))
- buf[0] = 0;
-}
-
FileVersionInfo::FileVersionInfo(const TCHAR* filename) {
// Get executable name
ModuleFileName exeName;
- if (!filename) filename = exeName.buf;
+ if (!filename)
+ filename = exeName.buf;
+
+ // Attempt to open the file, to cause Access Denied, etc, errors
+ // to be correctly reported, since the GetFileVersionInfoXXX calls lie...
+ {
+ Handle file(CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0));
+ if (file.h == INVALID_HANDLE_VALUE)
+ throw rdr::SystemException("Failed to open file", GetLastError());
+ }
// Get version info size
DWORD handle;
@@ -249,7 +58,7 @@
const TCHAR* FileVersionInfo::getVerString(const TCHAR* name, DWORD langId) {
char langIdBuf[sizeof(langId)];
for (int i=sizeof(langIdBuf)-1; i>=0; i--) {
- langIdBuf[i] = langId & 0xff;
+ langIdBuf[i] = (char) (langId & 0xff);
langId = langId >> 8;
}
@@ -273,173 +82,31 @@
}
-static LogWriter dfbLog("DynamicFn");
-
-DynamicFnBase::DynamicFnBase(const TCHAR* dllName, const char* fnName) : dllHandle(0), fnPtr(0) {
- dllHandle = LoadLibrary(dllName);
- if (!dllHandle) {
- dfbLog.info("DLL %s not found (%d)", (const char*)CStr(dllName), GetLastError());
- return;
- }
- fnPtr = GetProcAddress(dllHandle, fnName);
- if (!fnPtr)
- dfbLog.info("proc %s not found in %s (%d)", fnName, (const char*)CStr(dllName), GetLastError());
-}
-
-DynamicFnBase::~DynamicFnBase() {
- if (dllHandle)
- FreeLibrary(dllHandle);
-}
-
-
-static LogWriter miLog("MonitorInfo");
-
-MonitorInfo::MonitorInfo(HWND window) {
-#if (WINVER >= 0x0500)
- typedef HMONITOR (WINAPI *_MonitorFromWindow_proto)(HWND,DWORD);
- rfb::win32::DynamicFn<_MonitorFromWindow_proto> _MonitorFromWindow(_T("user32.dll"), "MonitorFromWindow");
- typedef BOOL (WINAPI *_GetMonitorInfo_proto)(HMONITOR,LPMONITORINFO);
- rfb::win32::DynamicFn<_GetMonitorInfo_proto> _GetMonitorInfo(_T("user32.dll"), "GetMonitorInfoA");
-
- // Can we dynamically link to the monitor functions?
- if (_MonitorFromWindow.isValid()) {
- if (_GetMonitorInfo.isValid()) {
- HMONITOR monitor = (*_MonitorFromWindow)(window, MONITOR_DEFAULTTONEAREST);
- miLog.debug("monitor=%lx", monitor);
- if (monitor) {
- memset(this, 0, sizeof(MONITORINFOEXA));
- cbSize = sizeof(MONITORINFOEXA);
- if ((*_GetMonitorInfo)(monitor, this)) {
- miLog.debug("monitor is %d,%d-%d,%d", rcMonitor.left, rcMonitor.top, rcMonitor.right, rcMonitor.bottom);
- miLog.debug("work area is %d,%d-%d,%d", rcWork.left, rcWork.top, rcWork.right, rcWork.bottom);
- miLog.debug("device is \"%s\"", szDevice);
- return;
- }
- miLog.error("failed to get monitor info: %ld", GetLastError());
- }
- } else {
- miLog.debug("GetMonitorInfo not found");
- }
- } else {
- miLog.debug("MonitorFromWindow not found");
- }
-#else
-#pragma message ("not building in GetMonitorInfo")
- cbSize = sizeof(MonitorInfo);
- szDevice[0] = 0;
-#endif
-
- // Legacy fallbacks - just return the desktop settings
- miLog.debug("using legacy fall-backs");
- HWND desktop = GetDesktopWindow();
- GetWindowRect(desktop, &rcMonitor);
- SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0);
- dwFlags = 0;
-}
-
-
-#if (WINVER >= 0x0500)
-
-struct moveToMonitorData {
- HWND window;
- const char* monitorName;
-};
-
-typedef BOOL (WINAPI *_GetMonitorInfo_proto)(HMONITOR,LPMONITORINFO);
-static rfb::win32::DynamicFn<_GetMonitorInfo_proto> _GetMonitorInfo(_T("user32.dll"), "GetMonitorInfoA");
-
-static BOOL CALLBACK moveToMonitorEnumProc(HMONITOR monitor,
- HDC dc,
- LPRECT pos,
- LPARAM d) {
- moveToMonitorData* data = (moveToMonitorData*)d;
- MONITORINFOEXA info;
- memset(&info, 0, sizeof(info));
- info.cbSize = sizeof(info);
-
- if ((*_GetMonitorInfo)(monitor, &info)) {
- if (stricmp(data->monitorName, info.szDevice) == 0) {
- SetWindowPos(data->window, 0,
- info.rcMonitor.left, info.rcMonitor.top,
- info.rcMonitor.right, info.rcMonitor.bottom,
- SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-#endif
-
-void moveToMonitor(HWND handle, const char* device) {
- miLog.debug("moveToMonitor %s", device);
-
-#if (WINVER >= 0x500)
- typedef BOOL (WINAPI *_EnumDisplayMonitors_proto)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
- rfb::win32::DynamicFn<_EnumDisplayMonitors_proto> _EnumDisplayMonitors(_T("user32.dll"), "EnumDisplayMonitors");
- if (!_EnumDisplayMonitors.isValid()) {
- miLog.debug("EnumDisplayMonitors not found");
- return;
- }
-
- moveToMonitorData data;
- data.window = handle;
- data.monitorName = device;
-
- (*_EnumDisplayMonitors)(0, 0, &moveToMonitorEnumProc, (LPARAM)&data);
-#endif
-}
-
-
-void centerWindow(HWND handle, HWND parent, bool clipToParent) {
+void centerWindow(HWND handle, HWND parent) {
RECT r;
- if (parent && IsWindowVisible(parent)) {
- if (!GetWindowRect(parent, &r)) return;
- } else {
- MonitorInfo mi(handle);
+ MonitorInfo mi(parent ? parent : handle);
+ if (!parent || !IsWindowVisible(parent) || !GetWindowRect(parent, &r))
r=mi.rcWork;
- }
- centerWindow(handle, r, clipToParent);
+ centerWindow(handle, r);
+ mi.clipTo(handle);
}
-void centerWindow(HWND handle, const RECT& r, bool clipToRect) {
+void centerWindow(HWND handle, const RECT& r) {
RECT wr;
if (!GetWindowRect(handle, &wr)) return;
int w = wr.right-wr.left;
int h = wr.bottom-wr.top;
- if (clipToRect) {
- w = min(r.right-r.left, w);
- h = min(r.bottom-r.top, h);
- }
int x = (r.left + r.right - w)/2;
int y = (r.top + r.bottom - h)/2;
- UINT flags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | (clipToRect ? 0 : SWP_NOSIZE);
- SetWindowPos(handle, 0, x, y, w, h, flags);
+ UINT flags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOSIZE;
+ SetWindowPos(handle, 0, x, y, 0, 0, flags);
}
-
-int MsgBox(HWND parent, const TCHAR* msg, UINT flags) {
- const TCHAR* msgType = 0;
- UINT tflags = flags & 0x70;
- if (tflags == MB_ICONHAND)
- msgType = _T("Error");
- else if (tflags == MB_ICONQUESTION)
- msgType = _T("Question");
- else if (tflags == MB_ICONEXCLAMATION)
- msgType = _T("Warning");
- else if (tflags == MB_ICONASTERISK)
- msgType = _T("Information");
- flags |= MB_TOPMOST | MB_SETFOREGROUND;
- int len = _tcslen(AppName.buf) + 1;
- if (msgType) len += _tcslen(msgType) + 3;
- TCharArray title = new TCHAR[len];
- _tcscpy(title.buf, AppName.buf);
- if (msgType) {
- _tcscat(title.buf, _T(" : "));
- _tcscat(title.buf, msgType);
- }
- return MessageBox(parent, msg, title.buf, flags);
+void resizeWindow(HWND handle, int width, int height) {
+ RECT r;
+ GetWindowRect(handle, &r);
+ SetWindowPos(handle, 0, 0, 0, width, height, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
+ centerWindow(handle, r);
}