Author: akhaldi
Date: Wed Dec 16 22:05:19 2015
New Revision: 70370

URL: http://svn.reactos.org/svn/reactos?rev=70370&view=rev
Log:
[0.4.0] * Merge Hermès' clipboard related fixes.

Added:
    branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/scrollutils.c
      - copied, changed from r70334, 
trunk/reactos/base/applications/clipbrd/scrollutils.c
    branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/scrollutils.h
      - copied, changed from r70334, 
trunk/reactos/base/applications/clipbrd/scrollutils.h
Modified:
    branches/ros-branch-0_4_0/   (props changed)
    branches/ros-branch-0_4_0/reactos/   (props changed)
    branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/CMakeLists.txt
    branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/clipbrd.c
    branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/cliputils.c
    branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/fileutils.h
    branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/precomp.h
    branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/winutils.c
    branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/winutils.h
    branches/ros-branch-0_4_0/reactos/win32ss/user/ntuser/clipboard.c
    branches/ros-branch-0_4_0/reactos/win32ss/user/user32/windows/clipboard.c

Propchange: branches/ros-branch-0_4_0/
------------------------------------------------------------------------------
--- svn:mergeinfo       (original)
+++ svn:mergeinfo       Wed Dec 16 22:05:19 2015
@@ -1 +1 @@
-/trunk:70000-70321,70323-70324,70335-70337,70357-70358,70360,70363
+/trunk:70000-70321,70323-70324,70328-70337,70347,70349,70354-70355,70357-70358,70360,70363

Propchange: branches/ros-branch-0_4_0/reactos/
------------------------------------------------------------------------------
--- svn:mergeinfo       (original)
+++ svn:mergeinfo       Wed Dec 16 22:05:19 2015
@@ -20,4 +20,4 @@
 
/branches/usb-bringup:51335,51337,51341-51343,51348,51350,51353,51355,51365-51369,51372,51384-54388,54396-54398,54736-54737,54752-54754,54756-54760,54762,54764-54765,54767-54768,54772,54774-54777,54781,54787,54790-54792,54797-54798,54806,54808,54834-54838,54843,54850,54852,54856,54858-54859
 /branches/usb-bringup-trunk:55019-55543,55548-55554,55556-55567
 /branches/wlan-bringup:54809-54998
-/trunk/reactos:70000-70321,70323-70324,70335-70337,70357-70358,70360,70363
+/trunk/reactos:70000-70321,70323-70324,70328-70337,70347,70349,70354-70355,70357-70358,70360,70363

Modified: 
branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/CMakeLists.txt
URL: 
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/CMakeLists.txt?rev=70370&r1=70369&r2=70370&view=diff
==============================================================================
--- branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/CMakeLists.txt  
[iso-8859-1] (original)
+++ branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/CMakeLists.txt  
[iso-8859-1] Wed Dec 16 22:05:19 2015
@@ -4,6 +4,7 @@
     cliputils.c
     winutils.c
     fileutils.c
+    scrollutils.c
     precomp.h)
 
 add_executable(clipbrd ${SOURCE} clipbrd.rc)

Modified: branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/clipbrd.c
URL: 
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/clipbrd.c?rev=70370&r1=70369&r2=70370&view=diff
==============================================================================
--- branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/clipbrd.c       
[iso-8859-1] (original)
+++ branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/clipbrd.c       
[iso-8859-1] Wed Dec 16 22:05:19 2015
@@ -11,6 +11,21 @@
 static const WCHAR szClassName[] = L"ClipBookWClass";
 
 CLIPBOARD_GLOBALS Globals;
+SCROLLSTATE Scrollstate;
+
+static void UpdateLinesToScroll(void)
+{
+    UINT uLinesToScroll;
+
+    if (!SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &uLinesToScroll, 0))
+    {
+        Globals.uLinesToScroll = 3;
+    }
+    else
+    {
+        Globals.uLinesToScroll = uLinesToScroll;
+    }
+}
 
 static void SaveClipboardToFile(void)
 {
@@ -121,11 +136,18 @@
     }
     else
     {
-        Globals.uDisplayFormat =  uFormat;
-    }
+        Globals.uDisplayFormat = uFormat;
+    }
+
+    if (Globals.hDspBmp)
+    {
+        DeleteObject(Globals.hDspBmp);
+    }
+
+    ZeroMemory(&Scrollstate, sizeof(Scrollstate));
+    UpdateWindowScrollState(Globals.hMainWnd, Globals.hDspBmp, &Scrollstate);
 
     InvalidateRect(Globals.hMainWnd, NULL, TRUE);
-    UpdateWindow(Globals.hMainWnd);
 }
 
 static void InitMenuPopup(HMENU hMenu, LPARAM index)
@@ -234,8 +256,12 @@
         case CMD_ABOUT:
         {
             WCHAR szTitle[MAX_STRING_LEN];
+            HICON hIcon;
+
+            hIcon = LoadIconW(Globals.hInstance, MAKEINTRESOURCE(CLIP_ICON));
             LoadStringW(Globals.hInstance, STRING_CLIPBOARD, szTitle, 
ARRAYSIZE(szTitle));
-            ShellAboutW(Globals.hMainWnd, szTitle, 0, NULL);
+            ShellAboutW(Globals.hMainWnd, szTitle, 0, hIcon);
+            DeleteObject(hIcon);
             break;
         }
 
