summaryrefslogtreecommitdiff
path: root/tk/win/tkWinClipboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'tk/win/tkWinClipboard.c')
-rw-r--r--tk/win/tkWinClipboard.c291
1 files changed, 291 insertions, 0 deletions
diff --git a/tk/win/tkWinClipboard.c b/tk/win/tkWinClipboard.c
new file mode 100644
index 00000000000..d7d73d71995
--- /dev/null
+++ b/tk/win/tkWinClipboard.c
@@ -0,0 +1,291 @@
+/*
+ * tkWinClipboard.c --
+ *
+ * This file contains functions for managing the clipboard.
+ *
+ * Copyright (c) 1995 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id$
+ */
+
+#include "tkWinInt.h"
+#include "tkSelect.h"
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkSelGetSelection --
+ *
+ * Retrieve the specified selection from another process. For
+ * now, only fetching XA_STRING from CLIPBOARD is supported.
+ * Eventually other types should be allowed.
+ *
+ * Results:
+ * The return value is a standard Tcl return value.
+ * If an error occurs (such as no selection exists)
+ * then an error message is left in interp->result.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkSelGetSelection(interp, tkwin, selection, target, proc, clientData)
+ Tcl_Interp *interp; /* Interpreter to use for reporting
+ * errors. */
+ Tk_Window tkwin; /* Window on whose behalf to retrieve
+ * the selection (determines display
+ * from which to retrieve). */
+ Atom selection; /* Selection to retrieve. */
+ Atom target; /* Desired form in which selection
+ * is to be returned. */
+ Tk_GetSelProc *proc; /* Procedure to call to process the
+ * selection, once it has been retrieved. */
+ ClientData clientData; /* Arbitrary value to pass to proc. */
+{
+ char *data, *buffer, *destPtr;
+ HGLOBAL handle;
+ int result, length;
+
+ if ((selection == Tk_InternAtom(tkwin, "CLIPBOARD"))
+ && (target == XA_STRING)) {
+ if (OpenClipboard(NULL)) {
+ handle = GetClipboardData(CF_TEXT);
+ if (handle != NULL) {
+ data = GlobalLock(handle);
+ length = strlen(data);
+ buffer = ckalloc(length+1);
+ destPtr = buffer;
+ while (*data != '\0') {
+ if (*data != '\r') {
+ *destPtr = *data;
+ destPtr++;
+ }
+ data++;
+ }
+ *destPtr = '\0';
+ GlobalUnlock(handle);
+ CloseClipboard();
+ result = (*proc)(clientData, interp, buffer);
+ ckfree(buffer);
+ return result;
+ }
+ CloseClipboard();
+ }
+ }
+
+ Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection),
+ " selection doesn't exist or form \"", Tk_GetAtomName(tkwin, target),
+ "\" not defined", (char *) NULL);
+ return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkSetSelectionOwner --
+ *
+ * This function claims ownership of the specified selection.
+ * If the selection is CLIPBOARD, then we empty the system
+ * clipboard.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Empties the system clipboard, and claims ownership.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+XSetSelectionOwner(display, selection, owner, time)
+ Display* display;
+ Atom selection;
+ Window owner;
+ Time time;
+{
+ HWND hwnd = owner ? TkWinGetHWND(owner) : NULL;
+ Tk_Window tkwin;
+
+ /*
+ * This is a gross hack because the Tk_InternAtom interface is broken.
+ * It expects a Tk_Window, even though it only needs a Tk_Display.
+ */
+
+ tkwin = (Tk_Window)tkMainWindowList->winPtr;
+
+ if (selection == Tk_InternAtom(tkwin, "CLIPBOARD")) {
+
+ /*
+ * Only claim and empty the clipboard if we aren't already the
+ * owner of the clipboard.
+ */
+
+ if (GetClipboardOwner() != hwnd) {
+ OpenClipboard(hwnd);
+ EmptyClipboard();
+ SetClipboardData(CF_TEXT, NULL);
+ CloseClipboard();
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkWinClipboardRender --
+ *
+ * This function supplies the contents of the clipboard in
+ * response to a WM_RENDERFORMAT message.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Sets the contents of the clipboard.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkWinClipboardRender(dispPtr, format)
+ TkDisplay *dispPtr;
+ UINT format;
+{
+ TkClipboardTarget *targetPtr;
+ TkClipboardBuffer *cbPtr;
+ HGLOBAL handle;
+ char *buffer, *p, *endPtr;
+ int length;
+
+ for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
+ targetPtr = targetPtr->nextPtr) {
+ if (targetPtr->type == XA_STRING)
+ break;
+ }
+ length = 0;
+ if (targetPtr != NULL) {
+ for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
+ cbPtr = cbPtr->nextPtr) {
+ length += cbPtr->length;
+ for (p = cbPtr->buffer, endPtr = p + cbPtr->length;
+ p < endPtr; p++) {
+ if (*p == '\n') {
+ length++;
+ }
+ }
+ }
+ }
+ handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, length+1);
+ if (!handle) {
+ return;
+ }
+ buffer = GlobalLock(handle);
+ if (targetPtr != NULL) {
+ for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
+ cbPtr = cbPtr->nextPtr) {
+ for (p = cbPtr->buffer, endPtr = p + cbPtr->length;
+ p < endPtr; p++) {
+ if (*p == '\n') {
+ *buffer++ = '\r';
+ }
+ *buffer++ = *p;
+ }
+ }
+ }
+ *buffer = '\0';
+ GlobalUnlock(handle);
+ SetClipboardData(CF_TEXT, handle);
+ return;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkSelUpdateClipboard --
+ *
+ * This function is called to force the clipboard to be updated
+ * after new data is added.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Clears the current contents of the clipboard.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkSelUpdateClipboard(winPtr, targetPtr)
+ TkWindow *winPtr;
+ TkClipboardTarget *targetPtr;
+{
+ HWND hwnd = TkWinGetHWND(winPtr->window);
+
+ OpenClipboard(hwnd);
+ EmptyClipboard();
+ SetClipboardData(CF_TEXT, NULL);
+ CloseClipboard();
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TkSelEventProc --
+ *
+ * This procedure is invoked whenever a selection-related
+ * event occurs.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Lots: depends on the type of event.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+TkSelEventProc(tkwin, eventPtr)
+ Tk_Window tkwin; /* Window for which event was
+ * targeted. */
+ register XEvent *eventPtr; /* X event: either SelectionClear,
+ * SelectionRequest, or
+ * SelectionNotify. */
+{
+ if (eventPtr->type == SelectionClear) {
+ TkSelClearSelection(tkwin, eventPtr);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkSelPropProc --
+ *
+ * This procedure is invoked when property-change events
+ * occur on windows not known to the toolkit. This is a stub
+ * function under Windows.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkSelPropProc(eventPtr)
+ register XEvent *eventPtr; /* X PropertyChange event. */
+{
+}