tkMacOSXClipboard.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:9k
- /*
- * tkMacOSXClipboard.c --
- *
- * This file manages the clipboard for the Tk toolkit.
- *
- * Copyright (c) 1995-1997 Sun Microsystems, Inc.
- * Copyright 2001, Apple Computer, Inc.
- * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
- *
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- *
- * RCS: @(#) $Id: tkMacOSXClipboard.c,v 1.2.2.7 2007/06/29 03:22:01 das Exp $
- */
- #include "tkMacOSXPrivate.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 the interp's result.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- int
- TkSelGetSelection(
- 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. */
- {
- int result;
- OSStatus err;
- long length;
- ScrapRef scrapRef;
- char *buf;
- if ((selection == Tk_InternAtom(tkwin, "CLIPBOARD"))
- && (target == XA_STRING)) {
- /*
- * Get the scrap from the Macintosh global clipboard.
- */
- err = ChkErr(GetCurrentScrap, &scrapRef);
- if (err != noErr) {
- Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection),
- " GetCurrentScrap failed.", NULL);
- return TCL_ERROR;
- }
- /*
- * Try UNICODE first
- */
- err = ChkErr(GetScrapFlavorSize, scrapRef, kScrapFlavorTypeUnicode,
- &length);
- if (err == noErr && length > 0) {
- Tcl_DString ds;
- char *data;
- buf = (char *) ckalloc(length + 2);
- buf[length] = 0;
- buf[length+1] = 0; /* 2-byte unicode null */
- err = ChkErr(GetScrapFlavorData, scrapRef, kScrapFlavorTypeUnicode,
- &length, buf);
- if (err == noErr) {
- Tcl_DStringInit(&ds);
- Tcl_UniCharToUtfDString((Tcl_UniChar *)buf,
- Tcl_UniCharLen((Tcl_UniChar *)buf), &ds);
- for (data = Tcl_DStringValue(&ds); *data != ' '; data++) {
- if (*data == 'r') {
- *data = 'n';
- }
- }
- result = (*proc)(clientData, interp, Tcl_DStringValue(&ds));
- Tcl_DStringFree(&ds);
- ckfree(buf);
- return result;
- }
- }
- err = ChkErr(GetScrapFlavorSize, scrapRef, 'TEXT', &length);
- if (err != noErr) {
- Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection),
- " GetScrapFlavorSize failed.", NULL);
- return TCL_ERROR;
- }
- if (length > 0) {
- Tcl_DString encodedText;
- char *data;
- buf = (char *) ckalloc(length + 1);
- buf[length] = 0;
- err = ChkErr(GetScrapFlavorData, scrapRef, 'TEXT', &length, buf);
- if (err != noErr) {
- Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection),
- " GetScrapFlavorData failed.", NULL);
- return TCL_ERROR;
- }
- /*
- * Tcl expects 'n' not 'r' as the line break character.
- */
- for (data = buf; *data != ' '; data++) {
- if (*data == 'r') {
- *data = 'n';
- }
- }
- Tcl_ExternalToUtfDString(TkMacOSXCarbonEncoding, buf, length,
- &encodedText);
- result = (*proc)(clientData, interp,
- Tcl_DStringValue(&encodedText));
- Tcl_DStringFree(&encodedText);
- ckfree(buf);
- return result;
- }
- }
- Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection),
- " selection doesn't exist or form "",
- Tk_GetAtomName(tkwin, target), "" not defined", 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:
- * None.
- *
- *----------------------------------------------------------------------
- */
- void
- XSetSelectionOwner(
- Display *display, /* X Display. */
- Atom selection, /* What selection to own. */
- Window owner, /* Window to be the owner. */
- Time time) /* The current time? */
- {
- Tk_Window tkwin;
- TkDisplay *dispPtr;
- /*
- * 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) TkGetMainInfoList()->winPtr;
- if (selection == Tk_InternAtom(tkwin, "CLIPBOARD")) {
- /*
- * Only claim and empty the clipboard if we aren't already the
- * owner of the clipboard.
- */
- dispPtr = TkGetMainInfoList()->winPtr->dispPtr;
- if (dispPtr->clipboardActive) {
- return;
- }
- ClearCurrentScrap();
- }
- }
- /*
- *----------------------------------------------------------------------
- *
- * TkSelUpdateClipboard --
- *
- * This function is called to force the clipboard to be updated
- * after new data is added. On the Mac we don't need to do
- * anything.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- void
- TkSelUpdateClipboard(
- TkWindow *winPtr, /* Window associated with clipboard. */
- TkClipboardTarget *targetPtr)
- /* Info about the content. */
- {
- }
- /*
- *--------------------------------------------------------------
- *
- * TkSelEventProc --
- *
- * This procedure is invoked whenever a selection-related
- * event occurs.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Lots: depends on the type of event.
- *
- *--------------------------------------------------------------
- */
- void
- TkSelEventProc(
- 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(
- register XEvent *eventPtr) /* X PropertyChange event. */
- {
- }
- /*
- *----------------------------------------------------------------------
- *
- * TkSuspendClipboard --
- *
- * Handle clipboard conversion as required by the suppend event.
- * This function is also called on exit.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The local scrap is moved to the global scrap.
- *
- *----------------------------------------------------------------------
- */
- void
- TkSuspendClipboard(void)
- {
- TkClipboardTarget *targetPtr;
- TkClipboardBuffer *cbPtr;
- TkDisplay *dispPtr;
- char *buffer, *p, *endPtr, *buffPtr;
- long length;
- ScrapRef scrapRef;
- dispPtr = TkGetDisplayList();
- if ((dispPtr == NULL) || !dispPtr->clipboardActive) {
- return;
- }
- for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
- targetPtr = targetPtr->nextPtr) {
- if (targetPtr->type == XA_STRING) {
- break;
- }
- }
- if (targetPtr != NULL) {
- Tcl_DString encodedText, unicodedText;
- length = 0;
- for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
- cbPtr = cbPtr->nextPtr) {
- length += cbPtr->length;
- }
- buffer = ckalloc(length);
- buffPtr = buffer;
- for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
- cbPtr = cbPtr->nextPtr) {
- for (p = cbPtr->buffer, endPtr = p + cbPtr->length;
- p < endPtr; p++) {
- if (*p == 'n') {
- *buffPtr++ = 'r';
- } else {
- *buffPtr++ = *p;
- }
- }
- }
- ClearCurrentScrap();
- GetCurrentScrap(&scrapRef);
- Tcl_UtfToExternalDString(TkMacOSXCarbonEncoding, buffer, length,
- &encodedText);
- PutScrapFlavor(scrapRef, 'TEXT', 0, Tcl_DStringLength(&encodedText),
- Tcl_DStringValue(&encodedText));
- Tcl_DStringFree(&encodedText);
- /*
- * Also put unicode data on scrap.
- */
- Tcl_DStringInit(&unicodedText);
- Tcl_UtfToUniCharDString(buffer, length, &unicodedText);
- PutScrapFlavor(scrapRef, kScrapFlavorTypeUnicode, 0,
- Tcl_DStringLength(&unicodedText),
- Tcl_DStringValue(&unicodedText));
- Tcl_DStringFree(&unicodedText);
- ckfree(buffer);
- }
- /*
- * The system now owns the scrap. We tell Tk that it has
- * lost the selection so that it will look for it the next time
- * it needs it. (Window list NULL if quiting.)
- */
- if (TkGetMainInfoList() != NULL) {
- Tk_ClearSelection((Tk_Window) TkGetMainInfoList()->winPtr,
- Tk_InternAtom((Tk_Window) TkGetMainInfoList()->winPtr,
- "CLIPBOARD"));
- }
- return;
- }