@@ -253,6 +279,11 @@
     PAINTSTRUCT ps;
     RECT rc;
 
+    if (!OpenClipboard(NULL))
+    {
+        return;
+    }
+
     hdc = BeginPaint(hWnd, &ps);
     GetClientRect(hWnd, &rc);
 
@@ -265,7 +296,7 @@
 
         case CF_UNICODETEXT:
         {
-            DrawTextFromClipboard(hdc, &rc, DT_LEFT);
+            DrawTextFromClipboard(hdc, &rc, DT_LEFT | DT_NOPREFIX);
             break;
         }
 
@@ -301,13 +332,14 @@
 
         default:
         {
-
-            DrawTextFromResource(Globals.hInstance, ERROR_UNSUPPORTED_FORMAT, 
hdc, &rc, DT_CENTER | DT_WORDBREAK);
+            DrawTextFromResource(Globals.hInstance, ERROR_UNSUPPORTED_FORMAT, 
hdc, &rc, DT_CENTER | DT_WORDBREAK | DT_NOPREFIX);
             break;
         }
     }
 
     EndPaint(hWnd, &ps);
+
+    CloseClipboard();
 }
 
 static LRESULT WINAPI MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM 
lParam)
@@ -320,10 +352,46 @@
             break;
         }
 
+        case WM_KEYDOWN:
+        {
+            HandleKeyboardScrollEvents(hWnd, uMsg, wParam, lParam);
+            break;
+        }
+
+        case WM_MOUSEWHEEL:
+        {
+            HandleMouseScrollEvents(hWnd, uMsg, wParam, lParam, &Scrollstate);
+            break;
+        }
+
+        case WM_HSCROLL:
+        {
+            HandleHorizontalScrollEvents(hWnd, uMsg, wParam, lParam, 
&Scrollstate);
+            break;
+        }
+
+        case WM_VSCROLL:
+        {
+            HandleVerticalScrollEvents(hWnd, uMsg, wParam, lParam, 
&Scrollstate);
+            break;
+        }
+
         case WM_SIZE:
         {
-            InvalidateRect(hWnd, NULL, TRUE);
-            UpdateWindow(hWnd);
+            UpdateWindowScrollState(hWnd, Globals.hDspBmp, &Scrollstate);
+
+            if ((Globals.uDisplayFormat == CF_METAFILEPICT) ||
+                (Globals.uDisplayFormat == CF_ENHMETAFILE) ||
+                (Globals.uDisplayFormat == CF_DSPENHMETAFILE) ||
+                (Globals.uDisplayFormat == CF_DSPMETAFILEPICT))
+            {
+                InvalidateRect(Globals.hMainWnd, NULL, FALSE);
+            }
+            else if (!IsClipboardFormatSupported(Globals.uDisplayFormat))
+            {
+                InvalidateRect(Globals.hMainWnd, NULL, TRUE);
+            }
+
             break;
         }
 
@@ -394,6 +462,45 @@
         case WM_DROPFILES:
         {
             LoadClipboardFromDrop((HDROP)wParam);
+            break;
+        }
+
+        case WM_QUERYNEWPALETTE:
+        {
+            if (RealizeClipboardPalette(hWnd) != GDI_ERROR)
+            {
+                InvalidateRect(hWnd, NULL, TRUE);
+                UpdateWindow(hWnd);
+                return TRUE;
+            }
+            return FALSE;
+        }
+
+        case WM_PALETTECHANGED:
+        {
+            if ((HWND)wParam != hWnd)
+            {
+                if (RealizeClipboardPalette(hWnd) != GDI_ERROR)
+                {
+                    InvalidateRect(hWnd, NULL, TRUE);
+                    UpdateWindow(hWnd);
+                }
+            }
+            break;
+        }
+
+        case WM_SYSCOLORCHANGE:
+        {
+            SetDisplayFormat(Globals.uDisplayFormat);
+            break;
+        }
+
+        case WM_SETTINGCHANGE:
+        {
+            if (wParam == SPI_SETWHEELSCROLLLINES)
+            {
+                UpdateLinesToScroll();
+            }
             break;
         }
 
@@ -467,6 +574,8 @@
         ShowLastWin32Error(Globals.hMainWnd);
     }
 
+    UpdateLinesToScroll();
+
     while (GetMessageW(&msg, 0, 0, 0))
     {
         if (!TranslateAcceleratorW(Globals.hMainWnd, hAccel, &msg))
@@ -476,5 +585,10 @@
         }
     }
 
+    if (Globals.hDspBmp)
+    {
+        DeleteObject(Globals.hDspBmp);
+    }
+
     return (int)msg.wParam;
 }

Modified: 
branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/cliputils.c
URL: 
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/cliputils.c?rev=70370&r1=70369&r2=70370&view=diff
==============================================================================
--- branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/cliputils.c     
[iso-8859-1] (original)
+++ branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/cliputils.c     
[iso-8859-1] Wed Dec 16 22:05:19 2015
@@ -108,17 +108,21 @@
         ShowLastWin32Error(Globals.hMainWnd);
     }
 
