1 From fb41f028badb4dfddfc47fb2a1a68c1aa90dcef5 Mon Sep 17 00:00:00 2001
2 From: Robert Bragg <robert@linux.intel.com>
3 Date: Fri, 8 May 2009 13:57:22 +0100
4 Subject: [PATCH] Adds initial Gtk clipboard support to moz-headless
6 If build with MOZ_X11 enabled then this now builds the clipboard code taken
7 from the gtk2 backend. This doesn't provide any embedding API yet to expose
10 widget/src/headless/Makefile.in | 6 +
11 widget/src/headless/nsClipboard.cpp | 948 +++++++++++++++++++++++++++++++
12 widget/src/headless/nsClipboard.h | 93 +++
13 widget/src/headless/nsIImageToPixbuf.h | 62 ++
14 widget/src/headless/nsImageToPixbuf.cpp | 196 +++++++
15 widget/src/headless/nsImageToPixbuf.h | 71 +++
16 widget/src/headless/nsWidgetFactory.cpp | 18 +
17 7 files changed, 1394 insertions(+), 0 deletions(-)
18 create mode 100644 widget/src/headless/nsClipboard.cpp
19 create mode 100644 widget/src/headless/nsClipboard.h
20 create mode 100644 widget/src/headless/nsIImageToPixbuf.h
21 create mode 100644 widget/src/headless/nsImageToPixbuf.cpp
22 create mode 100644 widget/src/headless/nsImageToPixbuf.h
24 diff --git a/widget/src/headless/Makefile.in b/widget/src/headless/Makefile.in
25 index c8727d9..cbdf900 100644
26 --- a/widget/src/headless/Makefile.in
27 +++ b/widget/src/headless/Makefile.in
28 @@ -95,6 +95,12 @@ CPPSRCS = \
29 nsScreenManagerHeadless.cpp \
33 +CPPSRCS += nsClipboard.cpp \
34 + nsImageToPixbuf.cpp \
38 # build our subdirs, too
39 SHARED_LIBRARY_LIBS = ../xpwidgets/libxpwidgets_s.a
41 diff --git a/widget/src/headless/nsClipboard.cpp b/widget/src/headless/nsClipboard.cpp
43 index 0000000..72a37fc
45 +++ b/widget/src/headless/nsClipboard.cpp
47 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
48 +/* vim:expandtab:shiftwidth=4:tabstop=4:
50 +/* ***** BEGIN LICENSE BLOCK *****
51 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
53 + * The contents of this file are subject to the Mozilla Public License Version
54 + * 1.1 (the "License"); you may not use this file except in compliance with
55 + * the License. You may obtain a copy of the License at
56 + * http://www.mozilla.org/MPL/
58 + * Software distributed under the License is distributed on an "AS IS" basis,
59 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
60 + * for the specific language governing rights and limitations under the
63 + * The Original Code is mozilla.org code.
65 + * The Initial Developer of the Original Code is Christopher Blizzard
66 + * <blizzard@mozilla.org>. Portions created by the Initial Developer
67 + * are Copyright (C) 2001 the Initial Developer. All Rights Reserved.
71 + * Alternatively, the contents of this file may be used under the terms of
72 + * either the GNU General Public License Version 2 or later (the "GPL"), or
73 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
74 + * in which case the provisions of the GPL or the LGPL are applicable instead
75 + * of those above. If you wish to allow use of your version of this file only
76 + * under the terms of either the GPL or the LGPL, and not to allow others to
77 + * use your version of this file under the terms of the MPL, indicate your
78 + * decision by deleting the provisions above and replace them with the notice
79 + * and other provisions required by the GPL or the LGPL. If you do not delete
80 + * the provisions above, a recipient may use your version of this file under
81 + * the terms of any one of the MPL, the GPL or the LGPL.
83 + * ***** END LICENSE BLOCK ***** */
85 +#include "nsClipboard.h"
86 +#include "nsSupportsPrimitives.h"
87 +#include "nsString.h"
88 +#include "nsReadableUtils.h"
89 +#include "nsXPIDLString.h"
90 +#include "nsPrimitiveHelpers.h"
91 +#include "nsICharsetConverterManager.h"
92 +#include "nsIServiceManager.h"
93 +#include "nsIImage.h"
94 +#include "nsImageToPixbuf.h"
95 +#include "nsStringStream.h"
99 +// For manipulation of the X event queue
100 +#include <X11/Xlib.h>
101 +#include <gdk/gdkx.h>
102 +#include <sys/time.h>
103 +#include <sys/types.h>
106 +#ifdef POLL_WITH_XCONNECTIONNUMBER
110 +// Callback when someone asks us for the selection
112 +invisible_selection_get_cb (GtkWidget *aWidget,
113 + GtkSelectionData *aSelectionData,
116 + nsClipboard *aClipboard);
119 +selection_clear_event_cb (GtkWidget *aWidget,
120 + GdkEventSelection *aEvent,
121 + nsClipboard *aClipboard);
124 +ConvertHTMLtoUCS2 (guchar *data,
125 + PRInt32 dataLength,
126 + PRUnichar **unicodeData,
127 + PRInt32 &outUnicodeLen);
130 +GetHTMLCharset (guchar * data, PRInt32 dataLength, nsCString& str);
133 +// Our own versions of gtk_clipboard_wait_for_contents and
134 +// gtk_clipboard_wait_for_text, which don't run the event loop while
135 +// waiting for the data. This prevents a lot of problems related to
136 +// dispatching events at unexpected times.
138 +static GtkSelectionData *
139 +wait_for_contents (GtkClipboard *clipboard, GdkAtom target);
142 +wait_for_text (GtkClipboard *clipboard);
145 +checkEventProc(Display *display, XEvent *event, XPointer arg);
147 +struct retrieval_context
152 + retrieval_context() : completed(PR_FALSE), data(nsnull) { }
156 +wait_for_retrieval(GtkClipboard *clipboard, retrieval_context *transferData);
159 +clipboard_contents_received(GtkClipboard *clipboard,
160 + GtkSelectionData *selection_data,
164 +clipboard_text_received(GtkClipboard *clipboard,
168 +nsClipboard::nsClipboard()
173 +nsClipboard::~nsClipboard()
176 + gtk_widget_destroy(mWidget);
179 +NS_IMPL_ISUPPORTS1(nsClipboard, nsIClipboard)
182 +nsClipboard::Init(void)
184 + mWidget = gtk_invisible_new();
186 + return NS_ERROR_FAILURE;
188 + g_signal_connect(G_OBJECT(mWidget), "selection_get",
189 + G_CALLBACK(invisible_selection_get_cb), this);
191 + g_signal_connect(G_OBJECT(mWidget), "selection_clear_event",
192 + G_CALLBACK(selection_clear_event_cb), this);
194 + // XXX make sure to set up the selection_clear event
200 +nsClipboard::SetData(nsITransferable *aTransferable,
201 + nsIClipboardOwner *aOwner, PRInt32 aWhichClipboard)
203 + // See if we can short cut
204 + if ((aWhichClipboard == kGlobalClipboard &&
205 + aTransferable == mGlobalTransferable.get() &&
206 + aOwner == mGlobalOwner.get()) ||
207 + (aWhichClipboard == kSelectionClipboard &&
208 + aTransferable == mSelectionTransferable.get() &&
209 + aOwner == mSelectionOwner.get())) {
214 + if (!mPrivacyHandler) {
215 + rv = NS_NewClipboardPrivacyHandler(getter_AddRefs(mPrivacyHandler));
216 + NS_ENSURE_SUCCESS(rv, rv);
218 + rv = mPrivacyHandler->PrepareDataForClipboard(aTransferable);
219 + NS_ENSURE_SUCCESS(rv, rv);
221 + // Clear out the clipboard in order to set the new data
222 + EmptyClipboard(aWhichClipboard);
224 + if (aWhichClipboard == kSelectionClipboard) {
225 + mSelectionOwner = aOwner;
226 + mSelectionTransferable = aTransferable;
229 + mGlobalOwner = aOwner;
230 + mGlobalTransferable = aTransferable;
233 + // Which selection are we about to claim, CLIPBOARD or PRIMARY?
234 + GdkAtom selectionAtom = GetSelectionAtom(aWhichClipboard);
236 + // Make ourselves the owner. If we fail to, return.
237 + if (!gtk_selection_owner_set(mWidget, selectionAtom, GDK_CURRENT_TIME))
238 + return NS_ERROR_FAILURE;
240 + // Clear the old selection target list.
241 + gtk_selection_clear_targets(mWidget, selectionAtom);
243 + // Get the types of supported flavors
244 + nsCOMPtr<nsISupportsArray> flavors;
246 + rv = aTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavors));
247 + if (!flavors || NS_FAILED(rv))
248 + return NS_ERROR_FAILURE;
250 + // Add all the flavors to this widget's supported type.
252 + flavors->Count(&count);
253 + for (PRUint32 i=0; i < count; i++) {
254 + nsCOMPtr<nsISupports> tastesLike;
255 + flavors->GetElementAt(i, getter_AddRefs(tastesLike));
256 + nsCOMPtr<nsISupportsCString> flavor = do_QueryInterface(tastesLike);
259 + nsXPIDLCString flavorStr;
260 + flavor->ToString(getter_Copies(flavorStr));
262 + // special case text/unicode since we can handle all of
263 + // the string types
264 + if (!strcmp(flavorStr, kUnicodeMime)) {
265 + AddTarget(gdk_atom_intern("UTF8_STRING", FALSE),
267 + AddTarget(gdk_atom_intern("COMPOUND_TEXT", FALSE),
269 + AddTarget(gdk_atom_intern("TEXT", FALSE), selectionAtom);
270 + AddTarget(GDK_SELECTION_TYPE_STRING, selectionAtom);
271 + // next loop iteration
275 + // very special case for this one. since our selection mechanism doesn't work for images,
276 + // we must use GTK's clipboard utility functions
277 + if (!strcmp(flavorStr, kNativeImageMime) || !strcmp(flavorStr, kPNGImageMime) ||
278 + !strcmp(flavorStr, kJPEGImageMime) || !strcmp(flavorStr, kGIFImageMime)) {
279 + nsCOMPtr<nsISupports> item;
281 + rv = aTransferable->GetTransferData(flavorStr, getter_AddRefs(item), &len);
282 + nsCOMPtr<nsISupportsInterfacePointer> ptrPrimitive(do_QueryInterface(item));
286 + nsCOMPtr<nsISupports> primitiveData;
287 + ptrPrimitive->GetData(getter_AddRefs(primitiveData));
288 + nsCOMPtr<nsIImage> image(do_QueryInterface(primitiveData));
289 + if (!image) // Not getting an image for an image mime type!?
292 + if (NS_FAILED(image->LockImagePixels(PR_FALSE)))
294 + GdkPixbuf* pixbuf = nsImageToPixbuf::ImageToPixbuf(image);
296 + image->UnlockImagePixels(PR_FALSE);
300 + GtkClipboard *aClipboard = gtk_clipboard_get(GetSelectionAtom(aWhichClipboard));
301 + gtk_clipboard_set_image(aClipboard, pixbuf);
302 + g_object_unref(pixbuf);
303 + image->UnlockImagePixels(PR_FALSE);
307 + // Add this to our list of valid targets
308 + GdkAtom atom = gdk_atom_intern(flavorStr, FALSE);
309 + AddTarget(atom, selectionAtom);
317 +nsClipboard::GetData(nsITransferable *aTransferable, PRInt32 aWhichClipboard)
319 + if (!aTransferable)
320 + return NS_ERROR_FAILURE;
322 + GtkClipboard *clipboard;
323 + clipboard = gtk_clipboard_get(GetSelectionAtom(aWhichClipboard));
325 + guchar *data = NULL;
327 + PRBool foundData = PR_FALSE;
328 + nsCAutoString foundFlavor;
330 + // Get a list of flavors this transferable can import
331 + nsCOMPtr<nsISupportsArray> flavors;
333 + rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavors));
334 + if (!flavors || NS_FAILED(rv))
335 + return NS_ERROR_FAILURE;
338 + flavors->Count(&count);
339 + for (PRUint32 i=0; i < count; i++) {
340 + nsCOMPtr<nsISupports> genericFlavor;
341 + flavors->GetElementAt(i, getter_AddRefs(genericFlavor));
343 + nsCOMPtr<nsISupportsCString> currentFlavor;
344 + currentFlavor = do_QueryInterface(genericFlavor);
346 + if (currentFlavor) {
347 + nsXPIDLCString flavorStr;
348 + currentFlavor->ToString(getter_Copies(flavorStr));
350 + // Special case text/unicode since we can convert any
351 + // string into text/unicode
352 + if (!strcmp(flavorStr, kUnicodeMime)) {
353 + gchar* new_text = wait_for_text(clipboard);
355 + // Convert utf-8 into our unicode format.
356 + NS_ConvertUTF8toUTF16 ucs2string(new_text);
357 + data = (guchar *)ToNewUnicode(ucs2string);
358 + length = ucs2string.Length() * 2;
360 + foundData = PR_TRUE;
361 + foundFlavor = kUnicodeMime;
364 + // If the type was text/unicode and we couldn't get
365 + // text off the clipboard, run the next loop
370 + // For images, we must wrap the data in an nsIInputStream then return instead of break,
371 + // because that code below won't help us.
372 + if (!strcmp(flavorStr, kJPEGImageMime) || !strcmp(flavorStr, kPNGImageMime) || !strcmp(flavorStr, kGIFImageMime)) {
374 + if (!strcmp(flavorStr, kJPEGImageMime)) // This is image/jpg, but X only understands image/jpeg
375 + atom = gdk_atom_intern("image/jpeg", FALSE);
377 + atom = gdk_atom_intern(flavorStr, FALSE);
379 + GtkSelectionData *selectionData = wait_for_contents(clipboard, atom);
380 + if (!selectionData)
383 + nsCOMPtr<nsIInputStream> byteStream;
384 + NS_NewByteInputStream(getter_AddRefs(byteStream), (const char*)selectionData->data,
385 + selectionData->length, NS_ASSIGNMENT_COPY);
386 + aTransferable->SetTransferData(flavorStr, byteStream, sizeof(nsIInputStream*));
387 + gtk_selection_data_free(selectionData);
391 + // Get the atom for this type and try to request it off
393 + GdkAtom atom = gdk_atom_intern(flavorStr, FALSE);
394 + GtkSelectionData *selectionData;
395 + selectionData = wait_for_contents(clipboard, atom);
396 + if (selectionData) {
397 + length = selectionData->length;
398 + // Special case text/html since we can convert into UCS2
399 + if (!strcmp(flavorStr, kHTMLMime)) {
400 + PRUnichar* htmlBody= nsnull;
401 + PRInt32 htmlBodyLen = 0;
402 + // Convert text/html into our unicode format
403 + ConvertHTMLtoUCS2((guchar *)selectionData->data, length,
404 + &htmlBody, htmlBodyLen);
407 + data = (guchar *)htmlBody;
408 + length = htmlBodyLen * 2;
410 + data = (guchar *)nsMemory::Alloc(length);
413 + memcpy(data, selectionData->data, length);
415 + foundData = PR_TRUE;
416 + foundFlavor = flavorStr;
423 + nsCOMPtr<nsISupports> wrapper;
424 + nsPrimitiveHelpers::CreatePrimitiveForData(foundFlavor.get(),
426 + getter_AddRefs(wrapper));
427 + aTransferable->SetTransferData(foundFlavor.get(),
432 + nsMemory::Free(data);
438 +nsClipboard::EmptyClipboard(PRInt32 aWhichClipboard)
440 + if (aWhichClipboard == kSelectionClipboard) {
441 + if (mSelectionOwner) {
442 + mSelectionOwner->LosingOwnership(mSelectionTransferable);
443 + mSelectionOwner = nsnull;
445 + mSelectionTransferable = nsnull;
448 + if (mGlobalOwner) {
449 + mGlobalOwner->LosingOwnership(mGlobalTransferable);
450 + mGlobalOwner = nsnull;
452 + mGlobalTransferable = nsnull;
459 +nsClipboard::HasDataMatchingFlavors(const char** aFlavorList, PRUint32 aLength,
460 + PRInt32 aWhichClipboard, PRBool *_retval)
462 + if (!aFlavorList || !_retval)
463 + return NS_ERROR_NULL_POINTER;
465 + *_retval = PR_FALSE;
467 + GtkSelectionData *selection_data =
468 + GetTargets(GetSelectionAtom(aWhichClipboard));
469 + if (!selection_data)
472 + gint n_targets = 0;
473 + GdkAtom *targets = NULL;
475 + if (!gtk_selection_data_get_targets(selection_data,
476 + &targets, &n_targets) ||
480 + // Walk through the provided types and try to match it to a
482 + for (PRUint32 i = 0; i < aLength && !*_retval; i++) {
483 + // We special case text/unicode here.
484 + if (!strcmp(aFlavorList[i], kUnicodeMime) &&
485 + gtk_selection_data_targets_include_text(selection_data)) {
486 + *_retval = PR_TRUE;
490 + for (PRInt32 j = 0; j < n_targets; j++) {
491 + gchar *atom_name = gdk_atom_name(targets[j]);
492 + if (!strcmp(atom_name, aFlavorList[i]))
493 + *_retval = PR_TRUE;
495 + // X clipboard wants image/jpeg, not image/jpg
496 + if (!strcmp(aFlavorList[i], kJPEGImageMime) && !strcmp(atom_name, "image/jpeg"))
497 + *_retval = PR_TRUE;
505 + gtk_selection_data_free(selection_data);
512 +nsClipboard::SupportsSelectionClipboard(PRBool *_retval)
514 + *_retval = PR_TRUE; // yeah, unix supports the selection clipboard
520 +nsClipboard::GetSelectionAtom(PRInt32 aWhichClipboard)
522 + if (aWhichClipboard == kGlobalClipboard)
523 + return GDK_SELECTION_CLIPBOARD;
525 + return GDK_SELECTION_PRIMARY;
530 +nsClipboard::GetTargets(GdkAtom aWhichClipboard)
532 + GtkClipboard *clipboard = gtk_clipboard_get(aWhichClipboard);
533 + return wait_for_contents(clipboard, gdk_atom_intern("TARGETS", FALSE));
537 +nsClipboard::GetTransferable(PRInt32 aWhichClipboard)
539 + nsITransferable *retval;
541 + if (aWhichClipboard == kSelectionClipboard)
542 + retval = mSelectionTransferable.get();
544 + retval = mGlobalTransferable.get();
550 +nsClipboard::AddTarget(GdkAtom aName, GdkAtom aClipboard)
552 + gtk_selection_add_target(mWidget, aClipboard, aName, 0);
556 +nsClipboard::SelectionGetEvent (GtkWidget *aWidget,
557 + GtkSelectionData *aSelectionData,
560 + // Someone has asked us to hand them something. The first thing
561 + // that we want to do is see if that something includes text. If
562 + // it does, try to give it text/unicode after converting it to
565 + PRInt32 whichClipboard;
567 + // which clipboard?
568 + if (aSelectionData->selection == GDK_SELECTION_PRIMARY)
569 + whichClipboard = kSelectionClipboard;
570 + else if (aSelectionData->selection == GDK_SELECTION_CLIPBOARD)
571 + whichClipboard = kGlobalClipboard;
573 + return; // THAT AIN'T NO CLIPBOARD I EVER HEARD OF
575 + nsCOMPtr<nsITransferable> trans = GetTransferable(whichClipboard);
578 + nsCOMPtr<nsISupports> item;
581 + // Check to see if the selection data includes any of the string
582 + // types that we support.
583 + if (aSelectionData->target == gdk_atom_intern ("STRING", FALSE) ||
584 + aSelectionData->target == gdk_atom_intern ("TEXT", FALSE) ||
585 + aSelectionData->target == gdk_atom_intern ("COMPOUND_TEXT", FALSE) ||
586 + aSelectionData->target == gdk_atom_intern ("UTF8_STRING", FALSE)) {
587 + // Try to convert our internal type into a text string. Get
588 + // the transferable for this clipboard and try to get the
589 + // text/unicode type for it.
590 + rv = trans->GetTransferData("text/unicode", getter_AddRefs(item),
592 + if (!item || NS_FAILED(rv))
595 + nsCOMPtr<nsISupportsString> wideString;
596 + wideString = do_QueryInterface(item);
600 + nsAutoString ucs2string;
601 + wideString->GetData(ucs2string);
602 + char *utf8string = ToNewUTF8String(ucs2string);
606 + gtk_selection_data_set_text (aSelectionData, utf8string,
607 + strlen(utf8string));
609 + nsMemory::Free(utf8string);
613 + // Try to match up the selection data target to something our
614 + // transferable provides.
615 + gchar *target_name = gdk_atom_name(aSelectionData->target);
619 + rv = trans->GetTransferData(target_name, getter_AddRefs(item), &len);
621 + if (!item || NS_FAILED(rv)) {
622 + g_free(target_name);
626 + void *primitive_data = nsnull;
627 + nsPrimitiveHelpers::CreateDataFromPrimitive(target_name, item,
628 + &primitive_data, len);
630 + if (primitive_data) {
631 + // Check to see if the selection data is text/html
632 + if (aSelectionData->target == gdk_atom_intern (kHTMLMime, FALSE)) {
634 + * "text/html" can be encoded UCS2. It is recommended that
635 + * documents transmitted as UCS2 always begin with a ZERO-WIDTH
636 + * NON-BREAKING SPACE character (hexadecimal FEFF, also called
637 + * Byte Order Mark (BOM)). Adding BOM can help other app to
638 + * detect mozilla use UCS2 encoding when copy-paste.
640 + guchar *buffer = (guchar *)
641 + nsMemory::Alloc((len * sizeof(guchar)) + sizeof(PRUnichar));
644 + PRUnichar prefix = 0xFEFF;
645 + memcpy(buffer, &prefix, sizeof(prefix));
646 + memcpy(buffer + sizeof(prefix), primitive_data, len);
647 + nsMemory::Free((guchar *)primitive_data);
648 + primitive_data = (guchar *)buffer;
649 + len += sizeof(prefix);
652 + gtk_selection_data_set(aSelectionData, aSelectionData->target,
653 + 8, /* 8 bits in a unit */
654 + (const guchar *)primitive_data, len);
655 + nsMemory::Free(primitive_data);
658 + g_free(target_name);
663 +nsClipboard::SelectionClearEvent (GtkWidget *aWidget,
664 + GdkEventSelection *aEvent)
666 + PRInt32 whichClipboard;
668 + // which clipboard?
669 + if (aEvent->selection == GDK_SELECTION_PRIMARY)
670 + whichClipboard = kSelectionClipboard;
671 + else if (aEvent->selection == GDK_SELECTION_CLIPBOARD)
672 + whichClipboard = kGlobalClipboard;
674 + return; // THAT AIN'T NO CLIPBOARD I EVER HEARD OF
676 + EmptyClipboard(whichClipboard);
680 +invisible_selection_get_cb (GtkWidget *aWidget,
681 + GtkSelectionData *aSelectionData,
684 + nsClipboard *aClipboard)
686 + aClipboard->SelectionGetEvent(aWidget, aSelectionData, aTime);
690 +selection_clear_event_cb (GtkWidget *aWidget,
691 + GdkEventSelection *aEvent,
692 + nsClipboard *aClipboard)
694 + aClipboard->SelectionClearEvent(aWidget, aEvent);
699 + * when copy-paste, mozilla wants data encoded using UCS2,
700 + * other app such as StarOffice use "text/html"(RFC2854).
701 + * This function convert data(got from GTK clipboard)
702 + * to data mozilla wanted.
704 + * data from GTK clipboard can be 3 forms:
705 + * 1. From current mozilla
706 + * "text/html", charset = utf-16
707 + * 2. From old version mozilla or mozilla-based app
708 + * content("body" only), charset = utf-16
709 + * 3. From other app who use "text/html" when copy-paste
710 + * "text/html", has "charset" info
712 + * data : got from GTK clipboard
713 + * dataLength: got from GTK clipboard
714 + * body : pass to Mozilla
715 + * bodyLength: pass to Mozilla
717 +void ConvertHTMLtoUCS2(guchar * data, PRInt32 dataLength,
718 + PRUnichar** unicodeData, PRInt32& outUnicodeLen)
720 + nsCAutoString charset;
721 + GetHTMLCharset(data, dataLength, charset);// get charset of HTML
722 + if (charset.EqualsLiteral("UTF-16")) {//current mozilla
723 + outUnicodeLen = (dataLength / 2) - 1;
724 + *unicodeData = reinterpret_cast<PRUnichar*>
725 + (nsMemory::Alloc((outUnicodeLen + sizeof('\0')) *
726 + sizeof(PRUnichar)));
727 + if (*unicodeData) {
728 + memcpy(*unicodeData, data + sizeof(PRUnichar),
729 + outUnicodeLen * sizeof(PRUnichar));
730 + (*unicodeData)[outUnicodeLen] = '\0';
732 + } else if (charset.EqualsLiteral("UNKNOWN")) {
736 + // app which use "text/html" to copy&paste
737 + nsCOMPtr<nsIUnicodeDecoder> decoder;
740 + nsCOMPtr<nsICharsetConverterManager> ccm =
741 + do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
742 + if (NS_FAILED(rv)) {
743 +#ifdef DEBUG_CLIPBOARD
744 + g_print(" can't get CHARSET CONVERTER MANAGER service\n");
749 + rv = ccm->GetUnicodeDecoder(charset.get(), getter_AddRefs(decoder));
750 + if (NS_FAILED(rv)) {
751 +#ifdef DEBUG_CLIPBOARD
752 + g_print(" get unicode decoder error\n");
758 + decoder->GetMaxLength((const char *)data, dataLength, &outUnicodeLen);
759 + // |outUnicodeLen| is number of chars
760 + if (outUnicodeLen) {
761 + *unicodeData = reinterpret_cast<PRUnichar*>
762 + (nsMemory::Alloc((outUnicodeLen + sizeof('\0')) *
763 + sizeof(PRUnichar)));
764 + if (*unicodeData) {
765 + PRInt32 numberTmp = dataLength;
766 + decoder->Convert((const char *)data, &numberTmp,
767 + *unicodeData, &outUnicodeLen);
768 +#ifdef DEBUG_CLIPBOARD
769 + if (numberTmp != dataLength)
770 + printf("didn't consume all the bytes\n");
772 + // null terminate. Convert() doesn't do it for us
773 + (*unicodeData)[outUnicodeLen] = '\0';
775 + } // if valid length
780 + * get "charset" information from clipboard data
781 + * return value can be:
782 + * 1. "UTF-16": mozilla or "text/html" with "charset=utf-16"
783 + * 2. "UNKNOWN": mozilla can't detect what encode it use
784 + * 3. other: "text/html" with other charset than utf-16
786 +void GetHTMLCharset(guchar * data, PRInt32 dataLength, nsCString& str)
788 + // if detect "FFFE" or "FEFF", assume UTF-16
789 + PRUnichar* beginChar = (PRUnichar*)data;
790 + if ((beginChar[0] == 0xFFFE) || (beginChar[0] == 0xFEFF)) {
791 + str.AssignLiteral("UTF-16");
794 + // no "FFFE" and "FEFF", assume ASCII first to find "charset" info
795 + const nsDependentCString htmlStr((const char *)data, dataLength);
796 + nsACString::const_iterator start, end;
797 + htmlStr.BeginReading(start);
798 + htmlStr.EndReading(end);
799 + nsACString::const_iterator valueStart(start), valueEnd(start);
801 + if (CaseInsensitiveFindInReadable(
802 + NS_LITERAL_CSTRING("CONTENT=\"text/html;"),
805 + htmlStr.EndReading(end);
807 + if (CaseInsensitiveFindInReadable(
808 + NS_LITERAL_CSTRING("charset="),
812 + htmlStr.EndReading(end);
814 + if (FindCharInReadable('"', start, end))
818 + // find "charset" in HTML
819 + if (valueStart != valueEnd) {
820 + str = Substring(valueStart, valueEnd);
822 +#ifdef DEBUG_CLIPBOARD
823 + printf("Charset of HTML = %s\n", charsetUpperStr.get());
827 + str.AssignLiteral("UNKNOWN");
831 +DispatchSelectionNotifyEvent(GtkWidget *widget, XEvent *xevent)
834 + event.selection.type = GDK_SELECTION_NOTIFY;
835 + event.selection.window = widget->window;
836 + event.selection.selection = gdk_x11_xatom_to_atom(xevent->xselection.selection);
837 + event.selection.target = gdk_x11_xatom_to_atom(xevent->xselection.target);
838 + event.selection.property = gdk_x11_xatom_to_atom(xevent->xselection.property);
839 + event.selection.time = xevent->xselection.time;
841 + gtk_widget_event(widget, &event);
845 +DispatchPropertyNotifyEvent(GtkWidget *widget, XEvent *xevent)
847 + if (((GdkWindowObject *) widget->window)->event_mask & GDK_PROPERTY_CHANGE_MASK) {
849 + event.property.type = GDK_PROPERTY_NOTIFY;
850 + event.property.window = widget->window;
851 + event.property.atom = gdk_x11_xatom_to_atom(xevent->xproperty.atom);
852 + event.property.time = xevent->xproperty.time;
853 + event.property.state = xevent->xproperty.state;
855 + gtk_widget_event(widget, &event);
859 +struct checkEventContext
861 + GtkWidget *cbWidget;
866 +checkEventProc(Display *display, XEvent *event, XPointer arg)
868 + checkEventContext *context = (checkEventContext *) arg;
870 + if (event->xany.type == SelectionNotify ||
871 + (event->xany.type == PropertyNotify &&
872 + event->xproperty.atom == context->selAtom)) {
874 + GdkWindow *cbWindow = gdk_window_lookup(event->xany.window);
876 + GtkWidget *cbWidget = NULL;
877 + gdk_window_get_user_data(cbWindow, (gpointer *)&cbWidget);
878 + if (cbWidget && GTK_IS_WIDGET(cbWidget)) {
879 + context->cbWidget = cbWidget;
888 +// Idle timeout for receiving selection and property notify events (microsec)
889 +static const int kClipboardTimeout = 500000;
892 +wait_for_retrieval(GtkClipboard *clipboard, retrieval_context *r_context)
894 + if (r_context->completed) // the request completed synchronously
897 + Display *xDisplay = GDK_DISPLAY();
898 + checkEventContext context;
899 + context.cbWidget = NULL;
900 + context.selAtom = gdk_x11_atom_to_xatom(gdk_atom_intern("GDK_SELECTION",
903 + // Send X events which are relevant to the ongoing selection retrieval
904 + // to the clipboard widget. Wait until either the operation completes, or
905 + // we hit our timeout. All other X events remain queued.
909 +#ifdef POLL_WITH_XCONNECTIONNUMBER
910 + struct pollfd fds[1];
911 + fds[0].fd = XConnectionNumber(xDisplay);
912 + fds[0].events = POLLIN;
914 + int cnumber = ConnectionNumber(xDisplay);
916 + FD_ZERO(&select_set);
917 + FD_SET(cnumber, &select_set);
925 + while (XCheckIfEvent(xDisplay, &xevent, checkEventProc,
926 + (XPointer) &context)) {
928 + if (xevent.xany.type == SelectionNotify)
929 + DispatchSelectionNotifyEvent(context.cbWidget, &xevent);
931 + DispatchPropertyNotifyEvent(context.cbWidget, &xevent);
933 + if (r_context->completed)
937 +#ifdef POLL_WITH_XCONNECTIONNUMBER
938 + select_result = poll(fds, 1, kClipboardTimeout / 1000);
941 + tv.tv_usec = kClipboardTimeout;
942 + select_result = select(cnumber, &select_set, NULL, NULL, &tv);
944 + } while (select_result == 1);
946 +#ifdef DEBUG_CLIPBOARD
947 + printf("exceeded clipboard timeout\n");
952 +clipboard_contents_received(GtkClipboard *clipboard,
953 + GtkSelectionData *selection_data,
956 + retrieval_context *context = static_cast<retrieval_context *>(data);
957 + context->completed = PR_TRUE;
959 + if (selection_data->length >= 0)
960 + context->data = gtk_selection_data_copy(selection_data);
964 +static GtkSelectionData *
965 +wait_for_contents(GtkClipboard *clipboard, GdkAtom target)
967 + retrieval_context context;
968 + gtk_clipboard_request_contents(clipboard, target,
969 + clipboard_contents_received,
972 + wait_for_retrieval(clipboard, &context);
973 + return static_cast<GtkSelectionData *>(context.data);
977 +clipboard_text_received(GtkClipboard *clipboard,
981 + retrieval_context *context = static_cast<retrieval_context *>(data);
982 + context->completed = PR_TRUE;
983 + context->data = g_strdup(text);
987 +wait_for_text(GtkClipboard *clipboard)
989 + retrieval_context context;
990 + gtk_clipboard_request_text(clipboard, clipboard_text_received, &context);
992 + wait_for_retrieval(clipboard, &context);
993 + return static_cast<gchar *>(context.data);
995 diff --git a/widget/src/headless/nsClipboard.h b/widget/src/headless/nsClipboard.h
997 index 0000000..dc690c0
999 +++ b/widget/src/headless/nsClipboard.h
1001 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
1002 +/* vim:expandtab:shiftwidth=4:tabstop=4:
1004 +/* ***** BEGIN LICENSE BLOCK *****
1005 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
1007 + * The contents of this file are subject to the Mozilla Public License Version
1008 + * 1.1 (the "License"); you may not use this file except in compliance with
1009 + * the License. You may obtain a copy of the License at
1010 + * http://www.mozilla.org/MPL/
1012 + * Software distributed under the License is distributed on an "AS IS" basis,
1013 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1014 + * for the specific language governing rights and limitations under the
1017 + * The Original Code is mozilla.org code.
1019 + * The Initial Developer of the Original Code is Christopher Blizzard
1020 + * <blizzard@mozilla.org>. Portions created by the Initial Developer
1021 + * are Copyright (C) 2001 the Initial Developer. All Rights Reserved.
1025 + * Alternatively, the contents of this file may be used under the terms of
1026 + * either the GNU General Public License Version 2 or later (the "GPL"), or
1027 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
1028 + * in which case the provisions of the GPL or the LGPL are applicable instead
1029 + * of those above. If you wish to allow use of your version of this file only
1030 + * under the terms of either the GPL or the LGPL, and not to allow others to
1031 + * use your version of this file under the terms of the MPL, indicate your
1032 + * decision by deleting the provisions above and replace them with the notice
1033 + * and other provisions required by the GPL or the LGPL. If you do not delete
1034 + * the provisions above, a recipient may use your version of this file under
1035 + * the terms of any one of the MPL, the GPL or the LGPL.
1037 + * ***** END LICENSE BLOCK ***** */
1039 +#ifndef __nsClipboard_h_
1040 +#define __nsClipboard_h_
1042 +#include "nsIClipboard.h"
1043 +#include "nsClipboardPrivacyHandler.h"
1044 +#include "nsAutoPtr.h"
1045 +#include <gtk/gtk.h>
1047 +class nsClipboard : public nsIClipboard
1051 + virtual ~nsClipboard();
1055 + NS_DECL_NSICLIPBOARD
1057 + // Make sure we are initialized, called from the factory
1059 + nsresult Init (void);
1060 + // Someone requested the selection from the hidden widget
1061 + void SelectionGetEvent (GtkWidget *aWidget,
1062 + GtkSelectionData *aSelectionData,
1064 + void SelectionClearEvent (GtkWidget *aWidget,
1065 + GdkEventSelection *aEvent);
1069 + // Utility methods
1070 + static GdkAtom GetSelectionAtom (PRInt32 aWhichClipboard);
1071 + static GtkSelectionData *GetTargets (GdkAtom aWhichClipboard);
1073 + // Get our hands on the correct transferable, given a specific
1075 + nsITransferable *GetTransferable (PRInt32 aWhichClipboard);
1077 + // Add a target type to the hidden widget
1078 + void AddTarget (GdkAtom aName,
1079 + GdkAtom aClipboard);
1081 + // The hidden widget where we do all of our operations
1082 + GtkWidget *mWidget;
1083 + // Hang on to our owners and transferables so we can transfer data
1085 + nsCOMPtr<nsIClipboardOwner> mSelectionOwner;
1086 + nsCOMPtr<nsIClipboardOwner> mGlobalOwner;
1087 + nsCOMPtr<nsITransferable> mSelectionTransferable;
1088 + nsCOMPtr<nsITransferable> mGlobalTransferable;
1089 + nsRefPtr<nsClipboardPrivacyHandler> mPrivacyHandler;
1093 +#endif /* __nsClipboard_h_ */
1094 diff --git a/widget/src/headless/nsIImageToPixbuf.h b/widget/src/headless/nsIImageToPixbuf.h
1095 new file mode 100644
1096 index 0000000..1c46015
1098 +++ b/widget/src/headless/nsIImageToPixbuf.h
1100 +/* ***** BEGIN LICENSE BLOCK *****
1101 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
1103 + * The contents of this file are subject to the Mozilla Public License Version
1104 + * 1.1 (the "License"); you may not use this file except in compliance with
1105 + * the License. You may obtain a copy of the License at
1106 + * http://www.mozilla.org/MPL/
1108 + * Software distributed under the License is distributed on an "AS IS" basis,
1109 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1110 + * for the specific language governing rights and limitations under the
1113 + * The Original Code is mozilla.org widget code.
1115 + * The Initial Developer of the Original Code is
1116 + * Christian Biesinger <cbiesinger@web.de>.
1117 + * Portions created by the Initial Developer are Copyright (C) 2006
1118 + * the Initial Developer. All Rights Reserved.
1122 + * Alternatively, the contents of this file may be used under the terms of
1123 + * either the GNU General Public License Version 2 or later (the "GPL"), or
1124 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
1125 + * in which case the provisions of the GPL or the LGPL are applicable instead
1126 + * of those above. If you wish to allow use of your version of this file only
1127 + * under the terms of either the GPL or the LGPL, and not to allow others to
1128 + * use your version of this file under the terms of the MPL, indicate your
1129 + * decision by deleting the provisions above and replace them with the notice
1130 + * and other provisions required by the GPL or the LGPL. If you do not delete
1131 + * the provisions above, a recipient may use your version of this file under
1132 + * the terms of any one of the MPL, the GPL or the LGPL.
1134 + * ***** END LICENSE BLOCK ***** */
1136 +#ifndef NSIIMAGETOPIXBUF_H_
1137 +#define NSIIMAGETOPIXBUF_H_
1139 +#include "nsISupports.h"
1141 +// dfa4ac93-83f2-4ab8-9b2a-0ff7022aebe2
1142 +#define NSIIMAGETOPIXBUF_IID \
1143 +{ 0xdfa4ac93, 0x83f2, 0x4ab8, \
1144 + { 0x9b, 0x2a, 0x0f, 0xf7, 0x02, 0x2a, 0xeb, 0xe2 } }
1147 +typedef struct _GdkPixbuf GdkPixbuf;
1150 + * An interface that allows converting an nsIImage to a GdkPixbuf*.
1152 +class nsIImageToPixbuf : public nsISupports {
1154 + NS_DECLARE_STATIC_IID_ACCESSOR(NSIIMAGETOPIXBUF_IID)
1156 + NS_IMETHOD_(GdkPixbuf*) ConvertImageToPixbuf(nsIImage* aImage) = 0;
1159 +NS_DEFINE_STATIC_IID_ACCESSOR(nsIImageToPixbuf, NSIIMAGETOPIXBUF_IID)
1162 diff --git a/widget/src/headless/nsImageToPixbuf.cpp b/widget/src/headless/nsImageToPixbuf.cpp
1163 new file mode 100644
1164 index 0000000..496815c
1166 +++ b/widget/src/headless/nsImageToPixbuf.cpp
1168 +/* vim:set sw=4 sts=4 et cin: */
1169 +/* ***** BEGIN LICENSE BLOCK *****
1170 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
1172 + * The contents of this file are subject to the Mozilla Public License Version
1173 + * 1.1 (the "License"); you may not use this file except in compliance with
1174 + * the License. You may obtain a copy of the License at
1175 + * http://www.mozilla.org/MPL/
1177 + * Software distributed under the License is distributed on an "AS IS" basis,
1178 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1179 + * for the specific language governing rights and limitations under the
1182 + * The Original Code is mozilla.org widget code.
1184 + * The Initial Developer of the Original Code is
1185 + * Christian Biesinger <cbiesinger@web.de>.
1186 + * Portions created by the Initial Developer are Copyright (C) 2006
1187 + * the Initial Developer. All Rights Reserved.
1191 + * Alternatively, the contents of this file may be used under the terms of
1192 + * either the GNU General Public License Version 2 or later (the "GPL"), or
1193 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
1194 + * in which case the provisions of the GPL or the LGPL are applicable instead
1195 + * of those above. If you wish to allow use of your version of this file only
1196 + * under the terms of either the GPL or the LGPL, and not to allow others to
1197 + * use your version of this file under the terms of the MPL, indicate your
1198 + * decision by deleting the provisions above and replace them with the notice
1199 + * and other provisions required by the GPL or the LGPL. If you do not delete
1200 + * the provisions above, a recipient may use your version of this file under
1201 + * the terms of any one of the MPL, the GPL or the LGPL.
1203 + * ***** END LICENSE BLOCK ***** */
1205 +#include <gdk-pixbuf/gdk-pixbuf.h>
1207 +#include "gfxASurface.h"
1208 +#include "gfxImageSurface.h"
1209 +#include "gfxContext.h"
1211 +#include "nsIImage.h"
1213 +#include "nsAutoPtr.h"
1215 +#include "nsImageToPixbuf.h"
1217 +NS_IMPL_ISUPPORTS1(nsImageToPixbuf, nsIImageToPixbuf)
1219 +inline unsigned char
1220 +unpremultiply (unsigned char color,
1221 + unsigned char alpha)
1225 + // plus alpha/2 to round instead of truncate
1226 + return (color * 255 + alpha / 2) / alpha;
1229 +NS_IMETHODIMP_(GdkPixbuf*)
1230 +nsImageToPixbuf::ConvertImageToPixbuf(nsIImage* aImage)
1232 + return ImageToPixbuf(aImage);
1236 +nsImageToPixbuf::ImageToPixbuf(nsIImage* aImage)
1238 + PRInt32 width = aImage->GetWidth(),
1239 + height = aImage->GetHeight();
1241 + nsRefPtr<gfxPattern> pattern;
1242 + aImage->GetPattern(getter_AddRefs(pattern));
1244 + return PatternToPixbuf(pattern, width, height);
1248 +nsImageToPixbuf::ImgSurfaceToPixbuf(gfxImageSurface* aImgSurface, PRInt32 aWidth, PRInt32 aHeight)
1250 + GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, PR_TRUE, 8,
1255 + PRUint32 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
1256 + guchar* pixels = gdk_pixbuf_get_pixels (pixbuf);
1258 + long cairoStride = aImgSurface->Stride();
1259 + unsigned char* cairoData = aImgSurface->Data();
1261 + gfxASurface::gfxImageFormat format = aImgSurface->Format();
1263 + for (PRInt32 row = 0; row < aHeight; ++row) {
1264 + for (PRInt32 col = 0; col < aWidth; ++col) {
1265 + guchar* pixel = pixels + row * rowstride + 4 * col;
1267 + PRUint32* cairoPixel = reinterpret_cast<PRUint32*>
1268 + ((cairoData + row * cairoStride + 4 * col));
1270 + if (format == gfxASurface::ImageFormatARGB32) {
1271 + const PRUint8 a = (*cairoPixel >> 24) & 0xFF;
1272 + const PRUint8 r = unpremultiply((*cairoPixel >> 16) & 0xFF, a);
1273 + const PRUint8 g = unpremultiply((*cairoPixel >> 8) & 0xFF, a);
1274 + const PRUint8 b = unpremultiply((*cairoPixel >> 0) & 0xFF, a);
1281 + NS_ASSERTION(format == gfxASurface::ImageFormatRGB24,
1282 + "unexpected format");
1283 + const PRUint8 r = (*cairoPixel >> 16) & 0xFF;
1284 + const PRUint8 g = (*cairoPixel >> 8) & 0xFF;
1285 + const PRUint8 b = (*cairoPixel >> 0) & 0xFF;
1290 + *pixel++ = 0xFF; // A
1299 +nsImageToPixbuf::SurfaceToPixbuf(gfxASurface* aSurface, PRInt32 aWidth, PRInt32 aHeight)
1301 + if (aSurface->CairoStatus()) {
1302 + NS_ERROR("invalid surface");
1306 + nsRefPtr<gfxImageSurface> imgSurface;
1307 + if (aSurface->GetType() == gfxASurface::SurfaceTypeImage) {
1308 + imgSurface = static_cast<gfxImageSurface*>
1309 + (static_cast<gfxASurface*>(aSurface));
1311 + imgSurface = new gfxImageSurface(gfxIntSize(aWidth, aHeight),
1312 + gfxImageSurface::ImageFormatARGB32);
1317 + nsRefPtr<gfxContext> context = new gfxContext(imgSurface);
1321 + context->SetOperator(gfxContext::OPERATOR_SOURCE);
1322 + context->SetSource(aSurface);
1326 + return ImgSurfaceToPixbuf(imgSurface, aWidth, aHeight);
1330 +nsImageToPixbuf::PatternToPixbuf(gfxPattern* aPattern, PRInt32 aWidth, PRInt32 aHeight)
1332 + if (aPattern->CairoStatus()) {
1333 + NS_ERROR("invalid pattern");
1337 + nsRefPtr<gfxImageSurface> imgSurface;
1338 + if (aPattern->GetType() == gfxPattern::PATTERN_SURFACE) {
1339 + nsRefPtr<gfxASurface> surface = aPattern->GetSurface();
1340 + if (surface->GetType() == gfxASurface::SurfaceTypeImage) {
1341 + imgSurface = static_cast<gfxImageSurface*>
1342 + (static_cast<gfxASurface*>(surface.get()));
1346 + if (!imgSurface) {
1347 + imgSurface = new gfxImageSurface(gfxIntSize(aWidth, aHeight),
1348 + gfxImageSurface::ImageFormatARGB32);
1353 + nsRefPtr<gfxContext> context = new gfxContext(imgSurface);
1357 + context->SetOperator(gfxContext::OPERATOR_SOURCE);
1358 + context->SetPattern(aPattern);
1362 + return ImgSurfaceToPixbuf(imgSurface, aWidth, aHeight);
1364 diff --git a/widget/src/headless/nsImageToPixbuf.h b/widget/src/headless/nsImageToPixbuf.h
1365 new file mode 100644
1366 index 0000000..0e3f516
1368 +++ b/widget/src/headless/nsImageToPixbuf.h
1370 +/* vim:set sw=4 sts=4 et cin: */
1371 +/* ***** BEGIN LICENSE BLOCK *****
1372 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
1374 + * The contents of this file are subject to the Mozilla Public License Version
1375 + * 1.1 (the "License"); you may not use this file except in compliance with
1376 + * the License. You may obtain a copy of the License at
1377 + * http://www.mozilla.org/MPL/
1379 + * Software distributed under the License is distributed on an "AS IS" basis,
1380 + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1381 + * for the specific language governing rights and limitations under the
1384 + * The Original Code is mozilla.org widget code.
1386 + * The Initial Developer of the Original Code is
1387 + * Christian Biesinger <cbiesinger@web.de>.
1388 + * Portions created by the Initial Developer are Copyright (C) 2006
1389 + * the Initial Developer. All Rights Reserved.
1393 + * Alternatively, the contents of this file may be used under the terms of
1394 + * either the GNU General Public License Version 2 or later (the "GPL"), or
1395 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
1396 + * in which case the provisions of the GPL or the LGPL are applicable instead
1397 + * of those above. If you wish to allow use of your version of this file only
1398 + * under the terms of either the GPL or the LGPL, and not to allow others to
1399 + * use your version of this file under the terms of the MPL, indicate your
1400 + * decision by deleting the provisions above and replace them with the notice
1401 + * and other provisions required by the GPL or the LGPL. If you do not delete
1402 + * the provisions above, a recipient may use your version of this file under
1403 + * the terms of any one of the MPL, the GPL or the LGPL.
1405 + * ***** END LICENSE BLOCK ***** */
1407 +#ifndef NSIMAGETOPIXBUF_H_
1408 +#define NSIMAGETOPIXBUF_H_
1410 +#include "nsIImageToPixbuf.h"
1414 +class gfxImageSurface;
1416 +class nsImageToPixbuf : public nsIImageToPixbuf {
1419 + NS_IMETHOD_(GdkPixbuf*) ConvertImageToPixbuf(nsIImage* aImage);
1421 + // Friendlier version of ConvertImageToPixbuf for callers inside of
1423 + static GdkPixbuf* ImageToPixbuf(nsIImage* aImage);
1424 + static GdkPixbuf* SurfaceToPixbuf(gfxASurface* aSurface,
1425 + PRInt32 aWidth, PRInt32 aHeight);
1426 + static GdkPixbuf* PatternToPixbuf(gfxPattern* aPattern,
1427 + PRInt32 aWidth, PRInt32 aHeight);
1429 + static GdkPixbuf* ImgSurfaceToPixbuf(gfxImageSurface* aImgSurface,
1430 + PRInt32 aWidth, PRInt32 aHeight);
1431 + ~nsImageToPixbuf() {}
1435 +// fc2389b8-c650-4093-9e42-b05e5f0685b7
1436 +#define NS_IMAGE_TO_PIXBUF_CID \
1437 +{ 0xfc2389b8, 0xc650, 0x4093, \
1438 + { 0x9e, 0x42, 0xb0, 0x5e, 0x5f, 0x06, 0x85, 0xb7 } }
1441 diff --git a/widget/src/headless/nsWidgetFactory.cpp b/widget/src/headless/nsWidgetFactory.cpp
1442 index eb94333..a215988 100644
1443 --- a/widget/src/headless/nsWidgetFactory.cpp
1444 +++ b/widget/src/headless/nsWidgetFactory.cpp
1446 #include "nsWindow.h"
1447 #include "nsTransferable.h"
1448 #include "nsHTMLFormatConverter.h"
1450 +#include "nsClipboardHelper.h"
1451 +#include "nsClipboard.h"
1453 //#include "nsFilePicker.h"
1454 #include "nsSound.h"
1455 #include "nsBidiKeyboard.h"
1456 @@ -74,6 +78,10 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel)
1457 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
1458 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard)
1459 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
1461 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
1462 +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsClipboard, Init)
1464 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
1465 NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerHeadless)
1466 //NS_GENERIC_FACTORY_CONSTRUCTOR(nsImageToPixbuf)
1467 @@ -189,6 +197,16 @@ static const nsModuleComponentInfo components[] =
1468 NS_TRANSFERABLE_CID,
1469 "@mozilla.org/widget/transferable;1",
1470 nsTransferableConstructor },
1472 + { "Gtk Clipboard",
1474 + "@mozilla.org/widget/clipboard;1",
1475 + nsClipboardConstructor },
1476 + { "Clipboard Helper",
1477 + NS_CLIPBOARDHELPER_CID,
1478 + "@mozilla.org/widget/clipboardhelper;1",
1479 + nsClipboardHelperConstructor },
1481 { "HTML Format Converter",
1482 NS_HTMLFORMATCONVERTER_CID,
1483 "@mozilla.org/widget/htmlformatconverter;1",