Bug 499803 - "Implement simple clipboard on Windows CE" [r=vladimir]
authorJustin Dolske <dolske@mozilla.com>
Fri, 03 Jul 2009 16:11:05 -0700
changeset 29984 461bacbc37abe3cc92ef989ae36eefffe7243386
parent 29983 99cf4f9414d7772569d29f3ecc1801dbd37221e0
child 29985 ab31f00e2c27837367e0d41704753a33f833d203
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvladimir
bugs499803
milestone1.9.2a1pre
Bug 499803 - "Implement simple clipboard on Windows CE" [r=vladimir]
browser/base/Makefile.in
widget/src/build/nsWinWidgetFactory.cpp
widget/src/windows/nsClipboardCE.cpp
widget/src/windows/nsClipboardCE.h
--- a/browser/base/Makefile.in
+++ b/browser/base/Makefile.in
@@ -82,14 +82,16 @@ libs locale::
 	$(SYSINSTALL) $(IFLAGS1) $(srcdir)/content/old-homepage-default.properties $(DIST)/bin
 
 install::
 	$(SYSINSTALL) $(IFLAGS1) $(srcdir)/content/browserconfig.properties $(DESTDIR)$(mozappdir)
 	$(SYSINSTALL) $(IFLAGS1) $(srcdir)/content/old-homepage-default.properties $(DESTDIR)$(mozappdir)
 endif
 
 ifneq (,$(filter windows mac cocoa gtk2, $(MOZ_WIDGET_TOOLKIT)))
+ifneq ($(OS_ARCH),WINCE)
 DEFINES += -DCONTEXT_COPY_IMAGE_CONTENTS=1
 endif
+endif
 
 ifneq (,$(BUILD_OFFICIAL)$(MOZILLA_OFFICIAL))
 DEFINES += -DOFFICIAL_BUILD=1
 endif
--- a/widget/src/build/nsWinWidgetFactory.cpp
+++ b/widget/src/build/nsWinWidgetFactory.cpp
@@ -60,19 +60,19 @@
 #include "nsClipboardHelper.h"
 
 #ifdef WINCE
 #include "nsClipboardCE.h"
 #else
 #include "nsClipboard.h"
 #include "nsBidiKeyboard.h"
 #include "nsDragService.h"
-#include "nsHTMLFormatConverter.h"
+#endif
 #include "nsTransferable.h"
-#endif
+#include "nsHTMLFormatConverter.h"
 
 #ifdef NS_PRINTING
 #include "nsDeviceContextSpecWin.h"
 #include "nsPrintOptionsWin.h"
 #include "nsPrintSession.h"
 #endif
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
@@ -81,19 +81,19 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePic
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsToolkit)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerWin)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsIdleServiceWin)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
 
-#ifndef WINCE
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
+#ifndef WINCE
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDragService)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard)
 #endif
 
 #ifdef NS_PRINTING
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintOptionsWin, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsPrinterEnumeratorWin)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSession, Init)
@@ -146,34 +146,34 @@ static const nsModuleComponentInfo compo
   { "Clipboard Helper",
     NS_CLIPBOARDHELPER_CID,
     "@mozilla.org/widget/clipboardhelper;1",
     nsClipboardHelperConstructor },
   { "Sound",
     NS_SOUND_CID,
     "@mozilla.org/sound;1",
     nsSoundConstructor },
+  { "Transferable",
+    NS_TRANSFERABLE_CID,
+    "@mozilla.org/widget/transferable;1",
+    nsTransferableConstructor },
+  { "HTML Format Converter",
+    NS_HTMLFORMATCONVERTER_CID,
+    "@mozilla.org/widget/htmlformatconverter;1",
+    nsHTMLFormatConverterConstructor },
 
 #ifndef WINCE
   { "Drag Service",
     NS_DRAGSERVICE_CID,
     "@mozilla.org/widget/dragservice;1",
     nsDragServiceConstructor },
   { "Bidi Keyboard",
     NS_BIDIKEYBOARD_CID,
     "@mozilla.org/widget/bidikeyboard;1",
     nsBidiKeyboardConstructor },
