Back to index

lightning-sunbird  0.9+nobinonly
Classes | Functions | Variables
nsClipboard.cpp File Reference
#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 <gtk/gtkclipboard.h>
#include <gtk/gtkinvisible.h>
#include <X11/Xlib.h>
#include <gdk/gdkx.h>
#include <gtk/gtkmain.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

Go to the source code of this file.

Classes

struct  retrieval_context
struct  checkEventContext

Functions

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)
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)
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)
static void DispatchSelectionNotifyEvent (GtkWidget *widget, XEvent *xevent)
static void DispatchPropertyNotifyEvent (GtkWidget *widget, XEvent *xevent)

Variables

static const int kClipboardTimeout = 500000

Class Documentation

struct checkEventContext

Definition at line 1330 of file nsClipboard.cpp.

Class Members
GtkWidget * cbWidget
Atom selAtom

Function Documentation

static Bool checkEventProc ( Display display,
XEvent *  event,
XPointer  arg 
) [static]

Definition at line 768 of file nsClipboard.cpp.

{
    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;
}

Here is the caller graph for this function:

static void clipboard_contents_received ( GtkClipboard *  clipboard,
GtkSelectionData *  selection_data,
gpointer  data 
) [static]

Definition at line 854 of file nsClipboard.cpp.

{
    retrieval_context *context = NS_STATIC_CAST(retrieval_context *, data);
    context->completed = PR_TRUE;

    if (selection_data->length >= 0)
        context->data = gtk_selection_data_copy(selection_data);
}

Here is the caller graph for this function:

static void clipboard_text_received ( GtkClipboard *  clipboard,
const gchar *  text,
gpointer  data 
) [static]

Definition at line 879 of file nsClipboard.cpp.

Here is the caller graph for this function:

void ConvertHTMLtoUCS2 ( guchar *  data,
PRInt32  dataLength,
PRUnichar **  unicodeData,
PRInt32 outUnicodeLen 
) [static]

Definition at line 618 of file nsClipboard.cpp.

{
    nsCAutoString charset;
    GetHTMLCharset(data, dataLength, charset);// get charset of HTML
    if (charset.EqualsLiteral("UTF-16")) {//current mozilla
        outUnicodeLen = (dataLength / 2) - 1;
        *unicodeData = NS_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 = NS_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
    }
}

Here is the call graph for this function:

static void DispatchPropertyNotifyEvent ( GtkWidget *  widget,
XEvent *  xevent 
) [static]

Definition at line 747 of file nsClipboard.cpp.

{
    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);
    }
}

Here is the caller graph for this function:

static void DispatchSelectionNotifyEvent ( GtkWidget *  widget,
XEvent *  xevent 
) [static]

Definition at line 733 of file nsClipboard.cpp.

{
    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);
}

Here is the caller graph for this function:

void GetHTMLCharset ( guchar *  data,
PRInt32  dataLength,
nsCString str 
) [static]

Definition at line 687 of file nsClipboard.cpp.

{
    // 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
    nsDependentCString htmlStr =
        nsDependentCString((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");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void invisible_selection_get_cb ( GtkWidget *  aWidget,
GtkSelectionData *  aSelectionData,
guint  aTime,
guint  aInfo,
nsClipboard aClipboard 
)

Definition at line 581 of file nsClipboard.cpp.

{
    aClipboard->SelectionGetEvent(aWidget, aSelectionData, aTime);
}

Here is the call graph for this function:

gboolean selection_clear_event_cb ( GtkWidget *  aWidget,
GdkEventSelection *  aEvent,
nsClipboard aClipboard 
)

Definition at line 591 of file nsClipboard.cpp.

{
    aClipboard->SelectionClearEvent(aWidget, aEvent);
    return TRUE;
}

Here is the call graph for this function:

static GtkSelectionData * wait_for_contents ( GtkClipboard *  clipboard,
GdkAtom  target 
) [static]

Definition at line 867 of file nsClipboard.cpp.

{
    retrieval_context context;
    gtk_clipboard_request_contents(clipboard, target,
                                   clipboard_contents_received,
                                   &context);

    wait_for_retrieval(clipboard, &context);
    return NS_STATIC_CAST(GtkSelectionData *, context.data);
}

Here is the call graph for this function:

static void wait_for_retrieval ( GtkClipboard *  clipboard,
retrieval_context transferData 
) [static]

Definition at line 794 of file nsClipboard.cpp.

{
    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
}

Here is the call graph for this function:

Here is the caller graph for this function:

static gchar * wait_for_text ( GtkClipboard *  clipboard) [static]

Definition at line 889 of file nsClipboard.cpp.

{
    retrieval_context context;
    gtk_clipboard_request_text(clipboard, clipboard_text_received, &context);

    wait_for_retrieval(clipboard, &context);
    return NS_STATIC_CAST(gchar *, context.data);
}

Here is the call graph for this function:


Variable Documentation

const int kClipboardTimeout = 500000 [static]

Definition at line 791 of file nsClipboard.cpp.