Author: tretiakov
Date: Thu Mar 8 16:31:33 2007
New Revision: 26029
URL:
http://svn.reactos.org/svn/reactos?rev=26029&view=rev
Log:
Merge clipboard branch to trunk
Modified:
trunk/reactos/base/applications/regedit/childwnd.c
trunk/reactos/dll/win32/shell32/shfldr_fs.c
trunk/reactos/dll/win32/shell32/shlfileop.c
trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c
trunk/reactos/dll/win32/shell32/shv_item_cmenu.c
trunk/reactos/dll/win32/user32/include/user32p.h
trunk/reactos/dll/win32/user32/windows/clipboard.c
trunk/reactos/dll/win32/user32/windows/defwnd.c
trunk/reactos/include/psdk/winuser.h
trunk/reactos/include/reactos/win32k/ntuser.h
trunk/reactos/subsystems/win32/win32k/include/clipboard.h
trunk/reactos/subsystems/win32/win32k/include/winsta.h
trunk/reactos/subsystems/win32/win32k/ntuser/clipboard.c
trunk/reactos/subsystems/win32/win32k/ntuser/misc.c
trunk/reactos/subsystems/win32/win32k/ntuser/useratom.c
trunk/reactos/subsystems/win32/win32k/ntuser/window.c
trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c
trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c
trunk/reactos/tools/nci/w32ksvc.db
Modified: trunk/reactos/base/applications/regedit/childwnd.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/regedit/…
==============================================================================
--- trunk/reactos/base/applications/regedit/childwnd.c (original)
+++ trunk/reactos/base/applications/regedit/childwnd.c Thu Mar 8 16:31:33 2007
@@ -431,8 +431,8 @@
TCHAR szBuffer[MAX_PATH];
_sntprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), _T("My
Computer\\%s\\%s"), rootName, keyPath);
- if (RegOpenKey(HKEY_CURRENT_USER,
-
_T("Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit"),
+ if (RegCreateKey(HKEY_CURRENT_USER,
+ g_szGeneralRegKey,
&hKey) == ERROR_SUCCESS)
{
RegSetValueEx(hKey, _T("LastKey"), 0, REG_SZ, (LPBYTE) szBuffer,
(DWORD) _tcslen(szBuffer) * sizeof(szBuffer[0]));
Modified: trunk/reactos/dll/win32/shell32/shfldr_fs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shfldr_f…
==============================================================================
--- trunk/reactos/dll/win32/shell32/shfldr_fs.c (original)
+++ trunk/reactos/dll/win32/shell32/shfldr_fs.c Thu Mar 8 16:31:33 2007
@@ -1,4 +1,3 @@
-
/*
* file system folder
*
@@ -54,6 +53,8 @@
#include "shfldr.h"
WINE_DEFAULT_DEBUG_CHANNEL (shell);
+
+extern BOOL fileMoving;
/***********************************************************************
* IShellFolder implementation
@@ -1232,11 +1233,14 @@
IShellFolder_QueryInterface (pSFFrom, &IID_IPersistFolder2,
(LPVOID *) & ppf2);
- if (ppf2) {
+ if (ppf2)
+ {
LPITEMIDLIST pidl;
- if (SUCCEEDED (IPersistFolder2_GetCurFolder (ppf2, &pidl))) {
- for (i = 0; i < cidl; i++) {
+ if (SUCCEEDED (IPersistFolder2_GetCurFolder (ppf2, &pidl)))
+ {
+ for (i = 0; i < cidl; i++)
+ {
SHGetPathFromIDListA (pidl, szSrcPath);
PathAddBackslashA (szSrcPath);
_ILSimpleGetText (apidl[i], szSrcPath + strlen (szSrcPath),
@@ -1246,7 +1250,43 @@
PathAddBackslashA (szDstPath);
_ILSimpleGetText (apidl[i], szDstPath + strlen (szDstPath),
MAX_PATH);
- MESSAGE ("would copy %s to %s\n", szSrcPath, szDstPath);
+ _ILSimpleGetText (apidl[i], szDstPath + strlen (szDstPath), MAX_PATH);
+ DPRINT1 ("copy %s to %s\n", szSrcPath, szDstPath);
+
+ if (fileMoving)
+ {
+ fileMoving = FALSE;
+ SHNotifyMoveFileA(szSrcPath, szDstPath);
+ }
+ else
+ {
+ SHNotifyCopyFileA(szSrcPath, szDstPath, TRUE);
+ }
+
+ /* FIXME: to work with folders we need SHFileOperation!
+ SHFILEOPSTRUCTA op;
+
+ if (fileMoving)
+ {
+ op.wFunc = FO_MOVE;
+ fileMoving = FALSE;
+ }
+ else
+ {
+ op.wFunc = FO_COPY;
+ }
+
+ op.pTo = szDstPath;
+ op.pFrom = szSrcPath;
+ op.fFlags = FOF_SIMPLEPROGRESS;
+ op.hwnd = NULL;
+ op.hNameMappings = NULL;
+ op.lpszProgressTitle = NULL;
+
+ UINT bRes = SHFileOperationA(&op);
+ DbgPrint("CopyItems SHFileOperationA 0x%08x\n", bRes);
+ */
+
}
SHFree (pidl);
}
Modified: trunk/reactos/dll/win32/shell32/shlfileop.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shlfileo…
==============================================================================
--- trunk/reactos/dll/win32/shell32/shlfileop.c (original)
+++ trunk/reactos/dll/win32/shell32/shlfileop.c Thu Mar 8 16:31:33 2007
@@ -478,6 +478,65 @@
return GetLastError();
}
+DWORD SHNotifyMoveFileA(LPCSTR src, LPCSTR dest)
+{
+ BOOL ret;
+ LPWSTR destW;
+
+ ret = MoveFileA(src, dest);
+ if (!ret)
+ {
+ DWORD dwAttr;
+
+ SHELL32_AnsiToUnicodeBuf(dest, &destW, 0);
+ dwAttr = SHFindAttrW(destW, FALSE);
+ SHELL32_FreeUnicodeBuf(destW);
+ if (INVALID_FILE_ATTRIBUTES == dwAttr)
+ {
+ /* Source file may be write protected or a system file */
+ dwAttr = GetFileAttributesA(src);
+ if (IsAttrib(dwAttr, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM))
+ if (SetFileAttributesA(src, dwAttr & ~(FILE_ATTRIBUTE_READONLY |
FILE_ATTRIBUTE_SYSTEM)))
+ ret = MoveFileA(src, dest);
+ }
+ }
+ if (ret)
+ {
+ //SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_PATHA, src, dest);
+ SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, dest, NULL);
+ SHChangeNotify(SHCNE_DELETE, SHCNF_PATHA, src, NULL);
+ return ERROR_SUCCESS;
+ }
+ return GetLastError();
+}
+
+/************************************************************************
+ * SHNotifyCopyFile [internal]
+ *
+ * Copies a file. Also triggers a change notify if one exists.
+ *
+ * PARAMS
+ * src [I] path to source file to move
+ * dest [I] path to target file to move to
+ * bFailIfExists [I] if TRUE, the target file will not be overwritten if
+ * a file with this name already exists
+ *
+ * RETURNS
+ * ERROR_SUCCESS if successful
+ */
+DWORD SHNotifyCopyFileA(LPCSTR src, LPCSTR dest, BOOL bFailIfExists)
+{
+ BOOL ret;
+
+ ret = CopyFileA(src, dest, bFailIfExists);
+ if (ret)
+ {
+ SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, dest, NULL);
+ return ERROR_SUCCESS;
+ }
+ return GetLastError();
+}
+
/*************************************************************************
* SHCreateDirectory [SHELL32.165]
*
@@ -649,6 +708,30 @@
}
return dwAttr;
}
+
+/*
+DWORD SHFindAttrA(LPSTR pName, BOOL fileOnly)
+{
+ WIN32_FIND_DATAA wfd;
+ BOOL b_FileMask = fileOnly && (NULL != StrPBrkA(pName, wWildcardChars));
+ DWORD dwAttr = INVALID_FILE_ATTRIBUTES;
+ HANDLE hFind = FindFirstFileA(pName, &wfd);
+
+ if (INVALID_HANDLE_VALUE != hFind)
+ {
+ do
+ {
+ if (b_FileMask && IsAttribDir(wfd.dwFileAttributes))
+ continue;
+ dwAttr = wfd.dwFileAttributes;
+ break;
+ }
+ while (FindNextFileA(hFind, &wfd));
+ FindClose(hFind);
+ }
+ return dwAttr;
+}
+*/
/*************************************************************************
*
Modified: trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shv_bg_c…
==============================================================================
--- trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c (original)
+++ trunk/reactos/dll/win32/shell32/shv_bg_cmenu.c Thu Mar 8 16:31:33 2007
@@ -18,6 +18,7 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
#include <string.h>
#define COBJMACROS
@@ -37,6 +38,8 @@
#include "undocshell.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
+
+extern BOOL fileMoving;
/**************************************************************************
* IContextMenu Implementation
@@ -215,6 +218,192 @@
}
}
+/***************************************************************************/
+static BOOL DoLink(LPCSTR pSrcFile, LPCSTR pDstFile)
+{
+ IShellLinkA *psl = NULL;
+ IPersistFile *pPf = NULL;
+ HRESULT hres;
+ WCHAR widelink[MAX_PATH];
+ BOOL ret = FALSE;
+
+ CoInitialize(0);
+
+ hres = CoCreateInstance( &CLSID_ShellLink,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ &IID_IShellLinkA,
+ (LPVOID )&psl);
+
+ if(SUCCEEDED(hres))
+ {
+ hres = IShellLinkA_QueryInterface(psl, &IID_IPersistFile, (LPVOID *)&pPf);
+ if(FAILED(hres))
+ {
+ ERR("failed QueryInterface for IPersistFile %08lx\n", hres);
+ goto fail;
+ }
+
+ DPRINT1("shortcut point to %s\n", pSrcFile);
+
+ hres = IShellLinkA_SetPath(psl, pSrcFile);
+
+ if(FAILED(hres))
+ {
+ ERR("failed Set{IDList|Path} %08lx\n", hres);
+ goto fail;
+ }
+
+ MultiByteToWideChar(CP_ACP, 0, pDstFile, -1, widelink, MAX_PATH);
+
+ /* create the short cut */
+ hres = IPersistFile_Save(pPf, widelink, TRUE);
+
+ if(FAILED(hres))
+ {
+ ERR("failed IPersistFile::Save %08lx\n", hres);
+ IPersistFile_Release(pPf);
+ IShellLinkA_Release(psl);
+ goto fail;
+ }
+
+ hres = IPersistFile_SaveCompleted(pPf, widelink);
+ IPersistFile_Release(pPf);
+ IShellLinkA_Release(psl);
+ DPRINT1("shortcut %s has been created, result=%08lx\n", pDstFile, hres);
+ ret = TRUE;
+ }
+ else
+ {
+ DPRINT1("CoCreateInstance failed, hres=%08lx\n", hres);
+ }
+
+ fail:
+ CoUninitialize();
+ return ret;
+}
+
+static BOOL MakeLink(IContextMenu2 *iface)
+{
+
+ BgCmImpl *This = (BgCmImpl *)iface;
+ BOOL bSuccess = FALSE;
+ IDataObject * pda;
+
+ TRACE("\n");
+
+ if(SUCCEEDED(OleGetClipboard(&pda)))
+ {
+ STGMEDIUM medium;
+ FORMATETC formatetc;
+
+ TRACE("pda=%p\n", pda);
+
+ /* Set the FORMATETC structure*/
+ InitFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
+
+ /* Get the pidls from IDataObject */
+ if(SUCCEEDED(IDataObject_GetData(pda, &formatetc, &medium)))
+ {
+ LPITEMIDLIST * apidl;
+ LPITEMIDLIST pidl;
+ IShellFolder *psfFrom = NULL, *psfDesktop;
+
+ LPIDA lpcida = GlobalLock(medium.u.hGlobal);
+ TRACE("cida=%p\n", lpcida);
+
+ apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
+
+ /* bind to the source shellfolder */
+ SHGetDesktopFolder(&psfDesktop);
+ if(psfDesktop)
+ {
+ IShellFolder_BindToObject(psfDesktop, pidl, NULL, &IID_IShellFolder,
(LPVOID*)&psfFrom);
+ IShellFolder_Release(psfDesktop);
+ }
+
+ if (psfFrom)
+ {
+ /* get source and destination shellfolder */
+ IPersistFolder2 *ppfdst = NULL;
+ IPersistFolder2 *ppfsrc = NULL;
+ IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2,
(LPVOID*)&ppfdst);
+ IShellFolder_QueryInterface(psfFrom, &IID_IPersistFolder2,
(LPVOID*)&ppfsrc);
+
+ DPRINT1("[%p,%p]\n",ppfdst,ppfsrc);
+
+ /* do the link/s */
+ /* hack to get desktop path */
+ if ( (ppfdst && ppfsrc) || (This->bDesktop && ppfsrc) )
+ {
+ int i;
+ char szSrcPath[MAX_PATH];
+ char szDstPath[MAX_PATH];
+ BOOL ret = FALSE;
+ LPITEMIDLIST pidl2;
+ char filename[MAX_PATH];
+ char linkFilename[MAX_PATH];
+ char srcFilename[MAX_PATH];
+
+ IPersistFolder2_GetCurFolder(ppfsrc, &pidl2);
+ SHGetPathFromIDListA (pidl2, szSrcPath);
+
+ if (This->bDesktop)
+ {
+ SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &pidl2);
+ SHGetPathFromIDListA (pidl2, szDstPath);
+ }
+ else
+ {
+ IPersistFolder2_GetCurFolder(ppfdst, &pidl2);
+ SHGetPathFromIDListA (pidl2, szDstPath);
+ }
+
+ for (i = 0; i < lpcida->cidl; i++)
+ {
+ _ILSimpleGetText (apidl[i], filename, MAX_PATH);
+
+ DPRINT1("filename %s\n", filename);
+
+ lstrcpyA(linkFilename, szDstPath);
+ PathAddBackslashA(linkFilename);
+ lstrcatA(linkFilename, "Shortcut to ");
+ lstrcatA(linkFilename, filename);
+ lstrcatA(linkFilename, ".lnk");
+
+ DPRINT1("linkFilename %s\n", linkFilename);
+
+ lstrcpyA(srcFilename, szSrcPath);
+ PathAddBackslashA(srcFilename);
+ lstrcatA(srcFilename, filename);
+
+ DPRINT1("srcFilename %s\n", srcFilename);
+
+ ret = DoLink(srcFilename, linkFilename);
+
+ if (ret)
+ {
+ SHChangeNotify(SHCNE_CREATE, SHCNF_PATHA, linkFilename, NULL);
+ }
+ }
+ }
+ if(ppfdst) IPersistFolder2_Release(ppfdst);
+ if(ppfsrc) IPersistFolder2_Release(ppfsrc);
+ IShellFolder_Release(psfFrom);
+ }
+
+ _ILFreeaPidl(apidl, lpcida->cidl);
+ SHFree(pidl);
+
+ /* release the medium*/
+ ReleaseStgMedium(&medium);
+ }
+ IDataObject_Release(pda);
+ }
+ return bSuccess;
+}
+
+
/**************************************************************************
* DoPaste
*/
@@ -261,16 +450,27 @@
{
/* get source and destination shellfolder */
ISFHelper *psfhlpdst, *psfhlpsrc;
- IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
(LPVOID*)&psfhlpdst);
+
+ if (This->bDesktop)
+ {
+ /* unimplemented
+ SHGetDesktopFolder(&psfDesktop);
+ IFSFolder_Constructor(psfDesktop, &IID_ISFHelper, (LPVOID*)&psfhlpdst);
+ IShellFolder_QueryInterface(psfhlpdst, &IID_ISFHelper,
(LPVOID*)&psfhlpdst);
+ */
+ IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
(LPVOID*)&psfhlpdst);
+ }
+ else
+ {
+ IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
(LPVOID*)&psfhlpdst);
+ }
+
IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper,
(LPVOID*)&psfhlpsrc);
/* do the copy/move */
if (psfhlpdst && psfhlpsrc)
{
ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl,
(LPCITEMIDLIST*)apidl);
- /* FIXME handle move
- ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl);
- */
}
if(psfhlpdst) ISFHelper_Release(psfhlpdst);
if(psfhlpsrc) ISFHelper_Release(psfhlpsrc);
@@ -285,30 +485,7 @@
}
IDataObject_Release(pda);
}
-#if 0
- HGLOBAL hMem;
-
- OpenClipboard(NULL);
- hMem = GetClipboardData(CF_HDROP);
-
- if(hMem)
- {
- char * pDropFiles = (char *)GlobalLock(hMem);
- if(pDropFiles)
- {
- int len, offset = sizeof(DROPFILESTRUCT);
-
- while( pDropFiles[offset] != 0)
- {
- len = strlen(pDropFiles + offset);
- TRACE("%s\n", pDropFiles + offset);
- offset += len+1;
- }
- }
- GlobalUnlock(hMem);
- }
- CloseClipboard();
-#endif
+
return bSuccess;
}
@@ -371,6 +548,10 @@
case FCIDM_SHVIEW_INSERT:
DoPaste(iface);
+ break;
+
+ case FCIDM_SHVIEW_INSERTLINK:
+ MakeLink(iface);
break;
case FCIDM_SHVIEW_PROPERTIES:
Modified: trunk/reactos/dll/win32/shell32/shv_item_cmenu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shv_item…
==============================================================================
--- trunk/reactos/dll/win32/shell32/shv_item_cmenu.c (original)
+++ trunk/reactos/dll/win32/shell32/shv_item_cmenu.c Thu Mar 8 16:31:33 2007
@@ -39,6 +39,9 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
+/* ugly hack for cut&psate files */
+BOOL fileMoving = FALSE;
+
/**************************************************************************
* IContextMenu Implementation
*/
@@ -372,6 +375,8 @@
LPSHELLBROWSER lpSB;
LPSHELLVIEW lpSV;
LPDATAOBJECT lpDo;
+
+ fileMoving = bCut;
TRACE("(%p)->(wnd=%p,bCut=0x%08x)\n",This, hwnd, bCut);
Modified: trunk/reactos/dll/win32/user32/include/user32p.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/include/u…
==============================================================================
--- trunk/reactos/dll/win32/user32/include/user32p.h (original)
+++ trunk/reactos/dll/win32/user32/include/user32p.h Thu Mar 8 16:31:33 2007
@@ -76,8 +76,10 @@
#define NtUserSetCaretBlinkTime(uMSeconds) \
(BOOL)NtUserCallOneParam((DWORD)uMSeconds, ONEPARAM_ROUTINE_SETCARETBLINKTIME)
+/*
#define NtUserEnumClipboardFormats(format) \
(UINT)NtUserCallOneParam(format, ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS)
+*/
#define NtUserWindowFromDC(hDC) \
(HWND)NtUserCallOneParam((DWORD)hDC, ONEPARAM_ROUTINE_WINDOWFROMDC)
Modified: trunk/reactos/dll/win32/user32/windows/clipboard.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/c…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/clipboard.c (original)
+++ trunk/reactos/dll/win32/user32/windows/clipboard.c Thu Mar 8 16:31:33 2007
@@ -1,37 +1,25 @@
-/*
- * ReactOS kernel
- * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
- *
- * This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
/* $Id$
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/clipboard.c
* PURPOSE: Input
* PROGRAMMER: Casper S. Hornstrup (chorns(a)users.sourceforge.net)
+ * Pablo Borobia <pborobia(a)gmail.com>
* UPDATE HISTORY:
* 09-05-2001 CSH Created
+ *
*/
/* INCLUDES ******************************************************************/
#include <user32.h>
+#define NDEBUG
+
#include <wine/debug.h>
+#define QUERY_SIZE 0
+
/* FUNCTIONS *****************************************************************/
/*
@@ -40,7 +28,8 @@
BOOL STDCALL
OpenClipboard(HWND hWndNewOwner)
{
- return NtUserOpenClipboard(hWndNewOwner, 0);
+ BOOL ret = NtUserOpenClipboard(hWndNewOwner, 0);
+ return ret;
}
/*
@@ -49,7 +38,9 @@
BOOL STDCALL
CloseClipboard(VOID)
{
- return NtUserCloseClipboard();
+ BOOL ret;
+ ret = NtUserCloseClipboard();
+ return ret;
}
/*
@@ -58,7 +49,8 @@
INT STDCALL
CountClipboardFormats(VOID)
{
- return NtUserCountClipboardFormats();
+ INT ret = NtUserCountClipboardFormats();
+ return ret;
}
/*
@@ -67,7 +59,7 @@
BOOL STDCALL
EmptyClipboard(VOID)
{
- return NtUserEmptyClipboard();
+ return NtUserEmptyClipboard();
}
/*
@@ -76,7 +68,8 @@
UINT STDCALL
EnumClipboardFormats(UINT format)
{
- return NtUserEnumClipboardFormats(format);
+ UINT ret = NtUserEnumClipboardFormats(format);
+ return ret;
}
/*
@@ -85,7 +78,31 @@
HANDLE STDCALL
GetClipboardData(UINT uFormat)
{
- return NtUserGetClipboardData(uFormat, 0);
+ HGLOBAL hGlobal = NULL;
+ PVOID pGlobal = NULL;
+ DWORD size = 0;
+
+ /* dealing with bitmap object */
+ if (uFormat != CF_BITMAP)
+ {
+ size = (DWORD)NtUserGetClipboardData(uFormat, QUERY_SIZE);
+
+ if (size)
+ {
+ hGlobal = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, size);
+ pGlobal = GlobalLock(hGlobal);
+
+ size = (DWORD)NtUserGetClipboardData(uFormat, (DWORD)pGlobal);
+
+ GlobalUnlock(hGlobal);
+ }
+ }
+ else
+ {
+ hGlobal = NtUserGetClipboardData(CF_BITMAP, !QUERY_SIZE);
+ }
+
+ return hGlobal;
}
/*
@@ -94,28 +111,32 @@
INT STDCALL
GetClipboardFormatNameA(UINT format, LPSTR lpszFormatName, int cchMaxCount)
{
- LPWSTR lpBuffer;
- UNICODE_STRING FormatName;
- INT Length;
-
- lpBuffer = HEAP_alloc(cchMaxCount * sizeof(WCHAR));
- if (!lpBuffer)
- {
- SetLastError(ERROR_OUTOFMEMORY);
- return 0;
- }
+ LPWSTR lpBuffer;
+ UNICODE_STRING FormatName;
+ INT Length;
+ ANSI_STRING ClassName;
+
+ ClassName.MaximumLength = cchMaxCount;
+ ClassName.Buffer = lpszFormatName;
+
+ lpBuffer = HEAP_alloc(cchMaxCount * sizeof(WCHAR));
+
+ if (!lpBuffer)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return 0;
+ }
FormatName.Length = 0;
FormatName.MaximumLength = cchMaxCount * sizeof(WCHAR);
FormatName.Buffer = lpBuffer;
+ /* we need a UNICODE string */
Length = NtUserGetClipboardFormatName(format, &FormatName, cchMaxCount);
- DPRINT("GetClipboardFormatNameA(%x): %S\n", format, lpBuffer);
- HEAP_strcpyWtoA(lpszFormatName, lpBuffer, Length);
- HEAP_free(lpBuffer);
- DPRINT("GetClipboardFormatNameA(%x): returning %s\n", format,
lpszFormatName);
-
- return Length;
+
+ HEAP_strcpyWtoA(lpszFormatName, FormatName.Buffer, Length);
+
+ return strlen(lpszFormatName);
}
/*
@@ -124,15 +145,15 @@
INT STDCALL
GetClipboardFormatNameW(UINT format, LPWSTR lpszFormatName, INT cchMaxCount)
{
- UNICODE_STRING FormatName;
- ULONG Ret;
-
- FormatName.Length = 0;
- FormatName.MaximumLength = cchMaxCount * sizeof(WCHAR);
- FormatName.Buffer = (PWSTR)lpszFormatName;
- Ret = NtUserGetClipboardFormatName(format, &FormatName, cchMaxCount);
- DPRINT("GetClipboardFormatNameW(%x): returning %S\n", format,
lpszFormatName);
- return Ret;
+ UNICODE_STRING FormatName;
+ ULONG Ret;
+
+ FormatName.Length = 0;
+ FormatName.MaximumLength = cchMaxCount * sizeof(WCHAR);
+ FormatName.Buffer = (PWSTR)lpszFormatName;
+ Ret = NtUserGetClipboardFormatName(format, &FormatName, cchMaxCount);
+ return Ret;
+
}
/*
@@ -177,7 +198,8 @@
INT STDCALL
GetPriorityClipboardFormat(UINT *paFormatPriorityList, INT cFormats)
{
- return NtUserGetPriorityClipboardFormat(paFormatPriorityList, cFormats);
+ INT ret = NtUserGetPriorityClipboardFormat(paFormatPriorityList, cFormats);
+ return ret;
}
/*
@@ -186,18 +208,41 @@
BOOL STDCALL
IsClipboardFormatAvailable(UINT format)
{
- return NtUserIsClipboardFormatAvailable(format);
-}
-
-/*
- * @implemented
- */
+ BOOL ret = NtUserIsClipboardFormatAvailable(format);
+ return ret;
+}
+
+/*
+ * @implemented
+ */
+
UINT STDCALL
RegisterClipboardFormatA(LPCSTR lpszFormat)
{
- ULONG Ret = RegisterWindowMessageA(lpszFormat);
- DPRINT("RegisterClipboardFormatA(%s) - %x\n", lpszFormat, Ret);
- return Ret;
+ UINT ret = 0;
+ UNICODE_STRING usFormat = {0};
+
+ if (lpszFormat == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ /* check for "" */
+ if (*lpszFormat == 0) //NULL
+ {
+ SetLastError(ERROR_INVALID_NAME);
+ return 0;
+ }
+
+ ret = RtlCreateUnicodeStringFromAsciiz(&usFormat, lpszFormat);
+ if (ret)
+ {
+ ret = NtUserRegisterClipboardFormat(&usFormat); //(LPCWSTR)
+ RtlFreeUnicodeString(&usFormat);
+ }
+
+ return ret;
}
/*
@@ -206,9 +251,48 @@
UINT STDCALL
RegisterClipboardFormatW(LPCWSTR lpszFormat)
{
- ULONG Ret = RegisterWindowMessageW(lpszFormat);
- DPRINT("RegisterClipboardFormatW(%S) - %x\n", lpszFormat, Ret);
- return Ret;
+ UINT ret = 0;
+ UNICODE_STRING usFormat = {0};
+
+ if (lpszFormat == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ /* check for "" */
+ if (*lpszFormat == 0) //NULL
+ {
+ SetLastError(ERROR_INVALID_NAME);
+ return 0;
+ }
+
+ RtlInitUnicodeString(&usFormat, lpszFormat);
+ ret = NtUserRegisterClipboardFormat(&usFormat);
+ RtlFreeUnicodeString(&usFormat);
+
+ return ret;
+}
+
+HGLOBAL renderLocale (DWORD Locale)
+{
+ DWORD* pLocale;
+ HGLOBAL hGlobal;
+
+ hGlobal = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, sizeof(DWORD));
+
+ if(!hGlobal)
+ {
+ return hGlobal;
+ }
+
+ pLocale = (DWORD*)GlobalLock(hGlobal);
+
+ *pLocale = Locale;
+
+ GlobalUnlock(hGlobal);
+
+ return hGlobal;
}
/*
@@ -217,7 +301,54 @@
HANDLE STDCALL
SetClipboardData(UINT uFormat, HANDLE hMem)
{
- return NtUserSetClipboardData(uFormat, hMem, 0);
+ DWORD size;
+ LPVOID pMem;
+ HANDLE ret = NULL;
+
+ if (hMem == NULL)
+ {
+ return NtUserSetClipboardData(uFormat, 0, 0);
+ }
+
+ if (uFormat == CF_BITMAP)
+ {
+ /* GlobalLock should return 0 for GDI handles
+ pMem = GlobalLock(hMem);
+ if (pMem)
+ {
+ // not a GDI handle
+ GlobalUnlock(hMem);
+ return ret;
+ }
+ else
+ {
+ */
+ /* check if this GDI handle is a HBITMAP */
+ /* GetObject for HBITMAP not implemented in ReactOS */
+ //if (GetObject(hMem, 0, NULL) == sifeof(BITMAP))
+ //{
+ return NtUserSetClipboardData(CF_BITMAP, hMem, 0);
+ //}
+ /*}*/
+ }
+
+ size = GlobalSize(hMem);
+ pMem = GlobalLock(hMem);
+
+ if ((pMem) && (size))
+ {
+ size = GlobalSize(hMem);
+ ret = NtUserSetClipboardData(uFormat, pMem, size);
+ //should i unlock hMem?
+ GlobalUnlock(hMem);
+ }
+ else
+ {
+ DPRINT1("SetClipboardData failed\n");
+ }
+
+ return ret;
+
}
/*
@@ -237,3 +368,35 @@
{
return NtUserChangeClipboardChain(hWndRemove, hWndNewNext);
}
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+AddClipboardFormatListener(HWND hwnd)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+RemoveClipboardFormatListener(HWND hwnd)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+GetUpdatedClipboardFormats(
+ PUINT lpuiFormats,
+ UINT cFormats,
+ PUINT pcFormatsOut)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
Modified: trunk/reactos/dll/win32/user32/windows/defwnd.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/d…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/defwnd.c (original)
+++ trunk/reactos/dll/win32/user32/windows/defwnd.c Thu Mar 8 16:31:33 2007
@@ -984,7 +984,31 @@
VOID FASTCALL
DefWndScreenshot(HWND hWnd)
{
-
+ RECT rect;
+
+ OpenClipboard(hWnd);
+ EmptyClipboard();
+
+ HDC hdc = GetWindowDC(hWnd);
+ GetWindowRect(hWnd, &rect);
+ INT w = rect.right - rect.left;
+ INT h = rect.bottom - rect.top;
+
+ HBITMAP hbitmap = CreateCompatibleBitmap(hdc, w, h);
+ HDC hdc2 = CreateCompatibleDC(hdc);
+ SelectObject(hdc2, hbitmap);
+
+ BitBlt(hdc2, 0, 0, w, h,
+ hdc, 0, 0,
+ SRCCOPY);
+
+ SetClipboardData(CF_BITMAP, hbitmap);
+
+ ReleaseDC(hWnd, hdc);
+ ReleaseDC(hWnd, hdc2);
+
+ CloseClipboard();
+
}
@@ -1349,7 +1373,12 @@
}
else if (wParam == VK_SNAPSHOT)
{
- DefWndScreenshot(hWnd);
+ HWND hwnd = hWnd;
+ while (GetParent(hwnd) != NULL)
+ {
+ hwnd = GetParent(hwnd);
+ }
+ DefWndScreenshot(hwnd);
}
}
else if( wParam == VK_F10 )
Modified: trunk/reactos/include/psdk/winuser.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/winuser.h?rev…
==============================================================================
--- trunk/reactos/include/psdk/winuser.h (original)
+++ trunk/reactos/include/psdk/winuser.h Thu Mar 8 16:31:33 2007
@@ -54,6 +54,8 @@
#define HCBT_KEYSKIPPED 7
#define HCBT_SYSCOMMAND 8
#define HCBT_SETFOCUS 9
+
+/* Predefined Clipboard Formats */
#define CF_TEXT 1
#define CF_BITMAP 2
#define CF_METAFILEPICT 3
@@ -68,9 +70,24 @@
#define CF_WAVE 12
#define CF_UNICODETEXT 13
#define CF_ENHMETAFILE 14
-#define CF_HDROP 15
-#define CF_LOCALE 16
-#define CF_MAX 17
+
+#if(WINVER >= 0x0400)
+#define CF_HDROP 15
+#define CF_LOCALE 16
+#endif
+
+#if(WINVER >= 0x0500)
+#define CF_DIBV5 17
+#endif
+
+#if(WINVER >= 0x0500)
+#define CF_MAX 18
+#elif(WINVER >= 0x0400)
+#define CF_MAX 17
+#else
+#define CF_MAX 15
+#endif
+
#define CF_OWNERDISPLAY 128
#define CF_DSPTEXT 129
#define CF_DSPBITMAP 130
@@ -80,6 +97,7 @@
#define CF_PRIVATELAST 767
#define CF_GDIOBJFIRST 768
#define CF_GDIOBJLAST 1023
+
#define HKL_NEXT 1
#define HKL_PREV 0
#define KLF_ACTIVATE 1
Modified: trunk/reactos/include/reactos/win32k/ntuser.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntu…
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntuser.h (original)
+++ trunk/reactos/include/reactos/win32k/ntuser.h Thu Mar 8 16:31:33 2007
@@ -122,7 +122,12 @@
HMENU hMenu,
UINT uIDEnableItem,
UINT uEnable);
-
+
+UINT
+NTAPI
+NtUserEnumClipboardFormats(
+ UINT format);
+
DWORD
NTAPI
NtUserInsertMenuItem(
@@ -1038,6 +1043,11 @@
NtUserGetKeyState(
DWORD Unknown0);
+BOOL
+NTAPI
+NtUserGetLastInputInfo(
+ PLASTINPUTINFO plii);
+
DWORD
NTAPI
NtUserGetListBoxInfo(
@@ -1439,6 +1449,11 @@
WNDPROC wpExtra,
DWORD Flags,
HMENU hMenu);
+
+UINT
+NTAPI
+NtUserRegisterClipboardFormat(
+ PUNICODE_STRING format);
BOOL
NTAPI
Modified: trunk/reactos/subsystems/win32/win32k/include/clipboard.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/clipboard.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/clipboard.h Thu Mar 8 16:31:33 2007
@@ -1,7 +1,48 @@
#ifndef _WIN32K_CLIPBOARD_H
#define _WIN32K_CLIPBOARD_H
+#include "window.h"
+
+VOID FASTCALL IntIncrementSecuenceNumber(VOID);
+
+typedef struct _ClipboardChainElement
+{
+ PWINDOW_OBJECT window;
+ struct _ClipboardChainElement *next;
+} CLIPBOARDCHAINELEMENT, *PCLIPBOARDCHAINELEMENT;
+
+typedef struct _ClipboardElement
+{
+ UINT format;
+ HANDLE hData;
+ DWORD size; // data may be delayed o synth render
+ struct _ClipboardElement *next;
+} CLIPBOARDELEMENT, *PCLIPBOARDELEMENT;
+
+typedef struct _CLIPBOARDSYSTEM
+{
+ PW32THREAD ClipboardThread;
+ PW32THREAD ClipboardOwnerThread;
+ PWINDOW_OBJECT ClipboardWindow;
+ PWINDOW_OBJECT ClipboardViewerWindow;
+ PWINDOW_OBJECT ClipboardOwnerWindow;
+ BOOL sendDrawClipboardMsg;
+ BOOL recentlySetClipboard;
+ BOOL delayedRender;
+ UINT lastEnumClipboardFormats;
+ DWORD ClipboardSequenceNumber;
+
+ PCLIPBOARDCHAINELEMENT WindowsChain;
+ PCLIPBOARDELEMENT ClipboardData;
+
+ PCHAR synthesizedData;
+ DWORD synthesizedDataSize;
+
+} CLIPBOARDSYSTEM, *PCLIPBOARDSYSTEM;
+
+/*
UINT FASTCALL
IntEnumClipboardFormats(UINT format);
+*/
#endif /* _WIN32K_CLIPBOARD_H */
Modified: trunk/reactos/subsystems/win32/win32k/include/winsta.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/winsta.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/winsta.h Thu Mar 8 16:31:33 2007
@@ -2,6 +2,7 @@
#define _WIN32K_WINSTA_H
#include "msgqueue.h"
+#include "clipboard.h"
#define WINSTA_ROOT_NAME L"\\Windows\\WindowStations"
#define WINSTA_ROOT_NAME_LENGTH 23
@@ -45,7 +46,10 @@
ULONG Flags;
struct _DESKTOP_OBJECT* ActiveDesktop;
- /* FIXME: Clipboard */
+
+ PCLIPBOARDSYSTEM Clipboard;
+ DWORD ClipboardSequenceNumber;
+
} WINSTATION_OBJECT, *PWINSTATION_OBJECT;
extern WINSTATION_OBJECT *InputWindowStation;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/clipboard.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/clipboard.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/clipboard.c Thu Mar 8 16:31:33 2007
@@ -1,27 +1,10 @@
-/*
- * ReactOS W32 Subsystem
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
- *
- * This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Clipboard routines
* FILE: subsys/win32k/ntuser/clipboard.c
* PROGRAMER: Filip Navara <xnavara(a)volny.cz>
+ * Pablo Borobia <pborobia(a)gmail.com>
*/
#include <w32k.h>
@@ -29,290 +12,1234 @@
#define NDEBUG
#include <debug.h>
-#define CHECK_LOCK \
- if (ClipboardThread && ClipboardThread !=
PsGetCurrentThreadWin32Thread()) \
- { \
- SetLastWin32Error(ERROR_LOCKED); \
- return FALSE; \
- }
-
-PW32THREAD ClipboardThread;
-HWND ClipboardWindow;
-HWND tempClipboardWindow;
-HANDLE hCBData;
-UINT uCBFormat;
-
-ULONG FASTCALL
-IntGetClipboardFormatName(UINT format, PUNICODE_STRING FormatName)
-{
-
- return IntGetAtomName((RTL_ATOM)format, FormatName->Buffer,
- FormatName->MaximumLength);
-}
-
-UINT FASTCALL
-IntEnumClipboardFormats(UINT format)
-{
-
- CHECK_LOCK
-
- if (!hCBData)
- return FALSE;
- //UNIMPLEMENTED;
- return 1;
+#define DATA_DELAYED_RENDER 0
+#define DATA_SYNTHESIZED_RENDER -1
+
+#define USE_WINSTA \
+ PWINSTATION_OBJECT WinStaObj; \
+ WinStaObj = PsGetCurrentThreadWin32Thread()->Desktop->WindowStation;
+
+#define WINSTA_ClipboardThread WinStaObj->Clipboard->ClipboardThread
+#define WINSTA_ClipboardOwnerThread WinStaObj->Clipboard->ClipboardOwnerThread
+#define WINSTA_ClipboardWindow WinStaObj->Clipboard->ClipboardWindow
+#define WINSTA_ClipboardViewerWindow WinStaObj->Clipboard->ClipboardViewerWindow
+#define WINSTA_ClipboardOwnerWindow WinStaObj->Clipboard->ClipboardOwnerWindow
+#define WINSTA_sendDrawClipboardMsg WinStaObj->Clipboard->sendDrawClipboardMsg
+#define WINSTA_recentlySetClipboard WinStaObj->Clipboard->recentlySetClipboard
+#define WINSTA_delayedRender WinStaObj->Clipboard->delayedRender
+#define WINSTA_lastEnumClipboardFormats
WinStaObj->Clipboard->lastEnumClipboardFormats
+#define WINSTA_ClipboardSequenceNumber
WinStaObj->Clipboard->ClipboardSequenceNumber
+#define WINSTA_WindowsChain WinStaObj->Clipboard->WindowsChain
+#define WINSTA_ClipboardData WinStaObj->Clipboard->ClipboardData
+#define WINSTA_synthesizedData WinStaObj->Clipboard->synthesizedData
+#define WINSTA_synthesizedDataSize WinStaObj->Clipboard->synthesizedDataSize
+
+PW32THREAD ClipboardThread;
+PW32THREAD ClipboardOwnerThread;
+PWINDOW_OBJECT ClipboardWindow;
+PWINDOW_OBJECT ClipboardViewerWindow;
+PWINDOW_OBJECT ClipboardOwnerWindow;
+BOOL sendDrawClipboardMsg;
+BOOL recentlySetClipboard;
+BOOL delayedRender;
+UINT lastEnumClipboardFormats;
+DWORD ClipboardSequenceNumber = 0;
+
+PCLIPBOARDCHAINELEMENT WindowsChain = NULL;
+PCLIPBOARDELEMENT ClipboardData = NULL;
+
+PCHAR synthesizedData;
+DWORD synthesizedDataSize;
+
+
+/*==============================================================*/
+
+/* return the pointer to the prev window of the finded window,
+ if NULL does not exists in the chain */
+PCLIPBOARDCHAINELEMENT FASTCALL
+IntIsWindowInChain(PWINDOW_OBJECT window)
+{
+ PCLIPBOARDCHAINELEMENT wce = WindowsChain;
+
+ while (wce)
+ {
+ if (wce->window == window)
+ {
+ break;
+ }
+ wce = wce->next;
+ }
+
+ return wce;
+}
+
+VOID FASTCALL printChain()
+{
+ /*test*/
+ PCLIPBOARDCHAINELEMENT wce2 = WindowsChain;
+ while (wce2)
+ {
+ DPRINT1("chain: %p\n", wce2->window->hSelf);
+ wce2 = wce2->next;
+ }
+}
+
+/* the new window always have to be the first in the chain */
+PCLIPBOARDCHAINELEMENT FASTCALL
+IntAddWindowToChain(PWINDOW_OBJECT window)
+{
+ PCLIPBOARDCHAINELEMENT wce = NULL;
+
+ if (!IntIsWindowInChain(window))
+ {
+ wce = WindowsChain;
+
+ wce = ExAllocatePool(PagedPool, sizeof(CLIPBOARDCHAINELEMENT));
+ if (wce == NULL)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ goto exit_addChain;
+ }
+
+ wce->window = window;
+ wce->next = WindowsChain;
+
+ WindowsChain = wce;
+
+ //printChain();
+ }
+exit_addChain:
+
+ /* return the next window to beremoved later */
+ return wce;
+}
+
+PCLIPBOARDCHAINELEMENT FASTCALL
+IntRemoveWindowFromChain(PWINDOW_OBJECT window)
+{
+ PCLIPBOARDCHAINELEMENT wce = WindowsChain;
+ PCLIPBOARDCHAINELEMENT *link = &WindowsChain;
+
+ if (IntIsWindowInChain(window))
+ {
+ while (wce != NULL)
+ {
+ if (wce->window == window)
+ {
+ *link = wce->next;
+ break;
+ }
+
+ link = &wce->next;
+ wce = wce->next;
+ }
+
+ //printChain();
+
+ return wce;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+
+/*==============================================================*/
+/* if format exists, returns a non zero value (pointing to format object) */
+PCLIPBOARDELEMENT FASTCALL
+intIsFormatAvailable(format)
+{
+ PCLIPBOARDELEMENT ret = NULL;
+ PCLIPBOARDELEMENT ce = ClipboardData;
+
+ while(ce)
+ {
+ if (ce->format == format)
+ {
+ ret = ce;
+ break;
+ }
+ ce = ce->next;
+ }
+ return ret;
+}
+
+/* counts how many distinct format were are in the clipboard */
+DWORD FASTCALL
+IntCountClipboardFormats()
+{
+ DWORD ret = 0;
+ PCLIPBOARDELEMENT ce = ClipboardData;
+
+ while(ce)
+ {
+ ret++;
+ ce = ce->next;
+ }
+ return ret;
+}
+
+/* adds a new format and data to the clipboard */
+PCLIPBOARDELEMENT FASTCALL
+intAddFormatedData(UINT format, HANDLE hData, DWORD size)
+{
+ PCLIPBOARDELEMENT ce = NULL;
+
+ ce = ExAllocatePool(PagedPool, sizeof(CLIPBOARDELEMENT));
+ if (ce == NULL)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ }
+ else
+ {
+ ce->format = format;
+ ce->size = size;
+ ce->hData = hData;
+ ce->next = ClipboardData;
+
+ ClipboardData = ce;
+
+ IntIncrementSecuenceNumber();
+ }
+
+ return ce;
+}
+
+/* removes a format and its data from the clipboard */
+BOOL FASTCALL
+intRemoveFormatedData(UINT format)
+{
+ BOOL ret = FALSE;
+ PCLIPBOARDELEMENT ce = ClipboardData;
+ PCLIPBOARDELEMENT *link = &ClipboardData;
+
+ if (intIsFormatAvailable(format))
+ {
+ while (ce != NULL)
+ {
+ if (ce->format == format)
+ {
+ *link = ce->next;
+ break;
+ }
+
+ link = &ce->next;
+ ce = ce->next;
+ }
+
+ if (ce->hData)
+ {
+ ExFreePool(ce->hData);
+ }
+ ExFreePool(ce);
+ ret = TRUE;
+ }
+
+ return ret;
+}
+
+VOID FASTCALL
+IntEmptyClipboardData()
+{
+ PCLIPBOARDELEMENT ce = ClipboardData;
+ PCLIPBOARDELEMENT tmp;
+
+ while(ce)
+ {
+ tmp = ce->next;
+ ExFreePool(ce->hData);
+ ExFreePool(ce);
+ ce = tmp;
+ }
+
+ ClipboardData = NULL;
+}
+
+/*==============================================================*/
+
+HANDLE FASTCALL
+renderBITMAPfromDIB(LPBYTE hDIB)
+{
+ HDC hdc;
+ HBITMAP hbitmap;
+ unsigned int offset;
+ BITMAPINFOHEADER *ih;
+
+ //hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE);
+ hdc = UserGetDCEx(ClipboardWindow, NULL, DCX_USESTYLE);
+
+ ih = (BITMAPINFOHEADER *)hDIB;
+
+ offset = sizeof(BITMAPINFOHEADER) + ((ih->biBitCount <= 8) ? (sizeof(RGBQUAD) *
(1 << ih->biBitCount)) : 0);
+
+ hbitmap = NtGdiCreateDIBitmap(hdc, ih, CBM_INIT, (LPBYTE)ih + offset,
(LPBITMAPINFO)ih, DIB_RGB_COLORS);
+
+ //UserReleaseDC(NULL, hdc, FALSE);
+ UserReleaseDC(ClipboardWindow, hdc, FALSE);
+
+ return hbitmap;
+}
+
+BOOL FASTCALL
+canSinthesize(UINT format)
+{
+ BOOL ret = FALSE;
+
+ switch(format)
+ {
+ case CF_BITMAP:
+ case CF_METAFILEPICT:
+ ret = TRUE;
+ }
+
+ return ret;
+}
+
+/* returns the size of the sinthesized data */
+DWORD FASTCALL
+synthesizeData(UINT format)
+{
+ DWORD ret = 0;
+
+ synthesizedData = NULL;
+ synthesizedDataSize = 0;
+
+ if (!canSinthesize(format))
+ {
+ return 0;
+ }
+
+ switch (format)
+ {
+ case CF_BITMAP:
+ {
+ break;
+ }
+
+ case CF_METAFILEPICT:
+ {
+ break;
+ }
+ }
+
+ ret = 1;
+
+ return ret;
+}
+
+VOID FASTCALL
+freeSynthesizedData()
+{
+ ExFreePool(synthesizedData);
+}
+
+/*==============================================================*/
+
+BOOL FASTCALL
+intIsClipboardOpenByMe()
+{
+ /* check if we open the clipboard */
+ if (ClipboardThread && ClipboardThread == PsGetCurrentThreadWin32Thread())
+ {
+ /* yes, we got a thread and its the same that opens the clipboard */
+ return TRUE;
+
+ }
+ /* will fail if not thread (closed) or not open by me*/
+ return FALSE;
+}
+
+/* IntClipboardFreeWindow it's called when a window was destroyed */
+VOID FASTCALL
+IntClipboardFreeWindow(PWINDOW_OBJECT window)
+{
+ /* called from co_UserFreeWindow in window.c */
+ /* check if clipboard is not locked by this window, if yes, unlock it */
+ if (ClipboardThread == PsGetCurrentThreadWin32Thread())
+ {
+ /* the window that opens the clipboard was destroyed */
+ ClipboardThread = NULL;
+ ClipboardWindow = NULL;
+ //TODO: free clipboard
+ }
+ if (window == ClipboardOwnerWindow)
+ {
+ /* the owner window was destroyed */
+ ClipboardOwnerWindow = NULL;
+ ClipboardOwnerThread = NULL;
+ }
+ /* remove window from window chain */
+ if (IntIsWindowInChain(window))
+ {
+ PCLIPBOARDCHAINELEMENT w = IntRemoveWindowFromChain(window);
+ if (w)
+ {
+ ExFreePool(w);
+ }
+ }
}
BOOL STDCALL
NtUserOpenClipboard(HWND hWnd, DWORD Unknown1)
{
- CHECK_LOCK
-
- tempClipboardWindow = hWnd;
- ClipboardThread = PsGetCurrentThreadWin32Thread();
- return TRUE;
+
+ PWINDOW_OBJECT Window;
+ BOOL ret = FALSE;
+
+ UserEnterExclusive();
+
+ sendDrawClipboardMsg = FALSE;
+ recentlySetClipboard = FALSE;
+
+ if (ClipboardThread)
+ {
+ /* clipboard is already open */
+ if (ClipboardThread == PsGetCurrentThreadWin32Thread())
+ {
+ if (ClipboardOwnerWindow)
+ {
+ if (ClipboardOwnerWindow->hSelf == hWnd)
+ {
+ ret = TRUE;
+ }
+ }
+ else
+ {
+ if (hWnd == NULL)
+ {
+ ret = TRUE;
+ }
+ }
+ }
+ }
+ else
+ {
+
+ if (hWnd != NULL)
+ {
+ Window = UserGetWindowObject(hWnd);
+
+ if (Window != NULL)
+ {
+ ClipboardWindow = Window;
+ ClipboardThread = PsGetCurrentThreadWin32Thread();
+ ret = TRUE;
+ }
+ else
+ {
+ ClipboardWindow = NULL;
+ ClipboardThread = NULL;
+ ClipboardOwnerWindow = NULL;
+ ClipboardOwnerThread = NULL;
+ }
+ }
+ else
+ {
+ ClipboardWindow = NULL;
+ ClipboardThread = PsGetCurrentThreadWin32Thread();
+ ret = TRUE;
+ }
+ }
+
+ UserLeave();
+
+ return ret;
}
BOOL STDCALL
NtUserCloseClipboard(VOID)
{
- CHECK_LOCK
-
- ClipboardWindow = 0;
- ClipboardThread = NULL;
- return TRUE;
-}
-
-/*
- * @unimplemented
- */
+ BOOL ret = FALSE;
+
+ UserEnterExclusive();
+
+ if (intIsClipboardOpenByMe())
+ {
+ ClipboardWindow = NULL;
+ ClipboardThread = NULL;
+ ret = TRUE;
+ }
+ else
+ {
+ SetLastWin32Error(ERROR_CLIPBOARD_NOT_OPEN);
+ }
+
+ recentlySetClipboard = FALSE;
+
+ UserLeave();
+
+ if (sendDrawClipboardMsg && WindowsChain)
+ {
+ /* only send message to the first window in the chain, then they'll do the
chain */
+ /* commented because it makes a crash in co_MsqSendMessage
+ ASSERT(WindowsChain->window);
+ ASSERT(WindowsChain->window->hSelf);
+ DPRINT1("Clipboard: sending WM_DRAWCLIPBOARD to %p\n",
WindowsChain->window->hSelf);
+ co_IntSendMessage(WindowsChain->window->hSelf, WM_DRAWCLIPBOARD, 0, 0);
+ */
+ }
+
+ return ret;
+}
+
HWND STDCALL
NtUserGetOpenClipboardWindow(VOID)
{
- /*
- UNIMPLEMENTED
- return 0;
- */
- return ClipboardWindow;
+ HWND ret = NULL;
+
+ UserEnterShared();
+
+ if (ClipboardWindow)
+ {
+ ret = ClipboardWindow->hSelf;
+ }
+
+ UserLeave();
+
+ return ret;
}
BOOL STDCALL
NtUserChangeClipboardChain(HWND hWndRemove, HWND hWndNewNext)
{
- UNIMPLEMENTED
- return 0;
+ BOOL ret = FALSE;
+ PCLIPBOARDCHAINELEMENT w = NULL;
+
+ UserEnterExclusive();
+
+ PWINDOW_OBJECT removeWindow = UserGetWindowObject(hWndRemove);
+
+ if (removeWindow)
+ {
+ if ((ret = !!IntIsWindowInChain(removeWindow)))
+ {
+ w = IntRemoveWindowFromChain(removeWindow);
+ if (w)
+ {
+ ExFreePool(w);
+ }
+ }
+ }
+
+ if (ret && WindowsChain)
+ {
+ // only send message to the first window in the chain,
+ // then they do the chain
+ DPRINT1("Message: WM_CHANGECBCHAIN to %p",
WindowsChain->window->hSelf);
+ /* WindowsChain->window may be NULL */
+ LPARAM lparam = WindowsChain->window == NULL ? 0 :
(LPARAM)WindowsChain->window->hSelf;
+ co_IntSendMessage(WindowsChain->window->hSelf, WM_CHANGECBCHAIN,
(WPARAM)hWndRemove, lparam);
+ }
+
+ UserLeave();
+
+ return ret;
}
DWORD STDCALL
NtUserCountClipboardFormats(VOID)
{
- UNIMPLEMENTED
- return 0;
+ DWORD ret = 0;
+
+ if (ClipboardData)
+ {
+ ret = IntCountClipboardFormats();
+ }
+
+ return ret;
}
DWORD STDCALL
NtUserEmptyClipboard(VOID)
{
- CHECK_LOCK
-
- // if (!hCBData)
- // return FALSE;
-
- // FIXME!
- // GlobalUnlock(hCBData);
- // GlobalFree(hCBData);
- hCBData = NULL;
- uCBFormat = 0;
- ClipboardWindow = tempClipboardWindow;
-
- return TRUE;
+ BOOL ret = FALSE;
+
+ UserEnterExclusive();
+
+ if (intIsClipboardOpenByMe())
+ {
+ if (ClipboardData)
+ {
+ IntEmptyClipboardData();
+ }
+
+ ClipboardOwnerWindow = ClipboardWindow;
+ ClipboardOwnerThread = ClipboardThread;
+
+ IntIncrementSecuenceNumber();
+
+ ret = TRUE;
+ }
+ else
+ {
+ SetLastWin32Error(ERROR_CLIPBOARD_NOT_OPEN);
+ }
+
+ if (ret && ClipboardOwnerWindow)
+ {
+ DPRINT1("Clipboard: WM_DESTROYCLIPBOARD to %p",
ClipboardOwnerWindow->hSelf);
+ co_IntSendMessage( ClipboardOwnerWindow->hSelf, WM_DESTROYCLIPBOARD, 0, 0);
+ }
+
+ UserLeave();
+
+ return ret;
}
HANDLE STDCALL
NtUserGetClipboardData(UINT uFormat, DWORD Unknown1)
{
- CHECK_LOCK
-
- if ((uFormat==1 && uCBFormat==13) || (uFormat==13 && uCBFormat==1))
- uCBFormat = uFormat;
-
- if (uFormat != uCBFormat)
- return FALSE;
-
- return hCBData;
+ HANDLE ret = NULL;
+ PCHAR buffer;
+
+ UserEnterShared();
+
+ if (intIsClipboardOpenByMe())
+ {
+ /* when Unknown1 is zero, we returns to user32 the data size */
+ if (Unknown1 == 0)
+ {
+ PCLIPBOARDELEMENT data = intIsFormatAvailable(uFormat);
+
+ if (data)
+ {
+ /* format exists in clipboard */
+ if (data->size == DATA_DELAYED_RENDER)
+ {
+ /* tell owner what data needs to be rendered */
+ if (ClipboardOwnerWindow)
+ {
+ ASSERT(ClipboardOwnerWindow->hSelf);
+ co_IntSendMessage(ClipboardOwnerWindow->hSelf,
WM_RENDERFORMAT, (WPARAM)uFormat, 0);
+ data = intIsFormatAvailable(uFormat);
+ ASSERT(data->size);
+ ret = (HANDLE)data->size;
+ }
+ }
+ else
+ {
+ if (data->size == DATA_SYNTHESIZED_RENDER)
+ {
+ data->size = synthesizeData(uFormat);
+ }
+
+ }
+ ret = (HANDLE)data->size;
+ }
+ else
+ {
+ /* there is no data in this format */
+ //ret = (HANDLE)FALSE;
+ }
+ }
+ else
+ {
+ PCLIPBOARDELEMENT data = intIsFormatAvailable(uFormat);
+
+ if (data)
+ {
+ if (data->size == DATA_DELAYED_RENDER)
+ {
+ // we rendered it in 1st call of getclipboard data
+ }
+ else
+ {
+ if (data->size == DATA_SYNTHESIZED_RENDER)
+ {
+ if (uFormat == CF_BITMAP)
+ {
+ /* BITMAP & METAFILEs returns a GDI handle */
+ PCLIPBOARDELEMENT data = intIsFormatAvailable(CF_DIB);
+ if (data)
+ {
+ ret = renderBITMAPfromDIB(data->hData);
+ }
+ }
+ else
+ {
+ buffer = (PCHAR)Unknown1;
+ memcpy(buffer, (PCHAR)synthesizedData, synthesizedDataSize);
+
+ freeSynthesizedData();
+
+ ret = (HANDLE)Unknown1;
+ }
+ }
+ else
+ {
+ buffer = (PCHAR)Unknown1;
+ memcpy(buffer, (PCHAR)data->hData, data->size);
+
+ ret = (HANDLE)Unknown1;
+ }
+ }
+
+ }
+
+ }
+ }
+ else
+ {
+ SetLastWin32Error(ERROR_CLIPBOARD_NOT_OPEN);
+ }
+
+ UserLeave();
+
+ return ret;
}
INT STDCALL
NtUserGetClipboardFormatName(UINT format, PUNICODE_STRING FormatName,
INT cchMaxCount)
{
- NTSTATUS Status;
- PWSTR Buf;
- UNICODE_STRING SafeFormatName, BufFormatName;
- ULONG Ret;
-
- if((cchMaxCount < 1) || !FormatName)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- /* copy the FormatName UNICODE_STRING structure */
- Status = MmCopyFromCaller(&SafeFormatName, FormatName, sizeof(UNICODE_STRING));
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- return 0;
- }
-
- /* Allocate memory for the string */
- Buf = ExAllocatePoolWithTag(PagedPool, cchMaxCount * sizeof(WCHAR), TAG_STRING);
- if(!Buf)
- {
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
- return 0;
- }
-
- /* Setup internal unicode string */
- BufFormatName.Length = 0;
- BufFormatName.MaximumLength = min(cchMaxCount * sizeof(WCHAR),
SafeFormatName.MaximumLength);
- BufFormatName.Buffer = Buf;
-
- if(BufFormatName.MaximumLength < sizeof(WCHAR))
- {
- ExFreePool(Buf);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- if (format >= 0xC000)
- {
- Ret = IntGetClipboardFormatName(format, &BufFormatName);
- }
- else
- {
- SetLastNtError(NO_ERROR);
- return 0;
- }
-
- /* copy the UNICODE_STRING buffer back to the user */
- Status = MmCopyToCaller(SafeFormatName.Buffer, BufFormatName.Buffer,
BufFormatName.MaximumLength);
- if(!NT_SUCCESS(Status))
- {
- ExFreePool(Buf);
- SetLastNtError(Status);
- return 0;
- }
-
- BufFormatName.MaximumLength = SafeFormatName.MaximumLength;
- BufFormatName.Buffer = SafeFormatName.Buffer;
-
- /* update the UNICODE_STRING structure (only the Length member should change) */
- Status = MmCopyToCaller(FormatName, &BufFormatName, sizeof(UNICODE_STRING));
- if(!NT_SUCCESS(Status))
- {
- ExFreePool(Buf);
- SetLastNtError(Status);
- return 0;
- }
-
- ExFreePool(Buf);
- return Ret;
-}
+ UNICODE_STRING sFormatName;
+ INT ret = 0;
+
+ /* if the format is built-in we fail */
+ if (format < 0xc000)
+ {
+ /* registetrated formats are >= 0xc000 */
+ return 0;
+ }
+
+ if((cchMaxCount < 1) || !FormatName)
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ _SEH_TRY
+ {
+ ProbeForWriteUnicodeString(FormatName);
+ sFormatName = *(volatile UNICODE_STRING *)FormatName;
+ ProbeForWrite(sFormatName.Buffer, sFormatName.MaximumLength, 1);
+
+ ret = IntGetAtomName((RTL_ATOM)format, sFormatName.Buffer, cchMaxCount *
sizeof(WCHAR));
+
+ if (ret >= 0)
+ {
+ ret = ret / sizeof(WCHAR);
+ sFormatName.Length = ret;
+ }
+ else
+ {
+ ret = 0;
+ }
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ }
+ _SEH_END;
+
+ return ret;
+}
+
+UINT STDCALL
+NtUserRegisterClipboardFormat(PUNICODE_STRING FormatName)
+{
+ UINT ret = 0;
+ UNICODE_STRING cFormatName = {0};
+
+ if (FormatName == NULL)
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return ret;
+ }
+
+ UserEnterExclusive();
+
+ _SEH_TRY
+ {
+ cFormatName = ProbeForReadUnicodeString(FormatName);
+
+ if (cFormatName.Length > 0)
+ {
+ ret = (UINT)IntAddAtom(cFormatName.Buffer);
+ //RtlFreeUnicodeString(&cFormatName);
+ }
+ else
+ {
+ SetLastWin32Error(ERROR_INVALID_NAME);
+ _SEH_LEAVE;
+ }
+
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ }
+ _SEH_END;
+
+ UserLeave();
+
+ return ret;
+}
+
HWND STDCALL
NtUserGetClipboardOwner(VOID)
{
- return ClipboardWindow;
+ HWND ret = NULL;
+
+ UserEnterShared();
+
+ if (ClipboardOwnerWindow)
+ {
+ ret = ClipboardOwnerWindow->hSelf;
+ }
+
+ UserLeave();
+
+ return ret;
+}
+
+HWND STDCALL
+NtUserGetClipboardViewer(VOID)
+{
+ HWND ret = NULL;
+
+ UserEnterShared();
+
+ if (WindowsChain)
+ {
+ ret = WindowsChain->window->hSelf;
+ }
+
+ UserLeave();
+
+ return ret;
+}
+
+INT STDCALL
+NtUserGetPriorityClipboardFormat(UINT *paFormatPriorityList, INT cFormats)
+{
+ UINT i;
+ UINT *priorityList;
+ INT ret = 0;
+
+ UserEnterExclusive();
+
+ _SEH_TRY
+ {
+ if (IntCountClipboardFormats() == 0)
+ {
+ ret = 0;
+ }
+ else
+ {
+ ProbeForRead(paFormatPriorityList, cFormats, sizeof(UINT));
+
+ priorityList = paFormatPriorityList;
+
+ ret = -1;
+
+ for (i = 0; i < cFormats; i++)
+ {
+ if (intIsFormatAvailable(priorityList[i]))
+ {
+ ret = priorityList[i];
+ break;
+ }
+ }
+
+ }
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ }
+ _SEH_END;
+
+ UserLeave();
+
+ return ret;
+
+}
+
+BOOL STDCALL
+NtUserIsClipboardFormatAvailable(UINT format)
+{
+ BOOL ret = FALSE;
+
+ UserEnterShared();
+
+ ret = (intIsFormatAvailable(format) != NULL);
+
+ UserLeave();
+
+ return ret;
+}
+
+
+
+HANDLE STDCALL
+NtUserSetClipboardData(UINT uFormat, HANDLE hMem, DWORD size)
+{
+ HANDLE hCBData = NULL;
+ UNICODE_STRING unicodeString;
+ OEM_STRING oemString;
+ ANSI_STRING ansiString;
+
+ UserEnterExclusive();
+
+ /* to place data here the we need to be the owner */
+ if (ClipboardOwnerThread == PsGetCurrentThreadWin32Thread())
+ {
+ PCLIPBOARDELEMENT data = intIsFormatAvailable(uFormat);
+ if (data)
+ {
+
+ if (data->size == DATA_DELAYED_RENDER)
+ {
+ intRemoveFormatedData(uFormat);
+ }
+ else
+ {
+ // we already have this format on clipboard
+ goto exit_setCB;
+ }
+ }
+
+ if (hMem)
+ {
+ _SEH_TRY
+ {
+ ProbeForRead(hMem, size, 1);
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ goto exit_setCB;
+ }
+ _SEH_END;
+
+ if (intIsClipboardOpenByMe())
+ {
+ delayedRender = FALSE;
+ }
+
+ if (!canSinthesize(uFormat))
+ {
+ hCBData = ExAllocatePool(PagedPool, size);
+ memcpy(hCBData, hMem, size);
+ intAddFormatedData(uFormat, hCBData, size);
+ DPRINT1("Data stored\n");
+ }
+
+ sendDrawClipboardMsg = TRUE;
+ recentlySetClipboard = TRUE;
+ lastEnumClipboardFormats = uFormat;
+
+ /* conversions */
+ switch (uFormat)
+ {
+ case CF_TEXT:
+ {
+ //TODO : sinthesize CF_UNICODETEXT & CF_OEMTEXT
+ // CF_TEXT -> CF_UNICODETEXT
+ RtlAnsiStringToUnicodeString(&unicodeString, hCBData, TRUE);
+ intAddFormatedData(CF_UNICODETEXT, unicodeString.Buffer,
unicodeString.Length * sizeof(WCHAR));
+ // CF_TEXT -> CF_OEMTEXT
+ RtlUnicodeStringToOemString(&oemString, &unicodeString,
TRUE);
+ intAddFormatedData(CF_OEMTEXT, oemString.Buffer,
oemString.Length);
+ //HKCU\Control Panel\International\Locale
+ //intAddFormatedData(CF_LOCALE, oemString.Buffer,
oemString.Length);
+ break;
+ }
+ case CF_UNICODETEXT:
+ {
+ //TODO : sinthesize CF_TEXT & CF_OEMTEXT
+ //CF_UNICODETEXT -> CF_TEXT
+ unicodeString.Buffer = hCBData;
+ unicodeString.Length = size;
+ RtlUnicodeStringToAnsiString(&ansiString, &unicodeString,
TRUE);
+ intAddFormatedData(CF_TEXT, ansiString.Buffer, ansiString.Length);
+ //CF_UNICODETEXT -> CF_OEMTEXT
+ RtlUnicodeStringToOemString(&oemString, &unicodeString,
TRUE);
+ intAddFormatedData(CF_OEMTEXT, oemString.Buffer, oemString.Length);
+ break;
+ }
+ case CF_OEMTEXT:
+ {
+ //TODO : sinthesize CF_TEXT & CF_UNICODETEXT
+ //CF_OEMTEXT -> CF_UNICODETEXT
+ oemString.Buffer = hCBData;
+ oemString.Length = size;
+ RtlOemStringToUnicodeString(&unicodeString, &oemString,
TRUE);
+ intAddFormatedData(CF_UNICODETEXT, unicodeString.Buffer,
unicodeString.Length * sizeof(WCHAR));
+ //CF_OEMTEXT -> CF_TEXT
+ RtlUnicodeStringToAnsiString(&ansiString, &unicodeString,
TRUE);
+ intAddFormatedData(CF_TEXT, ansiString.Buffer, ansiString.Length);
+ break;
+ }
+ case CF_BITMAP:
+ {
+ // we need to render the DIB or DIBV5 format as soon as possible
+ // because pallette information may change
+
+ HDC hdc;
+ INT ret;
+ BITMAP bm;
+ BITMAPINFO bi;
+
+ hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE);
+
+ BITMAPOBJ *BitmapObj;
+ BitmapObj = BITMAPOBJ_LockBitmap(hMem);
+ BITMAP_GetObject(BitmapObj, sizeof(BITMAP), (LPSTR)&bm);
+ if(BitmapObj)
+ {
+ BITMAPOBJ_UnlockBitmap(BitmapObj);
+ }
+
+ bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bi.bmiHeader.biWidth = bm.bmWidth;
+ bi.bmiHeader.biHeight = bm.bmHeight;
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = bm.bmPlanes * bm.bmBitsPixel;
+ bi.bmiHeader.biCompression = BI_RGB;
+ bi.bmiHeader.biSizeImage = 0;
+ bi.bmiHeader.biXPelsPerMeter = 0;
+ bi.bmiHeader.biYPelsPerMeter = 0;
+ bi.bmiHeader.biClrUsed = 0;
+
+ ret = NtGdiGetDIBits(hdc, hMem, 0, bm.bmHeight, NULL, &bi,
DIB_RGB_COLORS);
+
+ size = bi.bmiHeader.biSizeImage + sizeof(BITMAPINFOHEADER);
+
+ hCBData = ExAllocatePool(PagedPool, size);
+ memcpy(hCBData, &bi, sizeof(BITMAPINFOHEADER));
+
+ ret = NtGdiGetDIBits(hdc, hMem, 0, bm.bmHeight, (LPBYTE)hCBData +
sizeof(BITMAPINFOHEADER), &bi, DIB_RGB_COLORS);
+
+ UserReleaseDC(NULL, hdc, FALSE);
+
+ intAddFormatedData(CF_DIB, hCBData, size);
+ intAddFormatedData(CF_BITMAP, 0, DATA_SYNTHESIZED_RENDER);
+ // intAddFormatedData(CF_DIBV5, hCBData, size);
+
+ break;
+ }
+ case CF_DIB:
+ {
+ intAddFormatedData(CF_BITMAP, 0, DATA_SYNTHESIZED_RENDER);
+ // intAddFormatedData(CF_DIBV5, hCBData, size);
+ /* investigate */
+ // intAddFormatedData(CF_PALETTE, hCBData, size);
+ break;
+ }
+ case CF_DIBV5:
+ // intAddFormatedData(CF_BITMAP, hCBData, size);
+ // intAddFormatedData(CF_PALETTE, hCBData, size);
+ // intAddFormatedData(CF_DIB, hCBData, size);
+ break;
+ case CF_ENHMETAFILE:
+ // intAddFormatedData(CF_METAFILEPICT, hCBData, size);
+ break;
+ case CF_METAFILEPICT:
+ // intAddFormatedData(CF_ENHMETAFILE, hCBData, size);
+ break;
+ }
+
+ }
+ else
+ {
+ // the window provides data in the specified format
+ delayedRender = TRUE;
+ sendDrawClipboardMsg = TRUE;
+ intAddFormatedData(uFormat, NULL, 0);
+ DPRINT1("SetClipboardData delayed format: %d\n", uFormat);
+ }
+
+
+ }
+
+exit_setCB:
+
+ UserLeave();
+
+ return hMem;
+}
+
+HWND STDCALL
+NtUserSetClipboardViewer(HWND hWndNewViewer)
+{
+ HWND ret = NULL;
+ PCLIPBOARDCHAINELEMENT newWC = NULL;
+
+ UserEnterExclusive();
+
+ PWINDOW_OBJECT window = UserGetWindowObject(hWndNewViewer);
+
+ if (window)
+ {
+ if ((newWC = IntAddWindowToChain(window)))
+ {
+ if (newWC)
+ {
+ // newWC->next may be NULL if we are the first window in the chain
+ if (newWC->next)
+ {
+ // return the next HWND available window in the chain
+ ret = newWC->next->window->hSelf;
+ }
+ }
+ }
+ }
+
+ UserLeave();
+
+ return ret;
+}
+
+UINT STDCALL
+NtUserEnumClipboardFormats(UINT uFormat)
+{
+ UINT ret = 0;
+
+ UserEnterShared();
+
+ if (intIsClipboardOpenByMe())
+ {
+ if (uFormat == 0)
+ {
+ if (recentlySetClipboard)
+ {
+ ret = lastEnumClipboardFormats;
+ }
+ else
+ {
+ /* return the first available format */
+ if (ClipboardData)
+ {
+ ret = ClipboardData->format;
+ }
+ }
+ }
+ else
+ {
+ if (recentlySetClipboard)
+ {
+ ret = 0;
+ }
+ else
+ {
+ /* querying nextt available format */
+ PCLIPBOARDELEMENT data = intIsFormatAvailable(uFormat);
+
+ if (data)
+ {
+ if (data->next)
+ {
+ ret = data->next->format;
+ }
+ else
+ {
+ /* reached the end */
+ ret = 0;
+ }
+ }
+ }
+
+ }
+ }
+ else
+ {
+ SetLastWin32Error(ERROR_CLIPBOARD_NOT_OPEN);
+ }
+
+ UserLeave();
+
+ return ret;
+}
+
+// This number is incremented whenever the contents of the clipboard change
+// or the clipboard is emptied.
+// If clipboard rendering is delayed,
+// the sequence number is not incremented until the changes are rendered.
+VOID FASTCALL
+IntIncrementSecuenceNumber(VOID)
+{
+
+ USE_WINSTA
+
+ WINSTA_ClipboardSequenceNumber++;
+
}
DWORD STDCALL
NtUserGetClipboardSequenceNumber(VOID)
{
- UNIMPLEMENTED
- return 0;
-}
-
-HWND STDCALL
-NtUserGetClipboardViewer(VOID)
-{
- UNIMPLEMENTED
- return 0;
-}
-
-INT STDCALL
-NtUserGetPriorityClipboardFormat(UINT *paFormatPriorityList, INT cFormats)
-{
- UNIMPLEMENTED
- return 0;
-}
-
-BOOL STDCALL
-NtUserIsClipboardFormatAvailable(UINT format)
-{
- //UNIMPLEMENTED
-
- if (format != 1 && format != 13)
- {
- DbgPrint("Clipboard Format unavailable (%d)\n", format);
- return FALSE;
- }
-
- if ((format==1 && uCBFormat==13) || (format==13 && uCBFormat==1))
- uCBFormat = format;
-
- if (format != uCBFormat)
- return FALSE;
-
- return TRUE;
-}
-
-//SetClipboardData(CF_UNICODETEXT, hdst);
-HANDLE STDCALL
-NtUserSetClipboardData(UINT uFormat, HANDLE hMem, DWORD Unknown2)
-{
- // LPVOID pMem;
- CHECK_LOCK
-
-
- if (uFormat != 1 && uFormat != 13)
- {
- DbgPrint("Clipboard unsupported format (%d)\n", uFormat);
- return FALSE;
- }
-
- if (hMem)
- {
- uCBFormat = uFormat;
- hCBData = hMem;
- //pMem = GlobalLock(hMem);
- /*
- switch (uFormat) {
- default:
- DbgPrint("Clipboard unsupported format (%d)\n", uFormat);
- return FALSE;
- case CF_TEXT: // 1
- break;
- case CF_UNICODETEXT: // 13
- break;
- case CF_BITMAP: // 2
- break;
- case CF_OEMTEXT: // 7
- break;
- } */
- }
- else
- {
- //the window provides data in the specified format
- }
- return hMem;
-}
-
-HWND STDCALL
-NtUserSetClipboardViewer(HWND hWndNewViewer)
-{
- HWND hwndPrev = 0;
- DbgPrint("NtUserSetClipboardViewer is UNIMPLEMENTED (%p): returning %p\n",
hWndNewViewer, hwndPrev);
- return hwndPrev;
+ //windowstation sequence number
+ //if no WINSTA_ACCESSCLIPBOARD access to the window station,
+ //the function returns zero.
+ DWORD sn;
+
+ HWINSTA WinSta;
+ PWINSTATION_OBJECT WinStaObj;
+ NTSTATUS Status;
+
+ WinSta = UserGetProcessWindowStation();
+
+ Status = IntValidateWindowStationHandle(WinSta, UserMode, WINSTA_ACCESSCLIPBOARD,
&WinStaObj);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("No WINSTA_ACCESSCLIPBOARD access\n");
+ SetLastNtError(Status);
+ return 0;
+ }
+
+ sn = WinStaObj->ClipboardSequenceNumber;
+
+ ObDereferenceObject(WinStaObj);
+
+ //local copy
+ //sn = ClipboardSequenceNumber;
+
+ return sn;
+}
+
+BOOL FASTCALL
+IntSetupClipboard(PWINSTATION_OBJECT WinStaObj)
+{
+ WinStaObj->Clipboard = ExAllocatePool(PagedPool, sizeof(CLIPBOARDSYSTEM));
+ if (WinStaObj->Clipboard)
+ {
+ RtlZeroMemory(WinStaObj->Clipboard, sizeof(CLIPBOARDSYSTEM));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**************** VISTA FUNCTIONS******************/
+
+BOOL STDCALL NtUserAddClipboardFormatListener(
+ HWND hwnd
+)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
+
+BOOL STDCALL NtUserRemoveClipboardFormatListener(
+ HWND hwnd
+)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
+
+BOOL STDCALL NtUserGetUpdatedClipboardFormats(
+ PUINT lpuiFormats,
+ UINT cFormats,
+ PUINT pcFormatsOut
+)
+{
+ UNIMPLEMENTED;
+ return FALSE;
}
/* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/misc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/misc.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/misc.c Thu Mar 8 16:31:33 2007
@@ -308,10 +308,10 @@
case ONEPARAM_ROUTINE_SETCARETBLINKTIME:
RETURN( (DWORD)IntSetCaretBlinkTime((UINT)Param));
-
+/*
case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS:
- RETURN( (DWORD)IntEnumClipboardFormats((UINT)Param));
-
+ RETURN( (DWORD)NtUserEnumClipboardFormats((UINT)Param));
+*/
case ONEPARAM_ROUTINE_GETWINDOWINSTANCE:
{
PWINDOW_OBJECT Window;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/useratom.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/useratom.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/useratom.c Thu Mar 8 16:31:33 2007
@@ -32,7 +32,6 @@
RTL_ATOM FASTCALL
IntAddAtom(LPWSTR AtomName)
{
- PWINSTATION_OBJECT WinStaObject;
NTSTATUS Status = STATUS_SUCCESS;
RTL_ATOM Atom;
@@ -41,9 +40,9 @@
SetLastNtError(Status);
return (RTL_ATOM)0;
}
- WinStaObject = PsGetCurrentThreadWin32Thread()->Desktop->WindowStation;
- Status = RtlAddAtomToAtomTable(WinStaObject->AtomTable,
- AtomName, &Atom);
+
+ Status = RtlAddAtomToAtomTable(gAtomTable, AtomName, &Atom);
+
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
@@ -55,7 +54,6 @@
ULONG FASTCALL
IntGetAtomName(RTL_ATOM nAtom, LPWSTR lpBuffer, ULONG nSize)
{
- PWINSTATION_OBJECT WinStaObject;
NTSTATUS Status = STATUS_SUCCESS;
ULONG Size = nSize;
@@ -64,9 +62,9 @@
SetLastNtError(Status);
return 0;
}
- WinStaObject = PsGetCurrentThreadWin32Thread()->Desktop->WindowStation;
- Status = RtlQueryAtomInAtomTable(WinStaObject->AtomTable,
- nAtom, NULL, NULL, lpBuffer, &Size);
+
+ Status = RtlQueryAtomInAtomTable(gAtomTable, nAtom, NULL, NULL, lpBuffer, &Size);
+
if (Size < nSize)
*(lpBuffer + Size) = 0;
if (!NT_SUCCESS(Status))
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/window.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c Thu Mar 8 16:31:33 2007
@@ -30,7 +30,7 @@
#include <w32k.h>
-#define NDEBUG
+#define YDEBUG
#include <debug.h>
/* dialog resources appear to pass this in 16 bits, handle them properly */
@@ -460,6 +460,8 @@
RtlFreeUnicodeString(&Window->WindowName);
UserDerefObject(Window);
+
+ IntClipboardFreeWindow(Window);
return 0;
}
@@ -1888,16 +1890,18 @@
/* Calculate the non-client size. */
MaxPos.x = Window->WindowRect.left;
MaxPos.y = Window->WindowRect.top;
+
+
DPRINT("IntCreateWindowEx(): About to get non-client size.\n");
/* WinPosGetNonClientSize SENDS THE WM_NCCALCSIZE message */
Result = co_WinPosGetNonClientSize(Window,
&Window->WindowRect,
&Window->ClientRect);
-
IntGdiOffsetRect(&Window->WindowRect,
MaxPos.x - Window->WindowRect.left,
MaxPos.y - Window->WindowRect.top);
+
if (NULL != ParentWindow)
{
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/winpos.c Thu Mar 8 16:31:33 2007
@@ -969,6 +969,8 @@
}
WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect,
&NewClientRect);
+
+ //DPRINT1("co_WinPosDoNCCALCSize");
/* Relink windows. (also take into account shell window in hwndShellWindow) */
if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd !=
UserGetShellWindow())
@@ -1385,7 +1387,8 @@
break;
case SW_SHOWNOACTIVATE:
- Swp |= SWP_NOZORDER;
+ //Swp |= SWP_NOZORDER;
+ Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* Fall through. */
case SW_SHOWNORMAL:
case SW_SHOWDEFAULT:
@@ -1408,6 +1411,7 @@
}
ShowFlag = (Cmd != SW_HIDE);
+
if (ShowFlag != WasVisible)
{
co_IntSendMessage(Window->hSelf, WM_SHOWWINDOW, ShowFlag, 0);
@@ -1477,6 +1481,7 @@
MAKELONG(Window->ClientRect.left,
Window->ClientRect.top));
IntEngWindowChanged(Window, WOC_RGN_CLIENT);
+
}
/* Activate the window if activation is not requested and the window is not minimized
*/
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/winsta.c Thu Mar 8 16:31:33 2007
@@ -517,7 +517,13 @@
CurInfo->DblClickHeight = 4;
WindowStationObject->SystemCursor = CurInfo;
-
+
+
+ if (!IntSetupClipboard(WindowStationObject))
+ {
+ DPRINT1("WindowStation: Error Setting up the clipboard!!!\n");
+ }
+
if (!IntSetupCurIconHandles(WindowStationObject))
{
DPRINT1("Setting up the Cursor/Icon Handle table failed!\n");
Modified: trunk/reactos/tools/nci/w32ksvc.db
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/tools/nci/w32ksvc.db?rev=2…
==============================================================================
--- trunk/reactos/tools/nci/w32ksvc.db (original)
+++ trunk/reactos/tools/nci/w32ksvc.db Thu Mar 8 16:31:33 2007
@@ -342,6 +342,7 @@
NtUserEndDeferWindowPosEx 2
NtUserEndMenu 0
NtUserEndPaint 2
+NtUserEnumClipboardFormats 1
NtUserEnumDisplayDevices 4
NtUserEnumDisplayMonitors 5
NtUserEnumDisplaySettings 4
@@ -461,6 +462,7 @@
NtUserRealChildWindowFromPoint 3
NtUserRedrawWindow 4
NtUserRegisterClassEx 6
+NtUserRegisterClipboardFormat 1
NtUserRegisterHotKey 4
NtUserRegisterTasklist 1
NtUserRegisterWindowMessage 1