diff options
Diffstat (limited to 'win/tkWinClipboard.c')
-rw-r--r-- | win/tkWinClipboard.c | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/win/tkWinClipboard.c b/win/tkWinClipboard.c new file mode 100644 index 0000000..9d4237a --- /dev/null +++ b/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. + * + * SCCS: @(#) tkWinClipboard.c 1.8 97/05/20 17:01:13 + */ + +#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. */ +{ +} |