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);
 }