-    if (!CloseClipboard())
-    {
-        ShowLastWin32Error(Globals.hMainWnd);
-    }
+    CloseClipboard();
 }
 
 UINT GetAutomaticClipboardFormat(void)
 {
-    UINT uFormatList[] = {CF_UNICODETEXT, CF_ENHMETAFILE, CF_METAFILEPICT, 
CF_DIBV5, CF_DIB, CF_BITMAP};
+    static UINT uFormatList[] = {
+        CF_UNICODETEXT,
+        CF_ENHMETAFILE,
+        CF_METAFILEPICT,
+        CF_DIBV5,
+        CF_DIB,
+        CF_BITMAP
+    };
 
-    return GetPriorityClipboardFormat(uFormatList, 6);
+    return GetPriorityClipboardFormat(uFormatList, ARRAYSIZE(uFormatList));
 }
 
 BOOL IsClipboardFormatSupported(UINT uFormat)

Modified: 
branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/fileutils.h
URL: 
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/fileutils.h?rev=70370&r1=70369&r2=70370&view=diff
==============================================================================
--- branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/fileutils.h     
[iso-8859-1] (original)
+++ branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/fileutils.h     
[iso-8859-1] Wed Dec 16 22:05:19 2015
@@ -1,7 +1,7 @@
 /*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS Clipboard Viewer
- * FILE:            base/applications/clipbrd/fileutils.c
+ * FILE:            base/applications/clipbrd/fileutils.h
  * PURPOSE:         Clipboard file format helper functions.
  * PROGRAMMERS:     Ricardo Hanke
  */

Modified: branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/precomp.h
URL: 
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/precomp.h?rev=70370&r1=70369&r2=70370&view=diff
==============================================================================
--- branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/precomp.h       
[iso-8859-1] (original)
+++ branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/precomp.h       
[iso-8859-1] Wed Dec 16 22:05:19 2015
@@ -2,6 +2,8 @@
 #define _CLIPBRD_PCH_
 
 // #pragma once
+
+#include <limits.h>
 
 #include <windef.h>
 #include <winbase.h>
@@ -15,6 +17,7 @@
 #include "cliputils.h"
 #include "fileutils.h"
 #include "winutils.h"
+#include "scrollutils.h"
 
 #define MAX_STRING_LEN 255
 #define DISPLAY_MENU_POS 2
@@ -28,6 +31,8 @@
     HMENU hMenu;
     UINT uDisplayFormat;
     UINT uCheckedItem;
+    UINT uLinesToScroll;
+    HBITMAP hDspBmp;
 } CLIPBOARD_GLOBALS;
 
 extern CLIPBOARD_GLOBALS Globals;

Copied: 
branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/scrollutils.c (from 
r70334, trunk/reactos/base/applications/clipbrd/scrollutils.c)
URL: 
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/scrollutils.c?p2=branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/scrollutils.c&p1=trunk/reactos/base/applications/clipbrd/scrollutils.c&r1=70334&r2=70370&rev=70370&view=diff
==============================================================================
--- trunk/reactos/base/applications/clipbrd/scrollutils.c       [iso-8859-1] 
(original)
+++ branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/scrollutils.c   
[iso-8859-1] Wed Dec 16 22:05:19 2015
@@ -70,6 +70,53 @@
     }
 }
 
+void HandleMouseScrollEvents(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM 
lParam, LPSCROLLSTATE state)
+{
+    SCROLLINFO si; 
+    int Delta;
+    int NewPos;
+
+    si.cbSize = sizeof(si);
+    si.fMask = SIF_PAGE;
+    GetScrollInfo(hWnd, SB_VERT, &si);
+
+    if (Globals.uLinesToScroll == WHEEL_PAGESCROLL)
+    {
+        NewPos = si.nPage;
+    }
+    else
+    {
+        NewPos = Globals.uLinesToScroll * 5;
+    }
+
+    if (GET_WHEEL_DELTA_WPARAM(wParam) > 0)
+    {
+        NewPos = state->CurrentY - NewPos;
+    }
+    else
+    {
+        NewPos = state->CurrentY + NewPos;
+    }
+
+    NewPos = min(state->MaxY, max(0, NewPos));
+
+    if (NewPos == state->CurrentY)
+    {
+        return;
+    }
+
+    Delta = NewPos - state->CurrentY;
+
+    state->CurrentY = NewPos;
+
+    ScrollWindowEx(hWnd, 0, -Delta, NULL, NULL, NULL, NULL, SW_INVALIDATE);
+
+    si.cbSize = sizeof(si);
+    si.fMask = SIF_POS;
+    si.nPos = state->CurrentY;
+    SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
+}
+
 void HandleHorizontalScrollEvents(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM 
lParam, LPSCROLLSTATE state)
 {
     SCROLLINFO si; 

Copied: 
branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/scrollutils.h (from 
r70334, trunk/reactos/base/applications/clipbrd/scrollutils.h)
URL: 
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/scrollutils.h?p2=branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/scrollutils.h&p1=trunk/reactos/base/applications/clipbrd/scrollutils.h&r1=70334&r2=70370&rev=70370&view=diff
==============================================================================
--- trunk/reactos/base/applications/clipbrd/scrollutils.h       [iso-8859-1] 
(original)
+++ branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/scrollutils.h   
[iso-8859-1] Wed Dec 16 22:05:19 2015
@@ -15,6 +15,7 @@
 } SCROLLSTATE, *LPSCROLLSTATE;
 
 void HandleKeyboardScrollEvents(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM 
lParam);
+void HandleMouseScrollEvents(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM 
lParam, LPSCROLLSTATE state);
 void HandleHorizontalScrollEvents(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM 
lParam, LPSCROLLSTATE state);
 void HandleVerticalScrollEvents(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM 
lParam, LPSCROLLSTATE state);
 void UpdateWindowScrollState(HWND hWnd, HBITMAP hBmp, LPSCROLLSTATE lpState);