-  { "Transferable",
-    NS_TRANSFERABLE_CID,
-    "@mozilla.org/widget/transferable;1",
-    nsTransferableConstructor },
-  { "HTML Format Converter",
-    NS_HTMLFORMATCONVERTER_CID,
-    "@mozilla.org/widget/htmlformatconverter;1",
-    nsHTMLFormatConverterConstructor },
 #endif
 
 #ifdef NS_PRINTING
   { "nsPrintOptionsWin",
     NS_PRINTSETTINGSSERVICE_CID,
     "@mozilla.org/gfx/printsettings-service;1",
     nsPrintOptionsWinConstructor },
   { "Win Printer Enumerator",
--- a/widget/src/windows/nsClipboardCE.cpp
+++ b/widget/src/windows/nsClipboardCE.cpp
@@ -33,30 +33,209 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsClipboardCE.h"
 
+#include "nsISupportsPrimitives.h"
+#include "nsXPIDLString.h"
+#include "nsCRT.h"
+#include "nsComponentManagerUtils.h"
+
 #include <winuserm.h>
 
 nsClipboard::nsClipboard()
 {
 }
 
 nsClipboard::~nsClipboard()
 {
 }
 
+UINT nsClipboard::GetFormat(const char* aMimeStr)
+{
+  UINT format;
+
+  if (strcmp(aMimeStr, kTextMime) == 0)
+    format = CF_TEXT;
+  else if (strcmp(aMimeStr, kUnicodeMime) == 0)
+    format = CF_UNICODETEXT;
+  else if (strcmp(aMimeStr, kJPEGImageMime) == 0 ||
+           strcmp(aMimeStr, kPNGImageMime) == 0)
+    format = CF_DIB;
+  else if (strcmp(aMimeStr, kFileMime) == 0 || 
+           strcmp(aMimeStr, kFilePromiseMime) == 0)
+    format = CF_HDROP; // XXX CF_HDROP not listed as supported but it compiles!
+  else
+    format = ::RegisterClipboardFormat(NS_ConvertASCIItoUTF16(aMimeStr).get());
+
+  // CE doesn't support CF_HTML (kNativeHTMLMime)
+
+  return format;
+}
+
 NS_IMETHODIMP
 nsClipboard::SetNativeClipboardData(PRInt32 aWhichClipboard)
 {
-  return NS_ERROR_FAILURE;
+  if (aWhichClipboard != kGlobalClipboard || !mTransferable)
+    return NS_ERROR_INVALID_ARG;
+
+  if (!::OpenClipboard(NULL))
+    return NS_ERROR_FAILURE;
+
+  if (!::EmptyClipboard())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsISupportsArray> flavorList;
+  mTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
+
+  PRUint32 count, i;
+  flavorList->Count(&count);
+  nsresult rv = NS_OK;
+
+  for (i = 0; i < count; i++) {
+    nsCOMPtr<nsISupports> listItem;
+    flavorList->GetElementAt(i, getter_AddRefs(listItem));
+
+    nsCOMPtr<nsISupportsCString> flavor(do_QueryInterface(listItem));
+    if (!flavor)
+      continue;
+    nsXPIDLCString flavorStr;
+    flavor->ToString(getter_Copies(flavorStr));
+
+    UINT format = GetFormat(flavorStr);
+
+    PRUint32 len;
+    nsCOMPtr<nsISupports> wrapper;
+    mTransferable->GetTransferData(flavorStr, getter_AddRefs(wrapper), &len);
+    if (!wrapper)
+      continue;
+
+    char *memory = nsnull;
+    nsCOMPtr<nsISupportsString> textItem(do_QueryInterface(wrapper));
+    nsCOMPtr<nsISupportsPRBool> boolItem(do_QueryInterface(wrapper));
+
+    if (format == CF_TEXT || format == CF_DIB || format == CF_HDROP) {
+      NS_WARNING("Setting this clipboard format not implemented");
+      continue;
+    } else if (textItem) {
+      // format == CF_UNICODETEXT, or is otherwise unicode data.
+      nsAutoString text;
+      textItem->GetData(text);
+      PRInt32 len = text.Length() * 2;
+
+      memory = reinterpret_cast<char*>(::LocalAlloc(LMEM_FIXED, len + 2));
+      if (!memory) {
+        rv = NS_ERROR_OUT_OF_MEMORY;
+        break;
+      }
+      memcpy(memory, nsPromiseFlatString(text).get(), len);
+      memory[len]   = '\0';
+      memory[len+1] = '\0';
+    } else if (boolItem) {
+      // Private browsing sets a boolean type.
+      PRBool value;
+      boolItem->GetData(&value);
+      memory = reinterpret_cast<char*>(::LocalAlloc(LMEM_FIXED, 1));
+      if (!memory) {
+        rv = NS_ERROR_OUT_OF_MEMORY;
+        break;
+      }
+      *memory = value ? 1 : 0;
+    } else {
+      NS_WARNING("Can't set unknown transferrable primitive");
+      continue;
+    }
+
+    if (!::SetClipboardData(format, memory)) {
+      NS_WARNING("::SetClipboardData failed");
+      if (memory)
+        ::LocalFree(memory);
+    }
+  }
+
+  ::CloseClipboard();
+
+  return rv;
 }
 
 NS_IMETHODIMP
 nsClipboard::GetNativeClipboardData(nsITransferable *aTransferable,
 				    PRInt32 aWhichClipboard)
 {
-  return NS_ERROR_FAILURE;
+  if (aWhichClipboard != kGlobalClipboard || !aTransferable)
+    return NS_ERROR_INVALID_ARG;
+
+  if (!::OpenClipboard(NULL))
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsISupportsArray> flavorList;
+  mTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
+
+  PRUint32 count, i;
+  flavorList->Count(&count);
+  nsresult rv = NS_OK;
+
+  for (i = 0; i < count; i++) {
+    nsCOMPtr<nsISupports> listItem;
+    flavorList->GetElementAt(i, getter_AddRefs(listItem));
+
+    nsCOMPtr<nsISupportsCString> flavor(do_QueryInterface(listItem));
+    if (!flavor)
+      continue;
+    nsXPIDLCString flavorStr;
+    flavor->ToString(getter_Copies(flavorStr));
+
+    UINT format = GetFormat(flavorStr);
+
+    void *data;
+    data = ::GetClipboardData(format);
+    if (!data)
+      continue;
+
+    if (format == CF_UNICODETEXT) {
+      PRUnichar *dataStr = reinterpret_cast<PRUnichar*>(data);
+      nsString *stringCopy = new nsString(dataStr);
+
+      nsCOMPtr<nsISupportsString> primitive =
+        do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
+      if (!primitive) {
+        rv = NS_ERROR_OUT_OF_MEMORY;
+        break;
+      }
+
+      primitive->SetData(*stringCopy);
+      aTransferable->SetTransferData(flavorStr, primitive,
+                                     stringCopy->Length() * sizeof(PRUnichar));
+    } else {
+      NS_WARNING("Getting this clipboard format not implemented");
+      continue;
+    }
+
+  }
+
+  ::CloseClipboard();
+
+  return rv;
 }
+
+NS_IMETHODIMP nsClipboard::HasDataMatchingFlavors(const char** aFlavorList,
+                                                  PRUint32 aLength,
+                                                  PRInt32 aWhichClipboard,
+                                                  PRBool *_retval)
+{
+  *_retval = PR_FALSE;
+  if (aWhichClipboard != kGlobalClipboard || !aFlavorList)
+    return NS_OK;
+  for (PRUint32 i = 0;i < aLength; ++i) {
+
+    UINT format = GetFormat(aFlavorList[i]);
+    if (::IsClipboardFormatAvailable(format)) {
+      *_retval = PR_TRUE;
+      break;
+    }
+  }
+
+  return NS_OK;
+}
--- a/widget/src/windows/nsClipboardCE.h
+++ b/widget/src/windows/nsClipboardCE.h
@@ -48,15 +48,20 @@
  */
 
 class nsClipboard :
   public nsBaseClipboard
 {
 public:
   nsClipboard();
   virtual ~nsClipboard();
+  NS_IMETHOD HasDataMatchingFlavors(const char** aFlavorList, PRUint32 aLength,
+                                    PRInt32 aWhichClipboard, PRBool *_retval);
 
 protected:
   NS_IMETHOD SetNativeClipboardData (PRInt32 aWhichClipboard);
   NS_IMETHOD GetNativeClipboardData (nsITransferable * aTransferable, PRInt32 aWhichClipboard);
+
+private:
+  static UINT     GetFormat(const char* aMimeStr);
 };
 
 #endif