summaryrefslogtreecommitdiffstats
path: root/meta/packages/mozilla-headless/mozilla-headless/0001-Adds-initial-Gtk-clipboard-support-to-moz-headless.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/packages/mozilla-headless/mozilla-headless/0001-Adds-initial-Gtk-clipboard-support-to-moz-headless.patch')
-rw-r--r--meta/packages/mozilla-headless/mozilla-headless/0001-Adds-initial-Gtk-clipboard-support-to-moz-headless.patch1478
1 files changed, 0 insertions, 1478 deletions
diff --git a/meta/packages/mozilla-headless/mozilla-headless/0001-Adds-initial-Gtk-clipboard-support-to-moz-headless.patch b/meta/packages/mozilla-headless/mozilla-headless/0001-Adds-initial-Gtk-clipboard-support-to-moz-headless.patch
deleted file mode 100644
index db9e147990..0000000000
--- a/meta/packages/mozilla-headless/mozilla-headless/0001-Adds-initial-Gtk-clipboard-support-to-moz-headless.patch
+++ /dev/null
@@ -1,1478 +0,0 @@
-From fb41f028badb4dfddfc47fb2a1a68c1aa90dcef5 Mon Sep 17 00:00:00 2001
-From: Robert Bragg <robert@linux.intel.com>
-Date: Fri, 8 May 2009 13:57:22 +0100
-Subject: [PATCH] Adds initial Gtk clipboard support to moz-headless
-
-If build with MOZ_X11 enabled then this now builds the clipboard code taken
-from the gtk2 backend. This doesn't provide any embedding API yet to expose
-the clipboard.
----
- widget/src/headless/Makefile.in | 6 +
- widget/src/headless/nsClipboard.cpp | 948 +++++++++++++++++++++++++++++++
- widget/src/headless/nsClipboard.h | 93 +++
- widget/src/headless/nsIImageToPixbuf.h | 62 ++
- widget/src/headless/nsImageToPixbuf.cpp | 196 +++++++
- widget/src/headless/nsImageToPixbuf.h | 71 +++
- widget/src/headless/nsWidgetFactory.cpp | 18 +
- 7 files changed, 1394 insertions(+), 0 deletions(-)
- create mode 100644 widget/src/headless/nsClipboard.cpp
- create mode 100644 widget/src/headless/nsClipboard.h
- create mode 100644 widget/src/headless/nsIImageToPixbuf.h
- create mode 100644 widget/src/headless/nsImageToPixbuf.cpp
- create mode 100644 widget/src/headless/nsImageToPixbuf.h
-
-Index: offscreen/widget/src/headless/Makefile.in
-===================================================================
---- offscreen.orig/widget/src/headless/Makefile.in 2009-05-16 18:23:25.000000000 +0100
-+++ offscreen/widget/src/headless/Makefile.in 2009-06-12 14:14:05.000000000 +0100
-@@ -95,6 +95,12 @@
- nsScreenManagerHeadless.cpp \
- $(NULL)
-
-+ifdef MOZ_X11
-+CPPSRCS += nsClipboard.cpp \
-+ nsImageToPixbuf.cpp \
-+ $(NULL)
-+endif
-+
- # build our subdirs, too
- SHARED_LIBRARY_LIBS = ../xpwidgets/libxpwidgets_s.a
-
-Index: offscreen/widget/src/headless/nsClipboard.cpp
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ offscreen/widget/src/headless/nsClipboard.cpp 2009-06-12 14:14:05.000000000 +0100
-@@ -0,0 +1,948 @@
-+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-+/* vim:expandtab:shiftwidth=4:tabstop=4:
-+ */
-+/* ***** BEGIN LICENSE BLOCK *****
-+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
-+ *
-+ * The contents of this file are subject to the Mozilla Public License Version
-+ * 1.1 (the "License"); you may not use this file except in compliance with
-+ * the License. You may obtain a copy of the License at
-+ * http://www.mozilla.org/MPL/
-+ *
-+ * Software distributed under the License is distributed on an "AS IS" basis,
-+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-+ * for the specific language governing rights and limitations under the
-+ * License.
-+ *
-+ * The Original Code is mozilla.org code.
-+ *
-+ * The Initial Developer of the Original Code is Christopher Blizzard
-+ * <blizzard@mozilla.org>. Portions created by the Initial Developer
-+ * are Copyright (C) 2001 the Initial Developer. All Rights Reserved.
-+ *
-+ * Contributor(s):
-+ *
-+ * Alternatively, the contents of this file may be used under the terms of
-+ * either the GNU General Public License Version 2 or later (the "GPL"), or
-+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-+ * in which case the provisions of the GPL or the LGPL are applicable instead
-+ * of those above. If you wish to allow use of your version of this file only
-+ * under the terms of either the GPL or the LGPL, and not to allow others to
-+ * use your version of this file under the terms of the MPL, indicate your
-+ * decision by deleting the provisions above and replace them with the notice
-+ * 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 "nsClipboard.h"
-+#include "nsSupportsPrimitives.h"
-+#include "nsString.h"
-+#include "nsReadableUtils.h"
-+#include "nsXPIDLString.h"
-+#include "nsPrimitiveHelpers.h"
-+#include "nsICharsetConverterManager.h"
-+#include "nsIServiceManager.h"
-+#include "nsIImage.h"
-+#include "nsImageToPixbuf.h"
-+#include "nsStringStream.h"
-+
-+#include <gtk/gtk.h>
-+
-+// For manipulation of the X event queue
-+#include <X11/Xlib.h>
-+#include <gdk/gdkx.h>
-+#include <sys/time.h>
-+#include <sys/types.h>
-+#include <unistd.h>
-+
-+#ifdef POLL_WITH_XCONNECTIONNUMBER
-+#include <poll.h>
-+#endif
-+
-+// Callback when someone asks us for the selection
-+void
-+invisible_selection_get_cb (GtkWidget *aWidget,
-+ GtkSelectionData *aSelectionData,
-+ guint aTime,
-+ guint aInfo,
-+ nsClipboard *aClipboard);
-+
-+gboolean
-+selection_clear_event_cb (GtkWidget *aWidget,
-+ GdkEventSelection *aEvent,
-+ nsClipboard *aClipboard);
-+
-+static void
-+ConvertHTMLtoUCS2 (guchar *data,
-+ PRInt32 dataLength,
-+ PRUnichar **unicodeData,
-+ PRInt32 &outUnicodeLen);
-+
-+static void
-+GetHTMLCharset (guchar * data, PRInt32 dataLength, nsCString& str);
-+
-+
-+// Our own versions of gtk_clipboard_wait_for_contents and
-+// gtk_clipboard_wait_for_text, which don't run the event loop while
-+// waiting for the data. This prevents a lot of problems related to
-+// dispatching events at unexpected times.
-+
-+static GtkSelectionData *
-+wait_for_contents (GtkClipboard *clipboard, GdkAtom target);
-+
-+static gchar *
-+wait_for_text (GtkClipboard *clipboard);
-+
-+static Bool
-+checkEventProc(Display *display, XEvent *event, XPointer arg);
-+
-+struct retrieval_context
-+{
-+ PRBool completed;
-+ void *data;
-+
-+ retrieval_context() : completed(PR_FALSE), data(nsnull) { }
-+};
-+
-+static void
-+wait_for_retrieval(GtkClipboard *clipboard, retrieval_context *transferData);
-+
-+static void
-+clipboard_contents_received(GtkClipboard *clipboard,
-+ GtkSelectionData *selection_data,
-+ gpointer data);
-+
-+static void
-+clipboard_text_received(GtkClipboard *clipboard,
-+ const gchar *text,
-+ gpointer data);
-+
-+nsClipboard::nsClipboard()
-+{
-+ mWidget = nsnull;
-+}
-+
-+nsClipboard::~nsClipboard()
-+{
-+ if (mWidget)
-+ gtk_widget_destroy(mWidget);
-+}
-+
-+NS_IMPL_ISUPPORTS1(nsClipboard, nsIClipboard)
-+
-+nsresult
-+nsClipboard::Init(void)
-+{
-+ mWidget = gtk_invisible_new();
-+ if (!mWidget)
-+ return NS_ERROR_FAILURE;
-+
-+ g_signal_connect(G_OBJECT(mWidget), "selection_get",
-+ G_CALLBACK(invisible_selection_get_cb), this);
-+
-+ g_signal_connect(G_OBJECT(mWidget), "selection_clear_event",
-+ G_CALLBACK(selection_clear_event_cb), this);
-+
-+ // XXX make sure to set up the selection_clear event
-+
-+ return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsClipboard::SetData(nsITransferable *aTransferable,
-+ nsIClipboardOwner *aOwner, PRInt32 aWhichClipboard)
-+{
-+ // See if we can short cut
-+ if ((aWhichClipboard == kGlobalClipboard &&
-+ aTransferable == mGlobalTransferable.get() &&
-+ aOwner == mGlobalOwner.get()) ||
-+ (aWhichClipboard == kSelectionClipboard &&
-+ aTransferable == mSelectionTransferable.get() &&
-+ aOwner == mSelectionOwner.get())) {
-+ return NS_OK;
-+ }
-+
-+ nsresult rv;
-+ if (!mPrivacyHandler) {
-+ rv = NS_NewClipboardPrivacyHandler(getter_AddRefs(mPrivacyHandler));
-+ NS_ENSURE_SUCCESS(rv, rv);
-+ }
-+ rv = mPrivacyHandler->PrepareDataForClipboard(aTransferable);
-+ NS_ENSURE_SUCCESS(rv, rv);
-+
-+ // Clear out the clipboard in order to set the new data
-+ EmptyClipboard(aWhichClipboard);
-+
-+ if (aWhichClipboard == kSelectionClipboard) {
-+ mSelectionOwner = aOwner;
-+ mSelectionTransferable = aTransferable;
-+ }
-+ else {
-+ mGlobalOwner = aOwner;
-+ mGlobalTransferable = aTransferable;
-+ }
-+
-+ // Which selection are we about to claim, CLIPBOARD or PRIMARY?
-+ GdkAtom selectionAtom = GetSelectionAtom(aWhichClipboard);
-+
-+ // Make ourselves the owner. If we fail to, return.
-+ if (!gtk_selection_owner_set(mWidget, selectionAtom, GDK_CURRENT_TIME))
-+ return NS_ERROR_FAILURE;
-+
-+ // Clear the old selection target list.
-+ gtk_selection_clear_targets(mWidget, selectionAtom);
-+
-+ // Get the types of supported flavors
-+ nsCOMPtr<nsISupportsArray> flavors;
-+
-+ rv = aTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavors));
-+ if (!flavors || NS_FAILED(rv))
-+ return NS_ERROR_FAILURE;
-+
-+ // Add all the flavors to this widget's supported type.
-+ PRUint32 count;
-+ flavors->Count(&count);
-+ for (PRUint32 i=0; i < count; i++) {
-+ nsCOMPtr<nsISupports> tastesLike;
-+ flavors->GetElementAt(i, getter_AddRefs(tastesLike));
-+ nsCOMPtr<nsISupportsCString> flavor = do_QueryInterface(tastesLike);
-+
-+ if (flavor) {
-+ nsXPIDLCString flavorStr;
-+ flavor->ToString(getter_Copies(flavorStr));
-+
-+ // special case text/unicode since we can handle all of
-+ // the string types
-+ if (!strcmp(flavorStr, kUnicodeMime)) {
-+ AddTarget(gdk_atom_intern("UTF8_STRING", FALSE),
-+ selectionAtom);
-+ AddTarget(gdk_atom_intern("COMPOUND_TEXT", FALSE),
-+ selectionAtom);
-+ AddTarget(gdk_atom_intern("TEXT", FALSE), selectionAtom);
-+ AddTarget(GDK_SELECTION_TYPE_STRING, selectionAtom);
-+ // next loop iteration
-+ continue;
-+ }
-+
-+ // very special case for this one. since our selection mechanism doesn't work for images,
-+ // we must use GTK's clipboard utility functions
-+ if (!strcmp(flavorStr, kNativeImageMime) || !strcmp(flavorStr, kPNGImageMime) ||
-+ !strcmp(flavorStr, kJPEGImageMime) || !strcmp(flavorStr, kGIFImageMime)) {
-+ nsCOMPtr<nsISupports> item;
-+ PRUint32 len;
-+ rv = aTransferable->GetTransferData(flavorStr, getter_AddRefs(item), &len);
-+ nsCOMPtr<nsISupportsInterfacePointer> ptrPrimitive(do_QueryInterface(item));
-+ if (!ptrPrimitive)
-+ continue;
-+
-+ nsCOMPtr<nsISupports> primitiveData;
-+ ptrPrimitive->GetData(getter_AddRefs(primitiveData));
-+ nsCOMPtr<nsIImage> image(do_QueryInterface(primitiveData));
-+ if (!image) // Not getting an image for an image mime type!?
-+ continue;
-+
-+ if (NS_FAILED(image->LockImagePixels(PR_FALSE)))
-+ continue;
-+ GdkPixbuf* pixbuf = nsImageToPixbuf::ImageToPixbuf(image);
-+ if (!pixbuf) {
-+ image->UnlockImagePixels(PR_FALSE);
-+ continue;
-+ }
-+
-+ GtkClipboard *aClipboard = gtk_clipboard_get(GetSelectionAtom(aWhichClipboard));
-+ gtk_clipboard_set_image(aClipboard, pixbuf);
-+ g_object_unref(pixbuf);
-+ image->UnlockImagePixels(PR_FALSE);
-+ continue;
-+ }
-+
-+ // Add this to our list of valid targets
-+ GdkAtom atom = gdk_atom_intern(flavorStr, FALSE);
-+ AddTarget(atom, selectionAtom);
-+ }
-+ }
-+
-+ return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsClipboard::GetData(nsITransferable *aTransferable, PRInt32 aWhichClipboard)
-+{
-+ if (!aTransferable)
-+ return NS_ERROR_FAILURE;
-+
-+ GtkClipboard *clipboard;
-+ clipboard = gtk_clipboard_get(GetSelectionAtom(aWhichClipboard));
-+
-+ guchar *data = NULL;
-+ gint length = 0;
-+ PRBool foundData = PR_FALSE;
-+ nsCAutoString foundFlavor;
-+
-+ // Get a list of flavors this transferable can import
-+ nsCOMPtr<nsISupportsArray> flavors;
-+ nsresult rv;
-+ rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavors));
-+ if (!flavors || NS_FAILED(rv))
-+ return NS_ERROR_FAILURE;
-+
-+ PRUint32 count;
-+ flavors->Count(&count);
-+ for (PRUint32 i=0; i < count; i++) {
-+ nsCOMPtr<nsISupports> genericFlavor;
-+ flavors->GetElementAt(i, getter_AddRefs(genericFlavor));
-+
-+ nsCOMPtr<nsISupportsCString> currentFlavor;
-+ currentFlavor = do_QueryInterface(genericFlavor);
-+
-+ if (currentFlavor) {
-+ nsXPIDLCString flavorStr;
-+ currentFlavor->ToString(getter_Copies(flavorStr));
-+
-+ // Special case text/unicode since we can convert any
-+ // string into text/unicode
-+ if (!strcmp(flavorStr, kUnicodeMime)) {
-+ gchar* new_text = wait_for_text(clipboard);
-+ if (new_text) {
-+ // Convert utf-8 into our unicode format.
-+ NS_ConvertUTF8toUTF16 ucs2string(new_text);
-+ data = (guchar *)ToNewUnicode(ucs2string);
-+ length = ucs2string.Length() * 2;
-+ g_free(new_text);
-+ foundData = PR_TRUE;
-+ foundFlavor = kUnicodeMime;
-+ break;
-+ }
-+ // If the type was text/unicode and we couldn't get
-+ // text off the clipboard, run the next loop
-+ // iteration.
-+ continue;
-+ }
-+
-+ // For images, we must wrap the data in an nsIInputStream then return instead of break,
-+ // because that code below won't help us.
-+ if (!strcmp(flavorStr, kJPEGImageMime) || !strcmp(flavorStr, kPNGImageMime) || !strcmp(flavorStr, kGIFImageMime)) {
-+ GdkAtom atom;
-+ if (!strcmp(flavorStr, kJPEGImageMime)) // This is image/jpg, but X only understands image/jpeg
-+ atom = gdk_atom_intern("image/jpeg", FALSE);
-+ else
-+ atom = gdk_atom_intern(flavorStr, FALSE);
-+
-+ GtkSelectionData *selectionData = wait_for_contents(clipboard, atom);
-+ if (!selectionData)
-+ continue;
-+
-+ nsCOMPtr<nsIInputStream> byteStream;
-+ NS_NewByteInputStream(getter_AddRefs(byteStream), (const char*)selectionData->data,
-+ selectionData->length, NS_ASSIGNMENT_COPY);
-+ aTransferable->SetTransferData(flavorStr, byteStream, sizeof(nsIInputStream*));
-+ gtk_selection_data_free(selectionData);
-+ return NS_OK;
-+ }
-+
-+ // Get the atom for this type and try to request it off
-+ // the clipboard.
-+ GdkAtom atom = gdk_atom_intern(flavorStr, FALSE);
-+ GtkSelectionData *selectionData;
-+ selectionData = wait_for_contents(clipboard, atom);
-+ if (selectionData) {
-+ length = selectionData->length;
-+ // Special case text/html since we can convert into UCS2
-+ if (!strcmp(flavorStr, kHTMLMime)) {
-+ PRUnichar* htmlBody= nsnull;
-+ PRInt32 htmlBodyLen = 0;
-+ // Convert text/html into our unicode format
-+ ConvertHTMLtoUCS2((guchar *)selectionData->data, length,
-+ &htmlBody, htmlBodyLen);
-+ if (!htmlBodyLen)
-+ break;
-+ data = (guchar *)htmlBody;
-+ length = htmlBodyLen * 2;
-+ } else {
-+ data = (guchar *)nsMemory::Alloc(length);
-+ if (!data)
-+ break;
-+ memcpy(data, selectionData->data, length);
-+ }
-+ foundData = PR_TRUE;
-+ foundFlavor = flavorStr;
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (foundData) {
-+ nsCOMPtr<nsISupports> wrapper;
-+ nsPrimitiveHelpers::CreatePrimitiveForData(foundFlavor.get(),
-+ data, length,
-+ getter_AddRefs(wrapper));
-+ aTransferable->SetTransferData(foundFlavor.get(),
-+ wrapper, length);
-+ }
-+
-+ if (data)
-+ nsMemory::Free(data);
-+
-+ return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsClipboard::EmptyClipboard(PRInt32 aWhichClipboard)
-+{
-+ if (aWhichClipboard == kSelectionClipboard) {
-+ if (mSelectionOwner) {
-+ mSelectionOwner->LosingOwnership(mSelectionTransferable);
-+ mSelectionOwner = nsnull;
-+ }
-+ mSelectionTransferable = nsnull;
-+ }
-+ else {
-+ if (mGlobalOwner) {
-+ mGlobalOwner->LosingOwnership(mGlobalTransferable);
-+ mGlobalOwner = nsnull;
-+ }
-+ mGlobalTransferable = nsnull;
-+ }
-+
-+ return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsClipboard::HasDataMatchingFlavors(const char** aFlavorList, PRUint32 aLength,
-+ PRInt32 aWhichClipboard, PRBool *_retval)
-+{
-+ if (!aFlavorList || !_retval)
-+ return NS_ERROR_NULL_POINTER;
-+
-+ *_retval = PR_FALSE;
-+
-+ GtkSelectionData *selection_data =
-+ GetTargets(GetSelectionAtom(aWhichClipboard));
-+ if (!selection_data)
-+ return NS_OK;
-+
-+ gint n_targets = 0;
-+ GdkAtom *targets = NULL;
-+
-+ if (!gtk_selection_data_get_targets(selection_data,
-+ &targets, &n_targets) ||
-+ !n_targets)
-+ return NS_OK;
-+
-+ // Walk through the provided types and try to match it to a
-+ // provided type.
-+ for (PRUint32 i = 0; i < aLength && !*_retval; i++) {
-+ // We special case text/unicode here.
-+ if (!strcmp(aFlavorList[i], kUnicodeMime) &&
-+ gtk_selection_data_targets_include_text(selection_data)) {
-+ *_retval = PR_TRUE;
-+ break;
-+ }
-+
-+ for (PRInt32 j = 0; j < n_targets; j++) {
-+ gchar *atom_name = gdk_atom_name(targets[j]);
-+ if (!strcmp(atom_name, aFlavorList[i]))
-+ *_retval = PR_TRUE;
-+
-+ // X clipboard wants image/jpeg, not image/jpg
-+ if (!strcmp(aFlavorList[i], kJPEGImageMime) && !strcmp(atom_name, "image/jpeg"))
-+ *_retval = PR_TRUE;
-+
-+ g_free(atom_name);
-+
-+ if (*_retval)
-+ break;
-+ }
-+ }
-+ gtk_selection_data_free(selection_data);
-+ g_free(targets);
-+
-+ return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsClipboard::SupportsSelectionClipboard(PRBool *_retval)
-+{
-+ *_retval = PR_TRUE; // yeah, unix supports the selection clipboard
-+ return NS_OK;
-+}
-+
-+/* static */
-+GdkAtom
-+nsClipboard::GetSelectionAtom(PRInt32 aWhichClipboard)
-+{
-+ if (aWhichClipboard == kGlobalClipboard)
-+ return GDK_SELECTION_CLIPBOARD;
-+
-+ return GDK_SELECTION_PRIMARY;
-+}
-+
-+/* static */
-+GtkSelectionData *
-+nsClipboard::GetTargets(GdkAtom aWhichClipboard)
-+{
-+ GtkClipboard *clipboard = gtk_clipboard_get(aWhichClipboard);
-+ return wait_for_contents(clipboard, gdk_atom_intern("TARGETS", FALSE));
-+}
-+
-+nsITransferable *
-+nsClipboard::GetTransferable(PRInt32 aWhichClipboard)
-+{
-+ nsITransferable *retval;
-+
-+ if (aWhichClipboard == kSelectionClipboard)
-+ retval = mSelectionTransferable.get();
-+ else
-+ retval = mGlobalTransferable.get();
-+
-+ return retval;
-+}
-+
-+void
-+nsClipboard::AddTarget(GdkAtom aName, GdkAtom aClipboard)
-+{
-+ gtk_selection_add_target(mWidget, aClipboard, aName, 0);
-+}
-+
-+void
-+nsClipboard::SelectionGetEvent (GtkWidget *aWidget,
-+ GtkSelectionData *aSelectionData,
-+ guint aTime)
-+{
-+ // Someone has asked us to hand them something. The first thing
-+ // that we want to do is see if that something includes text. If
-+ // it does, try to give it text/unicode after converting it to
-+ // utf-8.
-+
-+ PRInt32 whichClipboard;
-+
-+ // which clipboard?
-+ if (aSelectionData->selection == GDK_SELECTION_PRIMARY)
-+ whichClipboard = kSelectionClipboard;
-+ else if (aSelectionData->selection == GDK_SELECTION_CLIPBOARD)
-+ whichClipboard = kGlobalClipboard;
-+ else
-+ return; // THAT AIN'T NO CLIPBOARD I EVER HEARD OF
-+
-+ nsCOMPtr<nsITransferable> trans = GetTransferable(whichClipboard);
-+
-+ nsresult rv;
-+ nsCOMPtr<nsISupports> item;
-+ PRUint32 len;
-+
-+ // Check to see if the selection data includes any of the string
-+ // types that we support.
-+ if (aSelectionData->target == gdk_atom_intern ("STRING", FALSE) ||
-+ aSelectionData->target == gdk_atom_intern ("TEXT", FALSE) ||
-+ aSelectionData->target == gdk_atom_intern ("COMPOUND_TEXT", FALSE) ||
-+ aSelectionData->target == gdk_atom_intern ("UTF8_STRING", FALSE)) {
-+ // Try to convert our internal type into a text string. Get
-+ // the transferable for this clipboard and try to get the
-+ // text/unicode type for it.
-+ rv = trans->GetTransferData("text/unicode", getter_AddRefs(item),
-+ &len);
-+ if (!item || NS_FAILED(rv))
-+ return;
-+
-+ nsCOMPtr<nsISupportsString> wideString;
-+ wideString = do_QueryInterface(item);
-+ if (!wideString)
-+ return;
-+
-+ nsAutoString ucs2string;
-+ wideString->GetData(ucs2string);
-+ char *utf8string = ToNewUTF8String(ucs2string);
-+ if (!utf8string)
-+ return;
-+
-+ gtk_selection_data_set_text (aSelectionData, utf8string,
-+ strlen(utf8string));
-+
-+ nsMemory::Free(utf8string);
-+ return;
-+ }
-+
-+ // Try to match up the selection data target to something our
-+ // transferable provides.
-+ gchar *target_name = gdk_atom_name(aSelectionData->target);
-+ if (!target_name)
-+ return;
-+
-+ rv = trans->GetTransferData(target_name, getter_AddRefs(item), &len);
-+ // nothing found?
-+ if (!item || NS_FAILED(rv)) {
-+ g_free(target_name);
-+ return;
-+ }
-+
-+ void *primitive_data = nsnull;
-+ nsPrimitiveHelpers::CreateDataFromPrimitive(target_name, item,
-+ &primitive_data, len);
-+
-+ if (primitive_data) {
-+ // Check to see if the selection data is text/html
-+ if (aSelectionData->target == gdk_atom_intern (kHTMLMime, FALSE)) {
-+ /*
-+ * "text/html" can be encoded UCS2. It is recommended that
-+ * documents transmitted as UCS2 always begin with a ZERO-WIDTH
-+ * NON-BREAKING SPACE character (hexadecimal FEFF, also called
-+ * Byte Order Mark (BOM)). Adding BOM can help other app to
-+ * detect mozilla use UCS2 encoding when copy-paste.
-+ */
-+ guchar *buffer = (guchar *)
-+ nsMemory::Alloc((len * sizeof(guchar)) + sizeof(PRUnichar));
-+ if (!buffer)
-+ return;
-+ PRUnichar prefix = 0xFEFF;
-+ memcpy(buffer, &prefix, sizeof(prefix));
-+ memcpy(buffer + sizeof(prefix), primitive_data, len);
-+ nsMemory::Free((guchar *)primitive_data);
-+ primitive_data = (guchar *)buffer;
-+ len += sizeof(prefix);
-+ }
-+
-+ gtk_selection_data_set(aSelectionData, aSelectionData->target,
-+ 8, /* 8 bits in a unit */
-+ (const guchar *)primitive_data, len);
-+ nsMemory::Free(primitive_data);
-+ }
-+
-+ g_free(target_name);
-+
-+}
-+
-+void
-+nsClipboard::SelectionClearEvent (GtkWidget *aWidget,
-+ GdkEventSelection *aEvent)
-+{
-+ PRInt32 whichClipboard;
-+
-+ // which clipboard?
-+ if (aEvent->selection == GDK_SELECTION_PRIMARY)
-+ whichClipboard = kSelectionClipboard;
-+ else if (aEvent->selection == GDK_SELECTION_CLIPBOARD)
-+ whichClipboard = kGlobalClipboard;
-+ else
-+ return; // THAT AIN'T NO CLIPBOARD I EVER HEARD OF
-+
-+ EmptyClipboard(whichClipboard);
-+}
-+
-+void
-+invisible_selection_get_cb (GtkWidget *aWidget,
-+ GtkSelectionData *aSelectionData,
-+ guint aTime,
-+ guint aInfo,
-+ nsClipboard *aClipboard)
-+{
-+ aClipboard->SelectionGetEvent(aWidget, aSelectionData, aTime);
-+}
-+
-+gboolean
-+selection_clear_event_cb (GtkWidget *aWidget,
-+ GdkEventSelection *aEvent,
-+ nsClipboard *aClipboard)
-+{
-+ aClipboard->SelectionClearEvent(aWidget, aEvent);
-+ return TRUE;
-+}
-+
-+/*
-+ * when copy-paste, mozilla wants data encoded using UCS2,
-+ * other app such as StarOffice use "text/html"(RFC2854).
-+ * This function convert data(got from GTK clipboard)
-+ * to data mozilla wanted.
-+ *
-+ * data from GTK clipboard can be 3 forms:
-+ * 1. From current mozilla
-+ * "text/html", charset = utf-16
-+ * 2. From old version mozilla or mozilla-based app
-+ * content("body" only), charset = utf-16
-+ * 3. From other app who use "text/html" when copy-paste
-+ * "text/html", has "charset" info
-+ *
-+ * data : got from GTK clipboard
-+ * dataLength: got from GTK clipboard
-+ * body : pass to Mozilla
-+ * bodyLength: pass to Mozilla
-+ */
-+void ConvertHTMLtoUCS2(guchar * data, PRInt32 dataLength,
-+ PRUnichar** unicodeData, PRInt32& outUnicodeLen)
-+{
-+ nsCAutoString charset;
-+ GetHTMLCharset(data, dataLength, charset);// get charset of HTML
-+ if (charset.EqualsLiteral("UTF-16")) {//current mozilla
-+ outUnicodeLen = (dataLength / 2) - 1;
-+ *unicodeData = reinterpret_cast<PRUnichar*>
-+ (nsMemory::Alloc((outUnicodeLen + sizeof('\0')) *
-+ sizeof(PRUnichar)));
-+ if (*unicodeData) {
-+ memcpy(*unicodeData, data + sizeof(PRUnichar),
-+ outUnicodeLen * sizeof(PRUnichar));
-+ (*unicodeData)[outUnicodeLen] = '\0';
-+ }
-+ } else if (charset.EqualsLiteral("UNKNOWN")) {
-+ outUnicodeLen = 0;
-+ return;
-+ } else {
-+ // app which use "text/html" to copy&paste
-+ nsCOMPtr<nsIUnicodeDecoder> decoder;
-+ nsresult rv;
-+ // get the decoder
-+ nsCOMPtr<nsICharsetConverterManager> ccm =
-+ do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
-+ if (NS_FAILED(rv)) {
-+#ifdef DEBUG_CLIPBOARD
-+ g_print(" can't get CHARSET CONVERTER MANAGER service\n");
-+#endif
-+ outUnicodeLen = 0;
-+ return;
-+ }
-+ rv = ccm->GetUnicodeDecoder(charset.get(), getter_AddRefs(decoder));
-+ if (NS_FAILED(rv)) {
-+#ifdef DEBUG_CLIPBOARD
-+ g_print(" get unicode decoder error\n");
-+#endif
-+ outUnicodeLen = 0;
-+ return;
-+ }
-+ // converting
-+ decoder->GetMaxLength((const char *)data, dataLength, &outUnicodeLen);
-+ // |outUnicodeLen| is number of chars
-+ if (outUnicodeLen) {
-+ *unicodeData = reinterpret_cast<PRUnichar*>
-+ (nsMemory::Alloc((outUnicodeLen + sizeof('\0')) *
-+ sizeof(PRUnichar)));
-+ if (*unicodeData) {
-+ PRInt32 numberTmp = dataLength;
-+ decoder->Convert((const char *)data, &numberTmp,
-+ *unicodeData, &outUnicodeLen);
-+#ifdef DEBUG_CLIPBOARD
-+ if (numberTmp != dataLength)
-+ printf("didn't consume all the bytes\n");
-+#endif
-+ // null terminate. Convert() doesn't do it for us
-+ (*unicodeData)[outUnicodeLen] = '\0';
-+ }
-+ } // if valid length
-+ }
-+}
-+
-+/*
-+ * get "charset" information from clipboard data
-+ * return value can be:
-+ * 1. "UTF-16": mozilla or "text/html" with "charset=utf-16"
-+ * 2. "UNKNOWN": mozilla can't detect what encode it use
-+ * 3. other: "text/html" with other charset than utf-16
-+ */
-+void GetHTMLCharset(guchar * data, PRInt32 dataLength, nsCString& str)
-+{
-+ // if detect "FFFE" or "FEFF", assume UTF-16
-+ PRUnichar* beginChar = (PRUnichar*)data;
-+ if ((beginChar[0] == 0xFFFE) || (beginChar[0] == 0xFEFF)) {
-+ str.AssignLiteral("UTF-16");
-+ return;
-+ }
-+ // no "FFFE" and "FEFF", assume ASCII first to find "charset" info
-+ const nsDependentCString htmlStr((const char *)data, dataLength);
-+ nsACString::const_iterator start, end;
-+ htmlStr.BeginReading(start);
-+ htmlStr.EndReading(end);
-+ nsACString::const_iterator valueStart(start), valueEnd(start);
-+
-+ if (CaseInsensitiveFindInReadable(
-+ NS_LITERAL_CSTRING("CONTENT=\"text/html;"),
-+ start, end)) {
-+ start = end;
-+ htmlStr.EndReading(end);
-+
-+ if (CaseInsensitiveFindInReadable(
-+ NS_LITERAL_CSTRING("charset="),
-+ start, end)) {
-+ valueStart = end;
-+ start = end;
-+ htmlStr.EndReading(end);
-+
-+ if (FindCharInReadable('"', start, end))
-+ valueEnd = start;
-+ }
-+ }
-+ // find "charset" in HTML
-+ if (valueStart != valueEnd) {
-+ str = Substring(valueStart, valueEnd);
-+ ToUpperCase(str);
-+#ifdef DEBUG_CLIPBOARD
-+ printf("Charset of HTML = %s\n", charsetUpperStr.get());
-+#endif
-+ return;
-+ }
-+ str.AssignLiteral("UNKNOWN");
-+}
-+
-+static void
-+DispatchSelectionNotifyEvent(GtkWidget *widget, XEvent *xevent)
-+{
-+ GdkEvent event;
-+ event.selection.type = GDK_SELECTION_NOTIFY;
-+ event.selection.window = widget->window;
-+ event.selection.selection = gdk_x11_xatom_to_atom(xevent->xselection.selection);
-+ event.selection.target = gdk_x11_xatom_to_atom(xevent->xselection.target);
-+ event.selection.property = gdk_x11_xatom_to_atom(xevent->xselection.property);
-+ event.selection.time = xevent->xselection.time;
-+
-+ gtk_widget_event(widget, &event);
-+}
-+
-+static void
-+DispatchPropertyNotifyEvent(GtkWidget *widget, XEvent *xevent)
-+{
-+ if (((GdkWindowObject *) widget->window)->event_mask & GDK_PROPERTY_CHANGE_MASK) {
-+ GdkEvent event;
-+ event.property.type = GDK_PROPERTY_NOTIFY;
-+ event.property.window = widget->window;
-+ event.property.atom = gdk_x11_xatom_to_atom(xevent->xproperty.atom);
-+ event.property.time = xevent->xproperty.time;
-+ event.property.state = xevent->xproperty.state;
-+
-+ gtk_widget_event(widget, &event);
-+ }
-+}
-+
-+struct checkEventContext
-+{
-+ GtkWidget *cbWidget;
-+ Atom selAtom;
-+};
-+
-+static Bool
-+checkEventProc(Display *display, XEvent *event, XPointer arg)
-+{
-+ checkEventContext *context = (checkEventContext *) arg;
-+
-+ if (event->xany.type == SelectionNotify ||
-+ (event->xany.type == PropertyNotify &&
-+ event->xproperty.atom == context->selAtom)) {
-+
-+ GdkWindow *cbWindow = gdk_window_lookup(event->xany.window);
-+ if (cbWindow) {
-+ GtkWidget *cbWidget = NULL;
-+ gdk_window_get_user_data(cbWindow, (gpointer *)&cbWidget);
-+ if (cbWidget && GTK_IS_WIDGET(cbWidget)) {
-+ context->cbWidget = cbWidget;
-+ return True;
-+ }
-+ }
-+ }
-+
-+ return False;
-+}
-+
-+// Idle timeout for receiving selection and property notify events (microsec)
-+static const int kClipboardTimeout = 500000;
-+
-+static void
-+wait_for_retrieval(GtkClipboard *clipboard, retrieval_context *r_context)
-+{
-+ if (r_context->completed) // the request completed synchronously
-+ return;
-+
-+ Display *xDisplay = GDK_DISPLAY();
-+ checkEventContext context;
-+ context.cbWidget = NULL;
-+ context.selAtom = gdk_x11_atom_to_xatom(gdk_atom_intern("GDK_SELECTION",
-+ FALSE));
-+
-+ // Send X events which are relevant to the ongoing selection retrieval
-+ // to the clipboard widget. Wait until either the operation completes, or
-+ // we hit our timeout. All other X events remain queued.
-+
-+ int select_result;
-+
-+#ifdef POLL_WITH_XCONNECTIONNUMBER
-+ struct pollfd fds[1];
-+ fds[0].fd = XConnectionNumber(xDisplay);
-+ fds[0].events = POLLIN;
-+#else
-+ int cnumber = ConnectionNumber(xDisplay);
-+ fd_set select_set;
-+ FD_ZERO(&select_set);
-+ FD_SET(cnumber, &select_set);
-+ ++cnumber;
-+ struct timeval tv;
-+#endif
-+
-+ do {
-+ XEvent xevent;
-+
-+ while (XCheckIfEvent(xDisplay, &xevent, checkEventProc,
-+ (XPointer) &context)) {
-+
-+ if (xevent.xany.type == SelectionNotify)
-+ DispatchSelectionNotifyEvent(context.cbWidget, &xevent);
-+ else
-+ DispatchPropertyNotifyEvent(context.cbWidget, &xevent);
-+
-+ if (r_context->completed)
-+ return;
-+ }
-+
-+#ifdef POLL_WITH_XCONNECTIONNUMBER
-+ select_result = poll(fds, 1, kClipboardTimeout / 1000);
-+#else
-+ tv.tv_sec = 0;
-+ tv.tv_usec = kClipboardTimeout;
-+ select_result = select(cnumber, &select_set, NULL, NULL, &tv);
-+#endif
-+ } while (select_result == 1);
-+
-+#ifdef DEBUG_CLIPBOARD
-+ printf("exceeded clipboard timeout\n");
-+#endif
-+}
-+
-+static void
-+clipboard_contents_received(GtkClipboard *clipboard,
-+ GtkSelectionData *selection_data,
-+ gpointer data)
-+{
-+ retrieval_context *context = static_cast<retrieval_context *>(data);
-+ context->completed = PR_TRUE;
-+
-+ if (selection_data->length >= 0)
-+ context->data = gtk_selection_data_copy(selection_data);
-+}
-+
-+
-+static GtkSelectionData *
-+wait_for_contents(GtkClipboard *clipboard, GdkAtom target)
-+{
-+ retrieval_context context;
-+ gtk_clipboard_request_contents(clipboard, target,
-+ clipboard_contents_received,
-+ &context);
-+
-+ wait_for_retrieval(clipboard, &context);
-+ return static_cast<GtkSelectionData *>(context.data);
-+}
-+
-+static void
-+clipboard_text_received(GtkClipboard *clipboard,
-+ const gchar *text,
-+ gpointer data)
-+{
-+ retrieval_context *context = static_cast<retrieval_context *>(data);
-+ context->completed = PR_TRUE;
-+ context->data = g_strdup(text);
-+}
-+
-+static gchar *
-+wait_for_text(GtkClipboard *clipboard)
-+{
-+ retrieval_context context;
-+ gtk_clipboard_request_text(clipboard, clipboard_text_received, &context);
-+
-+ wait_for_retrieval(clipboard, &context);
-+ return static_cast<gchar *>(context.data);
-+}
-Index: offscreen/widget/src/headless/nsClipboard.h
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ offscreen/widget/src/headless/nsClipboard.h 2009-06-12 14:14:05.000000000 +0100
-@@ -0,0 +1,93 @@
-+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-+/* vim:expandtab:shiftwidth=4:tabstop=4:
-+ */
-+/* ***** BEGIN LICENSE BLOCK *****
-+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
-+ *
-+ * The contents of this file are subject to the Mozilla Public License Version
-+ * 1.1 (the "License"); you may not use this file except in compliance with
-+ * the License. You may obtain a copy of the License at
-+ * http://www.mozilla.org/MPL/
-+ *
-+ * Software distributed under the License is distributed on an "AS IS" basis,
-+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-+ * for the specific language governing rights and limitations under the
-+ * License.
-+ *
-+ * The Original Code is mozilla.org code.
-+ *
-+ * The Initial Developer of the Original Code is Christopher Blizzard
-+ * <blizzard@mozilla.org>. Portions created by the Initial Developer
-+ * are Copyright (C) 2001 the Initial Developer. All Rights Reserved.
-+ *
-+ * Contributor(s):
-+ *
-+ * Alternatively, the contents of this file may be used under the terms of
-+ * either the GNU General Public License Version 2 or later (the "GPL"), or
-+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-+ * in which case the provisions of the GPL or the LGPL are applicable instead
-+ * of those above. If you wish to allow use of your version of this file only
-+ * under the terms of either the GPL or the LGPL, and not to allow others to
-+ * use your version of this file under the terms of the MPL, indicate your
-+ * decision by deleting the provisions above and replace them with the notice
-+ * 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 ***** */
-+
-+#ifndef __nsClipboard_h_
-+#define __nsClipboard_h_
-+
-+#include "nsIClipboard.h"
-+#include "nsClipboardPrivacyHandler.h"
-+#include "nsAutoPtr.h"
-+#include <gtk/gtk.h>
-+
-+class nsClipboard : public nsIClipboard
-+{
-+public:
-+ nsClipboard();
-+ virtual ~nsClipboard();
-+
-+ NS_DECL_ISUPPORTS
-+
-+ NS_DECL_NSICLIPBOARD
-+
-+ // Make sure we are initialized, called from the factory
-+ // constructor
-+ nsresult Init (void);
-+ // Someone requested the selection from the hidden widget
-+ void SelectionGetEvent (GtkWidget *aWidget,
-+ GtkSelectionData *aSelectionData,
-+ guint aTime);
-+ void SelectionClearEvent (GtkWidget *aWidget,
-+ GdkEventSelection *aEvent);
-+
-+
-+private:
-+ // Utility methods
-+ static GdkAtom GetSelectionAtom (PRInt32 aWhichClipboard);
-+ static GtkSelectionData *GetTargets (GdkAtom aWhichClipboard);
-+
-+ // Get our hands on the correct transferable, given a specific
-+ // clipboard
-+ nsITransferable *GetTransferable (PRInt32 aWhichClipboard);
-+
-+ // Add a target type to the hidden widget
-+ void AddTarget (GdkAtom aName,
-+ GdkAtom aClipboard);
-+
-+ // The hidden widget where we do all of our operations
-+ GtkWidget *mWidget;
-+ // Hang on to our owners and transferables so we can transfer data
-+ // when asked.
-+ nsCOMPtr<nsIClipboardOwner> mSelectionOwner;
-+ nsCOMPtr<nsIClipboardOwner> mGlobalOwner;
-+ nsCOMPtr<nsITransferable> mSelectionTransferable;
-+ nsCOMPtr<nsITransferable> mGlobalTransferable;
-+ nsRefPtr<nsClipboardPrivacyHandler> mPrivacyHandler;
-+
-+};
-+
-+#endif /* __nsClipboard_h_ */
-Index: offscreen/widget/src/headless/nsIImageToPixbuf.h
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ offscreen/widget/src/headless/nsIImageToPixbuf.h 2009-06-12 14:14:05.000000000 +0100
-@@ -0,0 +1,62 @@
-+/* ***** BEGIN LICENSE BLOCK *****
-+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
-+ *
-+ * The contents of this file are subject to the Mozilla Public License Version
-+ * 1.1 (the "License"); you may not use this file except in compliance with
-+ * the License. You may obtain a copy of the License at
-+ * http://www.mozilla.org/MPL/
-+ *
-+ * Software distributed under the License is distributed on an "AS IS" basis,
-+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-+ * for the specific language governing rights and limitations under the
-+ * License.
-+ *
-+ * The Original Code is mozilla.org widget code.
-+ *
-+ * The Initial Developer of the Original Code is
-+ * Christian Biesinger <cbiesinger@web.de>.
-+ * Portions created by the Initial Developer are Copyright (C) 2006
-+ * the Initial Developer. All Rights Reserved.
-+ *
-+ * Contributor(s):
-+ *
-+ * Alternatively, the contents of this file may be used under the terms of
-+ * either the GNU General Public License Version 2 or later (the "GPL"), or
-+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-+ * in which case the provisions of the GPL or the LGPL are applicable instead
-+ * of those above. If you wish to allow use of your version of this file only
-+ * under the terms of either the GPL or the LGPL, and not to allow others to
-+ * use your version of this file under the terms of the MPL, indicate your
-+ * decision by deleting the provisions above and replace them with the notice
-+ * 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 ***** */
-+
-+#ifndef NSIIMAGETOPIXBUF_H_
-+#define NSIIMAGETOPIXBUF_H_
-+
-+#include "nsISupports.h"
-+
-+// dfa4ac93-83f2-4ab8-9b2a-0ff7022aebe2
-+#define NSIIMAGETOPIXBUF_IID \
-+{ 0xdfa4ac93, 0x83f2, 0x4ab8, \
-+ { 0x9b, 0x2a, 0x0f, 0xf7, 0x02, 0x2a, 0xeb, 0xe2 } }
-+
-+class nsIImage;
-+typedef struct _GdkPixbuf GdkPixbuf;
-+
-+/**
-+ * An interface that allows converting an nsIImage to a GdkPixbuf*.
-+ */
-+class nsIImageToPixbuf : public nsISupports {
-+ public:
-+ NS_DECLARE_STATIC_IID_ACCESSOR(NSIIMAGETOPIXBUF_IID)
-+
-+ NS_IMETHOD_(GdkPixbuf*) ConvertImageToPixbuf(nsIImage* aImage) = 0;
-+};
-+
-+NS_DEFINE_STATIC_IID_ACCESSOR(nsIImageToPixbuf, NSIIMAGETOPIXBUF_IID)
-+
-+#endif
-Index: offscreen/widget/src/headless/nsImageToPixbuf.cpp
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ offscreen/widget/src/headless/nsImageToPixbuf.cpp 2009-06-12 14:14:05.000000000 +0100
-@@ -0,0 +1,196 @@
-+/* vim:set sw=4 sts=4 et cin: */
-+/* ***** BEGIN LICENSE BLOCK *****
-+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
-+ *
-+ * The contents of this file are subject to the Mozilla Public License Version
-+ * 1.1 (the "License"); you may not use this file except in compliance with
-+ * the License. You may obtain a copy of the License at
-+ * http://www.mozilla.org/MPL/
-+ *
-+ * Software distributed under the License is distributed on an "AS IS" basis,
-+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-+ * for the specific language governing rights and limitations under the
-+ * License.
-+ *
-+ * The Original Code is mozilla.org widget code.
-+ *
-+ * The Initial Developer of the Original Code is
-+ * Christian Biesinger <cbiesinger@web.de>.
-+ * Portions created by the Initial Developer are Copyright (C) 2006
-+ * the Initial Developer. All Rights Reserved.
-+ *
-+ * Contributor(s):
-+ *
-+ * Alternatively, the contents of this file may be used under the terms of
-+ * either the GNU General Public License Version 2 or later (the "GPL"), or
-+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-+ * in which case the provisions of the GPL or the LGPL are applicable instead
-+ * of those above. If you wish to allow use of your version of this file only
-+ * under the terms of either the GPL or the LGPL, and not to allow others to
-+ * use your version of this file under the terms of the MPL, indicate your
-+ * decision by deleting the provisions above and replace them with the notice
-+ * 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 <gdk-pixbuf/gdk-pixbuf.h>
-+
-+#include "gfxASurface.h"
-+#include "gfxImageSurface.h"
-+#include "gfxContext.h"
-+
-+#include "nsIImage.h"
-+
-+#include "nsAutoPtr.h"
-+
-+#include "nsImageToPixbuf.h"
-+
-+NS_IMPL_ISUPPORTS1(nsImageToPixbuf, nsIImageToPixbuf)
-+
-+inline unsigned char
-+unpremultiply (unsigned char color,
-+ unsigned char alpha)
-+{
-+ if (alpha == 0)
-+ return 0;
-+ // plus alpha/2 to round instead of truncate
-+ return (color * 255 + alpha / 2) / alpha;
-+}
-+
-+NS_IMETHODIMP_(GdkPixbuf*)
-+nsImageToPixbuf::ConvertImageToPixbuf(nsIImage* aImage)
-+{
-+ return ImageToPixbuf(aImage);
-+}
-+
-+GdkPixbuf*
-+nsImageToPixbuf::ImageToPixbuf(nsIImage* aImage)
-+{
-+ PRInt32 width = aImage->GetWidth(),
-+ height = aImage->GetHeight();
-+
-+ nsRefPtr<gfxPattern> pattern;
-+ aImage->GetPattern(getter_AddRefs(pattern));
-+
-+ return PatternToPixbuf(pattern, width, height);
-+}
-+
-+GdkPixbuf*
-+nsImageToPixbuf::ImgSurfaceToPixbuf(gfxImageSurface* aImgSurface, PRInt32 aWidth, PRInt32 aHeight)
-+{
-+ GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, PR_TRUE, 8,
-+ aWidth, aHeight);
-+ if (!pixbuf)
-+ return nsnull;
-+
-+ PRUint32 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-+ guchar* pixels = gdk_pixbuf_get_pixels (pixbuf);
-+
-+ long cairoStride = aImgSurface->Stride();
-+ unsigned char* cairoData = aImgSurface->Data();
-+
-+ gfxASurface::gfxImageFormat format = aImgSurface->Format();
-+
-+ for (PRInt32 row = 0; row < aHeight; ++row) {
-+ for (PRInt32 col = 0; col < aWidth; ++col) {
-+ guchar* pixel = pixels + row * rowstride + 4 * col;
-+
-+ PRUint32* cairoPixel = reinterpret_cast<PRUint32*>
-+ ((cairoData + row * cairoStride + 4 * col));
-+
-+ if (format == gfxASurface::ImageFormatARGB32) {
-+ const PRUint8 a = (*cairoPixel >> 24) & 0xFF;
-+ const PRUint8 r = unpremultiply((*cairoPixel >> 16) & 0xFF, a);
-+ const PRUint8 g = unpremultiply((*cairoPixel >> 8) & 0xFF, a);
-+ const PRUint8 b = unpremultiply((*cairoPixel >> 0) & 0xFF, a);
-+
-+ *pixel++ = r;
-+ *pixel++ = g;
-+ *pixel++ = b;
-+ *pixel++ = a;
-+ } else {
-+ NS_ASSERTION(format == gfxASurface::ImageFormatRGB24,
-+ "unexpected format");
-+ const PRUint8 r = (*cairoPixel >> 16) & 0xFF;
-+ const PRUint8 g = (*cairoPixel >> 8) & 0xFF;
-+ const PRUint8 b = (*cairoPixel >> 0) & 0xFF;
-+
-+ *pixel++ = r;
-+ *pixel++ = g;
-+ *pixel++ = b;
-+ *pixel++ = 0xFF; // A
-+ }
-+ }
-+ }
-+
-+ return pixbuf;
-+}
-+
-+GdkPixbuf*
-+nsImageToPixbuf::SurfaceToPixbuf(gfxASurface* aSurface, PRInt32 aWidth, PRInt32 aHeight)
-+{
-+ if (aSurface->CairoStatus()) {
-+ NS_ERROR("invalid surface");
-+ return nsnull;
-+ }
-+
-+ nsRefPtr<gfxImageSurface> imgSurface;
-+ if (aSurface->GetType() == gfxASurface::SurfaceTypeImage) {
-+ imgSurface = static_cast<gfxImageSurface*>
-+ (static_cast<gfxASurface*>(aSurface));
-+ } else {
-+ imgSurface = new gfxImageSurface(gfxIntSize(aWidth, aHeight),
-+ gfxImageSurface::ImageFormatARGB32);
-+
-+ if (!imgSurface)
-+ return nsnull;
-+
-+ nsRefPtr<gfxContext> context = new gfxContext(imgSurface);
-+ if (!context)
-+ return nsnull;
-+
-+ context->SetOperator(gfxContext::OPERATOR_SOURCE);
-+ context->SetSource(aSurface);
-+ context->Paint();
-+ }
-+
-+ return ImgSurfaceToPixbuf(imgSurface, aWidth, aHeight);
-+}
-+
-+GdkPixbuf*
-+nsImageToPixbuf::PatternToPixbuf(gfxPattern* aPattern, PRInt32 aWidth, PRInt32 aHeight)
-+{
-+ if (aPattern->CairoStatus()) {
-+ NS_ERROR("invalid pattern");
-+ return nsnull;
-+ }
-+
-+ nsRefPtr<gfxImageSurface> imgSurface;
-+ if (aPattern->GetType() == gfxPattern::PATTERN_SURFACE) {
-+ nsRefPtr<gfxASurface> surface = aPattern->GetSurface();
-+ if (surface->GetType() == gfxASurface::SurfaceTypeImage) {
-+ imgSurface = static_cast<gfxImageSurface*>
-+ (static_cast<gfxASurface*>(surface.get()));
-+ }
-+ }
-+
-+ if (!imgSurface) {
-+ imgSurface = new gfxImageSurface(gfxIntSize(aWidth, aHeight),
-+ gfxImageSurface::ImageFormatARGB32);
-+
-+ if (!imgSurface)
-+ return nsnull;
-+
-+ nsRefPtr<gfxContext> context = new gfxContext(imgSurface);
-+ if (!context)
-+ return nsnull;
-+
-+ context->SetOperator(gfxContext::OPERATOR_SOURCE);
-+ context->SetPattern(aPattern);
-+ context->Paint();
-+ }
-+
-+ return ImgSurfaceToPixbuf(imgSurface, aWidth, aHeight);
-+}
-Index: offscreen/widget/src/headless/nsImageToPixbuf.h
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ offscreen/widget/src/headless/nsImageToPixbuf.h 2009-06-12 14:14:05.000000000 +0100
-@@ -0,0 +1,71 @@
-+/* vim:set sw=4 sts=4 et cin: */
-+/* ***** BEGIN LICENSE BLOCK *****
-+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
-+ *
-+ * The contents of this file are subject to the Mozilla Public License Version
-+ * 1.1 (the "License"); you may not use this file except in compliance with
-+ * the License. You may obtain a copy of the License at
-+ * http://www.mozilla.org/MPL/
-+ *
-+ * Software distributed under the License is distributed on an "AS IS" basis,
-+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-+ * for the specific language governing rights and limitations under the
-+ * License.
-+ *
-+ * The Original Code is mozilla.org widget code.
-+ *
-+ * The Initial Developer of the Original Code is
-+ * Christian Biesinger <cbiesinger@web.de>.
-+ * Portions created by the Initial Developer are Copyright (C) 2006
-+ * the Initial Developer. All Rights Reserved.
-+ *
-+ * Contributor(s):
-+ *
-+ * Alternatively, the contents of this file may be used under the terms of
-+ * either the GNU General Public License Version 2 or later (the "GPL"), or
-+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-+ * in which case the provisions of the GPL or the LGPL are applicable instead
-+ * of those above. If you wish to allow use of your version of this file only
-+ * under the terms of either the GPL or the LGPL, and not to allow others to
-+ * use your version of this file under the terms of the MPL, indicate your
-+ * decision by deleting the provisions above and replace them with the notice
-+ * 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 ***** */
-+
-+#ifndef NSIMAGETOPIXBUF_H_
-+#define NSIMAGETOPIXBUF_H_
-+
-+#include "nsIImageToPixbuf.h"
-+
-+class gfxASurface;
-+class gfxPattern;
-+class gfxImageSurface;
-+
-+class nsImageToPixbuf : public nsIImageToPixbuf {
-+ public:
-+ NS_DECL_ISUPPORTS
-+ NS_IMETHOD_(GdkPixbuf*) ConvertImageToPixbuf(nsIImage* aImage);
-+
-+ // Friendlier version of ConvertImageToPixbuf for callers inside of
-+ // widget
-+ static GdkPixbuf* ImageToPixbuf(nsIImage* aImage);
-+ static GdkPixbuf* SurfaceToPixbuf(gfxASurface* aSurface,
-+ PRInt32 aWidth, PRInt32 aHeight);
-+ static GdkPixbuf* PatternToPixbuf(gfxPattern* aPattern,
-+ PRInt32 aWidth, PRInt32 aHeight);
-+ private:
-+ static GdkPixbuf* ImgSurfaceToPixbuf(gfxImageSurface* aImgSurface,
-+ PRInt32 aWidth, PRInt32 aHeight);
-+ ~nsImageToPixbuf() {}
-+};
-+
-+
-+// fc2389b8-c650-4093-9e42-b05e5f0685b7
-+#define NS_IMAGE_TO_PIXBUF_CID \
-+{ 0xfc2389b8, 0xc650, 0x4093, \
-+ { 0x9e, 0x42, 0xb0, 0x5e, 0x5f, 0x06, 0x85, 0xb7 } }
-+
-+#endif
-Index: offscreen/widget/src/headless/nsWidgetFactory.cpp
-===================================================================
---- offscreen.orig/widget/src/headless/nsWidgetFactory.cpp 2009-06-12 14:08:56.000000000 +0100
-+++ offscreen/widget/src/headless/nsWidgetFactory.cpp 2009-06-12 14:15:24.000000000 +0100
-@@ -46,6 +46,10 @@
- #include "nsWindow.h"
- #include "nsTransferable.h"
- #include "nsHTMLFormatConverter.h"
-+#ifdef MOZ_X11
-+#include "nsClipboardHelper.h"
-+#include "nsClipboard.h"
-+#endif
- #include "nsSound.h"
- #include "nsBidiKeyboard.h"
- #include "nsScreenManagerHeadless.h"
-@@ -66,6 +70,10 @@
- NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
- NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard)
- NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
-+#ifdef MOZ_X11
-+NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
-+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsClipboard, Init)
-+#endif
- NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
- NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerHeadless)
- //NS_GENERIC_FACTORY_CONSTRUCTOR(nsImageToPixbuf)
-@@ -142,6 +150,16 @@
- NS_TRANSFERABLE_CID,
- "@mozilla.org/widget/transferable;1",
- nsTransferableConstructor },
-+#ifdef MOZ_X11
-+ { "Gtk Clipboard",
-+ NS_CLIPBOARD_CID,
-+ "@mozilla.org/widget/clipboard;1",
-+ nsClipboardConstructor },
-+ { "Clipboard Helper",
-+ NS_CLIPBOARDHELPER_CID,
-+ "@mozilla.org/widget/clipboardhelper;1",
-+ nsClipboardHelperConstructor },
-+#endif
- { "HTML Format Converter",
- NS_HTMLFORMATCONVERTER_CID,
- "@mozilla.org/widget/htmlformatconverter;1",