Modified: branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/winutils.c
URL: 
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/winutils.c?rev=70370&r1=70369&r2=70370&view=diff
==============================================================================
--- branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/winutils.c      
[iso-8859-1] (original)
+++ branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/winutils.c      
[iso-8859-1] Wed Dec 16 22:05:19 2015
@@ -14,11 +14,9 @@
     LPWSTR lpMsgBuf = NULL;
 
     dwError = GetLastError();
-    if (dwError == NO_ERROR)
-        return;
 
     FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-                   NULL, dwError, 0, (LPWSTR)&lpMsgBuf, 0,  NULL);
+                   NULL, dwError, 0, (LPWSTR)&lpMsgBuf, 0, NULL);
     MessageBoxW(hwndParent, lpMsgBuf, NULL, MB_OK | MB_ICONERROR);
     LocalFree(lpMsgBuf);
 }
@@ -73,9 +71,6 @@
     HGLOBAL hGlobal;
     LPWSTR lpchText;
 
-    if (!OpenClipboard(NULL))
-        return;
-
     hGlobal = GetClipboardData(CF_UNICODETEXT);
     if (!hGlobal)
         return;
@@ -86,16 +81,12 @@
 
     DrawTextW(hDC, lpchText, -1, lpRect, uFormat);
     GlobalUnlock(hGlobal);
-    CloseClipboard();
 }
 
 void BitBltFromClipboard(HDC hdcDest, int nXDest, int nYDest, int nWidth, int 
nHeight, int nXSrc, int nYSrc, DWORD dwRop)
 {
     HDC hdcMem;
     HBITMAP hbm;
-
-    if (!OpenClipboard(NULL))
-        return;
 
     hdcMem = CreateCompatibleDC(hdcDest);
     if (hdcMem)
@@ -105,18 +96,15 @@
         BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcMem, nXSrc, nYSrc, 
dwRop);
         DeleteDC(hdcMem);
     }
-    CloseClipboard();
 }
 
 void SetDIBitsToDeviceFromClipboard(UINT uFormat, HDC hdc, int XDest, int 
YDest, int XSrc, int YSrc, UINT uStartScan, UINT fuColorUse)
 {
     LPBITMAPINFOHEADER lpInfoHeader;
     LPBYTE lpBits;
+    LONG bmWidth, bmHeight;
+    DWORD dwPalSize = 0;
     HGLOBAL hGlobal;
-    INT iPalSize;
-
-    if (!OpenClipboard(NULL))
-        return;
 
     hGlobal = GetClipboardData(uFormat);
     if (!hGlobal)
@@ -126,30 +114,104 @@
     if (!lpInfoHeader)
         return;
 
-    if (lpInfoHeader->biBitCount < 16)
-    {
-        iPalSize = (1 << lpInfoHeader->biBitCount) * 4;
+    if (lpInfoHeader->biSize == sizeof(BITMAPCOREHEADER))
+    {
+        LPBITMAPCOREHEADER lpCoreHeader = (LPBITMAPCOREHEADER)lpInfoHeader;
+
+        dwPalSize = 0;
+
+        if (lpCoreHeader->bcBitCount <= 8)
+        {
+            dwPalSize = (1 << lpCoreHeader->bcBitCount);
+
+            if (fuColorUse == DIB_RGB_COLORS)
+                dwPalSize *= sizeof(RGBTRIPLE);
+            else
+                dwPalSize *= sizeof(WORD);
+        }
+
+        bmWidth  = lpCoreHeader->bcWidth;
+        bmHeight = lpCoreHeader->bcHeight;
+    }
+    else if ((lpInfoHeader->biSize == sizeof(BITMAPINFOHEADER)) ||
+             (lpInfoHeader->biSize == sizeof(BITMAPV4HEADER))   ||
+             (lpInfoHeader->biSize == sizeof(BITMAPV5HEADER)))
+    {
+        dwPalSize = lpInfoHeader->biClrUsed;
+
+        if ((dwPalSize == 0) && (lpInfoHeader->biBitCount <= 8))
+            dwPalSize = (1 << lpInfoHeader->biBitCount);
+
+        if (fuColorUse == DIB_RGB_COLORS)
+            dwPalSize *= sizeof(RGBQUAD);
+        else
+            dwPalSize *= sizeof(WORD);
+
+        if (/*(lpInfoHeader->biSize == sizeof(BITMAPINFOHEADER)) &&*/
+            (lpInfoHeader->biCompression == BI_BITFIELDS))
+        {
+            dwPalSize += 3 * sizeof(DWORD);
+        }
+
+        /*
+         * This is a (disabled) hack for Windows, when uFormat == CF_DIB
+         * it needs yet another extra 3 DWORDs, in addition to the
+         * ones already taken into account in via the compression.
+         * This problem doesn't happen when uFormat == CF_DIBV5
+         * (in that case, when compression is taken into account,
+         * everything is nice).
+         *
+         * NOTE 1: This fix is only for us, because when one pastes DIBs
+         * directly in apps, the bitmap offset problem is still present.
+         *
+         * NOTE 2: The problem can be seen with Windows' clipbrd.exe if
+         * one copies a CF_DIB image in the clipboard. By default Windows'
+         * clipbrd.exe works with CF_DIBV5 and CF_BITMAP, so the problem
+         * is unseen, and the clipboard doesn't have to convert to CF_DIB.
+         *
+         * FIXME: investigate!!
+         * ANSWER: this is a Windows bug; part of the answer is there:
+         * 
http://go4answers.webhost4life.com/Help/bug-clipboard-format-conversions-28724.aspx
+         * May be related:
+         * http://blog.talosintel.com/2015/10/dangerous-clipboard.html
+         */
+#if 0
+        if ((lpInfoHeader->biSize == sizeof(BITMAPINFOHEADER)) &&
+            (lpInfoHeader->biCompression == BI_BITFIELDS))
+        {
+            dwPalSize += 3 * sizeof(DWORD);
+        }
+#endif
+
+        bmWidth  = lpInfoHeader->biWidth;
+        bmHeight = lpInfoHeader->biHeight;
     }
     else
     {
-        iPalSize = 0;
-    }
-
-    lpBits = (LPBYTE)lpInfoHeader + lpInfoHeader->biSize + iPalSize;
-
-    SetDIBitsToDevice(hdc, XDest, YDest, lpInfoHeader->biWidth, 
lpInfoHeader->biHeight, XSrc, YSrc, uStartScan, lpInfoHeader->biHeight, lpBits, 
(LPBITMAPINFO)lpInfoHeader, fuColorUse);
+        /* Invalid format */
+        GlobalUnlock(hGlobal);
+        return;
+    }
+
+    lpBits = (LPBYTE)lpInfoHeader + lpInfoHeader->biSize + dwPalSize;
+
+    SetDIBitsToDevice(hdc,
+                      XDest, YDest,
+                      bmWidth, bmHeight,
+                      XSrc, YSrc,
+                      uStartScan,
+                      bmHeight,
+                      lpBits,
+                      (LPBITMAPINFO)lpInfoHeader,
+                      fuColorUse);
 
     GlobalUnlock(hGlobal);
-    CloseClipboard();
 }
 
 void PlayMetaFileFromClipboard(HDC hdc, const RECT *lpRect)
 {
     LPMETAFILEPICT mp;
     HGLOBAL hGlobal;
-
-    if (!OpenClipboard(NULL))
-        return;
 
     hGlobal = GetClipboardData(CF_METAFILEPICT);
     if (!hGlobal)
@@ -164,17 +226,62 @@
     SetViewportOrgEx(hdc, lpRect->left, lpRect->top, NULL);
     PlayMetaFile(hdc, mp->hMF);
     GlobalUnlock(hGlobal);
-    CloseClipboard();
 }
 
 void PlayEnhMetaFileFromClipboard(HDC hdc, const RECT *lpRect)
 {
     HENHMETAFILE hEmf;
-
-    if (!OpenClipboard(NULL))
-        return;
 
     hEmf = GetClipboardData(CF_ENHMETAFILE);
     PlayEnhMetaFile(hdc, hEmf, lpRect);
+}
+
+UINT RealizeClipboardPalette(HWND hWnd)
+{
+    HPALETTE hPalette;
+    HPALETTE hOldPalette;
+    UINT uResult;
+    HDC hDevContext;
+
+    if (!OpenClipboard(NULL))
+    {
+        return GDI_ERROR;
+    }
+
+    if (!IsClipboardFormatAvailable(CF_PALETTE))
+    {
+        CloseClipboard();
+        return GDI_ERROR;
+    }
+
+    hPalette = GetClipboardData(CF_PALETTE);
+    if (!hPalette)
+    {
+        CloseClipboard();
+        return GDI_ERROR;
+    }
+
+    hDevContext = GetDC(hWnd);
+    if (!hDevContext)
+    {
+        CloseClipboard();
+        return GDI_ERROR;
+    }
+
+    hOldPalette = SelectPalette(hDevContext, hPalette, FALSE);
+    if (!hOldPalette)
+    {
+        ReleaseDC(hWnd, hDevContext);
+        CloseClipboard();
+        return GDI_ERROR;
+    }
+
+    uResult = RealizePalette(hDevContext);
+
+    SelectPalette(hDevContext, hOldPalette, FALSE);
+    ReleaseDC(hWnd, hDevContext);
+
     CloseClipboard();
-}
+
+    return uResult;
+}

Modified: branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/winutils.h
URL: 
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/winutils.h?rev=70370&r1=70369&r2=70370&view=diff
==============================================================================
--- branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/winutils.h      
[iso-8859-1] (original)
+++ branches/ros-branch-0_4_0/reactos/base/applications/clipbrd/winutils.h      
[iso-8859-1] Wed Dec 16 22:05:19 2015
@@ -1,7 +1,7 @@
 /*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS Clipboard Viewer
- * FILE:            base/applications/clipbrd/winutils.c
+ * FILE:            base/applications/clipbrd/winutils.h
  * PURPOSE:         Miscellaneous helper functions.
  * PROGRAMMERS:     Ricardo Hanke
  */
@@ -15,3 +15,4 @@
 void SetDIBitsToDeviceFromClipboard(UINT uFormat, HDC hdc, int XDest, int 
YDest, int XSrc, int YSrc, UINT uStartScan, UINT fuColorUse);
 void PlayMetaFileFromClipboard(HDC hdc, const RECT *lpRect);
 void PlayEnhMetaFileFromClipboard(HDC hdc, const RECT *lpRect);
+UINT RealizeClipboardPalette(HWND hWnd);

Modified: branches/ros-branch-0_4_0/reactos/win32ss/user/ntuser/clipboard.c
URL: 
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_0/reactos/win32ss/user/ntuser/clipboard.c?rev=70370&r1=70369&r2=70370&view=diff
==============================================================================
--- branches/ros-branch-0_4_0/reactos/win32ss/user/ntuser/clipboard.c   
[iso-8859-1] (original)
+++ branches/ros-branch-0_4_0/reactos/win32ss/user/ntuser/clipboard.c   
[iso-8859-1] Wed Dec 16 22:05:19 2015
@@ -40,11 +40,11 @@
 static PCLIP FASTCALL
 IntIsFormatAvailable(PWINSTATION_OBJECT pWinStaObj, UINT fmt)
 {
-    unsigned i = 0;
+    DWORD i;
 
     for (i = 0; i < pWinStaObj->cNumClipFormats; ++i)
     {
-           if (pWinStaObj->pClipBase[i].fmt == fmt)
+        if (pWinStaObj->pClipBase[i].fmt == fmt)
             return &pWinStaObj->pClipBase[i];
     }
 
@@ -125,13 +125,8 @@
 IntIsClipboardOpenByMe(PWINSTATION_OBJECT pWinSta)
 {
     /* Check if current thread has opened the clipboard */
-    if (pWinSta->ptiClipLock &&
-        pWinSta->ptiClipLock == PsGetCurrentThreadWin32Thread())
-    {
-        return TRUE;
-    }
-
-    return FALSE;
+    return (pWinSta->ptiClipLock &&
+            pWinSta->ptiClipLock == PsGetCurrentThreadWin32Thread());
 }
 
 static VOID NTAPI
@@ -232,14 +227,14 @@
 
     pDibEl = IntIsFormatAvailable(pWinStaObj, CF_DIB);
     ASSERT(pDibEl && !IS_DATA_SYNTHESIZED(pDibEl));
-    if(!pDibEl->fGlobalHandle)
+    if (!pDibEl->fGlobalHandle)
         return;
 
     pMemObj = (PCLIPBOARDDATA)UserGetObject(gHandleTable, pDibEl->hData, 
TYPE_CLIPDATA);
     if (!pMemObj)
         return;
 
-       pBmi = (BITMAPINFO*)pMemObj->Data;
+    pBmi = (BITMAPINFO*)pMemObj->Data;
 
     if (pMemObj->cbData < sizeof(DWORD) && pMemObj->cbData < 
pBmi->bmiHeader.biSize)
         goto cleanup;
@@ -335,17 +330,18 @@
 VOID NTAPI
 UserEmptyClipboardData(PWINSTATION_OBJECT pWinSta)
 {
-    unsigned i;
+    DWORD i;
     PCLIP pElement;
 
     for (i = 0; i < pWinSta->cNumClipFormats; ++i)
     {
         pElement = &pWinSta->pClipBase[i];
-               IntFreeElementData(pElement);
-    }
-
-    if(pWinSta->pClipBase)
+        IntFreeElementData(pElement);
+    }
+
+    if (pWinSta->pClipBase)
         ExFreePoolWithTag(pWinSta->pClipBase, USERTAG_CLIPBOARD);
+
     pWinSta->pClipBase = NULL;
     pWinSta->cNumClipFormats = 0;
 }
@@ -384,7 +380,7 @@
 {
     UINT Ret = 0;
     PCLIP pElement;
-    PWINSTATION_OBJECT pWinStaObj = NULL;
+    PWINSTATION_OBJECT pWinStaObj;
 
     pWinStaObj = IntGetWinStaForCbAccess();
     if (!pWinStaObj)
@@ -413,7 +409,7 @@
     }
 
 cleanup:
-    if(pWinStaObj)
+    if (pWinStaObj)
         ObDereferenceObject(pWinStaObj);
 
     return Ret;
@@ -439,11 +435,11 @@
 
     if (pWinStaObj->ptiClipLock)
     {
-        /* Clipboard is already open */
+        /* Clipboard is already opened */
         if (pWinStaObj->spwndClipOpen != pWindow)
         {
+            ERR("Access denied!\n");
             EngSetLastError(ERROR_ACCESS_DENIED);
-            ERR("Access denied!\n");
             goto cleanup;
         }
     }
@@ -476,12 +472,13 @@
 UserCloseClipboard(VOID)
 {
     BOOL bRet = FALSE;
-    PWINSTATION_OBJECT pWinStaObj = NULL;
-
-    pWinStaObj = IntGetWinStaForCbAccess();
-    if (!pWinStaObj)
-        goto cleanup;
-
+    PWINSTATION_OBJECT pWinStaObj;
+
+    pWinStaObj = IntGetWinStaForCbAccess();
+    if (!pWinStaObj)
+        goto cleanup;
+
+    /* Check if clipboard has been opened */
     if (!IntIsClipboardOpenByMe(pWinStaObj))
     {
         EngSetLastError(ERROR_CLIPBOARD_NOT_OPEN);
@@ -569,10 +566,10 @@
 
     if (pWindowRemove && pWinStaObj->spwndClipViewer)
     {
-        if(pWindowRemove == pWinStaObj->spwndClipViewer)
+        if (pWindowRemove == pWinStaObj->spwndClipViewer)
             pWinStaObj->spwndClipViewer = UserGetWindowObject(hWndNewNext);
 
-        if(pWinStaObj->spwndClipViewer)
+        if (pWinStaObj->spwndClipViewer)
             bRet = 
(BOOL)co_IntSendMessage(pWinStaObj->spwndClipViewer->head.h, WM_CHANGECBCHAIN, 
(WPARAM)hWndRemove, (LPARAM)hWndNewNext);
     }
 
@@ -588,7 +585,7 @@
 NtUserCountClipboardFormats(VOID)
 {
     DWORD cFormats = 0;
-    PWINSTATION_OBJECT pWinStaObj = NULL;
+    PWINSTATION_OBJECT pWinStaObj;
 
     UserEnterShared();
 
@@ -616,29 +613,33 @@
     if (!pWinStaObj)
         return FALSE;
 
-    if (IntIsClipboardOpenByMe(pWinStaObj))
-    {
-        UserEmptyClipboardData(pWinStaObj);
-
-        if (pWinStaObj->spwndClipOwner)
-        {
-            TRACE("Clipboard: WM_DESTROYCLIPBOARD to %p\n", 
pWinStaObj->spwndClipOwner->head.h);
-            co_IntSendMessageNoWait(pWinStaObj->spwndClipOwner->head.h, 
WM_DESTROYCLIPBOARD, 0, 0);
-        }
-
-        pWinStaObj->spwndClipOwner = pWinStaObj->spwndClipOpen;
-
-        pWinStaObj->iClipSequenceNumber++;
-
-        bRet = TRUE;
-    }
-    else
+    /* Check if clipboard has been opened */
+    if (!IntIsClipboardOpenByMe(pWinStaObj))
     {
         EngSetLastError(ERROR_CLIPBOARD_NOT_OPEN);
-        ERR("Access denied!\n");
-    }
-
-    ObDereferenceObject(pWinStaObj);
+        goto cleanup;
+    }
+
+    UserEmptyClipboardData(pWinStaObj);
+
+    if (pWinStaObj->spwndClipOwner)
+    {
+        TRACE("Clipboard: WM_DESTROYCLIPBOARD to %p\n", 
pWinStaObj->spwndClipOwner->head.h);
+        co_IntSendMessageNoWait(pWinStaObj->spwndClipOwner->head.h, 
WM_DESTROYCLIPBOARD, 0, 0);
+    }
+
+    pWinStaObj->spwndClipOwner = pWinStaObj->spwndClipOpen;
+
+    pWinStaObj->iClipSerialNumber++;
+    pWinStaObj->iClipSequenceNumber++;
+    pWinStaObj->fClipboardChanged = TRUE;
+    pWinStaObj->fInDelayedRendering = FALSE;
+
+    bRet = TRUE;
+
+cleanup:
+    if (pWinStaObj)
+        ObDereferenceObject(pWinStaObj);
 
     return bRet;
 }
@@ -730,7 +731,7 @@
     UserEnterShared();
 
     pWinStaObj = IntGetWinStaForCbAccess();
-    if(!pWinStaObj)
+    if (!pWinStaObj)
         goto cleanup;
 
     if (pWinStaObj->spwndClipViewer)
@@ -823,7 +824,7 @@
 {
     HANDLE hRet = NULL;
     PCLIP pElement;
-    PWINSTATION_OBJECT pWinStaObj = NULL;
+    PWINSTATION_OBJECT pWinStaObj;
 
     TRACE("NtUserGetClipboardData(%x, %p)\n", fmt, pgcd);
 
@@ -833,6 +834,7 @@
     if (!pWinStaObj)
         goto cleanup;
 
+    /* Check if clipboard has been opened */
     if (!IntIsClipboardOpenByMe(pWinStaObj))
     {
         EngSetLastError(ERROR_CLIPBOARD_NOT_OPEN);
@@ -853,7 +855,6 @@
 
     if (!pElement || IS_DATA_DELAYED(pElement))
         goto cleanup;
-
 
     if (IS_DATA_SYNTHESIZED(pElement))
     {
@@ -911,7 +912,7 @@
     _SEH2_END;
 
 cleanup:
-    if(pWinStaObj)
+    if (pWinStaObj)
         ObDereferenceObject(pWinStaObj);
 
     UserLeave();
@@ -925,16 +926,21 @@
 UserSetClipboardData(UINT fmt, HANDLE hData, PSETCLIPBDATA scd)
 {
     HANDLE hRet = NULL;
-    PWINSTATION_OBJECT pWinStaObj = NULL;
-
-    pWinStaObj = IntGetWinStaForCbAccess();
-    if (!pWinStaObj)
-        goto cleanup;
-
-    /* If it's delayed rendering we don't have to open clipboard */
-    if ((pWinStaObj->fInDelayedRendering &&
-        pWinStaObj->spwndClipOwner->head.pti != 
PsGetCurrentThreadWin32Thread()) ||
-        !IntIsClipboardOpenByMe(pWinStaObj))
+    PWINSTATION_OBJECT pWinStaObj;
+
+    pWinStaObj = IntGetWinStaForCbAccess();
+    if (!pWinStaObj)
+        goto cleanup;
+
+    /*
+     * Check if the clipboard is correctly opened:
+     * - in case of normal rendering, we must have opened the clipboard;
+     * - in case of delayed rendering, the clipboard must be already opened
+     *   by another application, but we need to be the clipboard owner.
+     */
+    if ((!pWinStaObj->fInDelayedRendering && 
!IntIsClipboardOpenByMe(pWinStaObj)) ||
+        (pWinStaObj->fInDelayedRendering && !(pWinStaObj->ptiClipLock &&
+         pWinStaObj->spwndClipOwner->head.pti == 
PsGetCurrentThreadWin32Thread())))
     {
         ERR("Access denied!\n");
         EngSetLastError(ERROR_CLIPBOARD_NOT_OPEN);
@@ -944,7 +950,7 @@
     if (scd->fIncSerialNumber)
         pWinStaObj->iClipSerialNumber++;
 
-    /* Is it a delayed render? */
+    /* Is it a delayed rendering? */
     if (hData)
     {
         /* Is it a bitmap? */
@@ -958,14 +964,17 @@
         IntAddFormatedData(pWinStaObj, fmt, hData, scd->fGlobalHandle, FALSE);
         TRACE("hData stored\n");
 
-        pWinStaObj->iClipSequenceNumber++;
+        /* If the serial number was increased, increase also the sequence 
number */
+        if (scd->fIncSerialNumber)
+            pWinStaObj->iClipSequenceNumber++;
+
         pWinStaObj->fClipboardChanged = TRUE;
 
         /* Note: Synthesized formats are added in NtUserCloseClipboard */
     }
     else
     {
-        /* This is a delayed render */
+        /* This is a delayed rendering */
         IntAddFormatedData(pWinStaObj, fmt, DATA_DELAYED, FALSE, FALSE);
         TRACE("SetClipboardData delayed format: %u\n", fmt);
     }
@@ -976,7 +985,7 @@
 cleanup:
     TRACE("NtUserSetClipboardData returns: %p\n", hRet);
 
-    if(pWinStaObj)
+    if (pWinStaObj)
         ObDereferenceObject(pWinStaObj);
 
     return hRet;
@@ -1016,7 +1025,7 @@
 NtUserSetClipboardViewer(HWND hWndNewViewer)
 {
     HWND hWndNext = NULL;
-    PWINSTATION_OBJECT pWinStaObj = NULL;
+    PWINSTATION_OBJECT pWinStaObj;
     PWND pWindow;
 
     UserEnterExclusive();
@@ -1041,7 +1050,7 @@
     pWinStaObj->spwndClipViewer = pWindow;
 
 cleanup:
-    if(pWinStaObj)
+    if (pWinStaObj)
         ObDereferenceObject(pWinStaObj);
 
     UserLeave();

Modified: 
branches/ros-branch-0_4_0/reactos/win32ss/user/user32/windows/clipboard.c
URL: 
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_0/reactos/win32ss/user/user32/windows/clipboard.c?rev=70370&r1=70369&r2=70370&view=diff
==============================================================================
--- branches/ros-branch-0_4_0/reactos/win32ss/user/user32/windows/clipboard.c   
[iso-8859-1] (original)
+++ branches/ros-branch-0_4_0/reactos/win32ss/user/user32/windows/clipboard.c   
[iso-8859-1] Wed Dec 16 22:05:19 2015
@@ -17,8 +17,6 @@
 
 #include <wine/debug.h>
 WINE_DEFAULT_DEBUG_CHANNEL(user32);
-
-#define QUERY_SIZE 0
 
 /* FUNCTIONS *****************************************************************/
 
@@ -263,7 +261,7 @@
             pData = pNewData;
         }
 
-        /* Save synthesized format in clibboard */
+        /* Save synthesized format in clipboard */
         if (pData)
         {
             HANDLE hMem;
@@ -296,7 +294,7 @@
     HANDLE hRet = NULL;
     SETCLIPBDATA scd = {FALSE, FALSE};
 
-    /* Check if this is delayed render */
+    /* Check if this is a delayed rendering */
     if (hMem == NULL)
         return NtUserSetClipboardData(uFormat, NULL, &scd);
 
@@ -308,7 +306,10 @@
     /* Meta files are probably checked for validity */
     else if (uFormat == CF_DSPMETAFILEPICT || uFormat == CF_METAFILEPICT ||
              uFormat == CF_DSPENHMETAFILE || uFormat == CF_ENHMETAFILE)
+    {
+        UNIMPLEMENTED;
         hRet = NULL; // not supported yet
+    }
     else
     {
         /* Some formats accept only global handles, other accept global 
handles or integer values */


Reply via email to