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; long length, offset = 0; Handle handle; if ((selection == Tk_InternAtom(tkwin, "CLIPBOARD")) && (target == XA_STRING)) { /* * Get the scrap from the Macintosh global clipboard. */ handle = NewHandle(1); length = GetScrap(handle, 'TEXT', &offset); if (length > 0) { Tcl_DString encodedText; SetHandleSize(handle, (Size) length + 1); HLock(handle); (*handle)[length] = '\0'; Tcl_ExternalToUtfDString(NULL, *handle, length, &encodedText); result = (*proc)(clientData, interp, Tcl_DStringValue(&encodedText)); Tcl_DStringFree(&encodedText); HUnlock(handle); DisposeHandle(handle); return result; } DisposeHandle(handle); } Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection), " selection doesn't exist or form \"", Tk_GetAtomName(tkwin, target), "\" not defined", (char *) NULL); return TCL_ERROR; }
void TkWmProtocolEventProc( TkWindow *winPtr, /* Window to which the event was sent. */ XEvent *eventPtr) /* X event. */ { WmInfo *wmPtr; ProtocolHandler *protPtr; Tcl_Interp *interp; Atom protocol; int result; wmPtr = winPtr->wmInfoPtr; if (wmPtr == NULL) { return; } protocol = (Atom) eventPtr->xclient.data.l[0]; for (protPtr = wmPtr->protPtr; protPtr != NULL; protPtr = protPtr->nextPtr) { if (protocol == protPtr->protocol) { Tcl_Preserve(protPtr); interp = protPtr->interp; Tcl_Preserve(interp); result = Tcl_EvalEx(interp, protPtr->command, -1, TCL_EVAL_GLOBAL); if (result != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (command for \""); Tcl_AddErrorInfo(interp, Tk_GetAtomName((Tk_Window) winPtr, protocol)); Tcl_AddErrorInfo(interp, "\" window manager protocol)"); Tcl_BackgroundError(interp); } Tcl_Release(interp); Tcl_Release(protPtr); return; } } /* * No handler was present for this protocol. If this is a WM_DELETE_WINDOW * message then just destroy the window. */ if (protocol == Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW")) { Tk_DestroyWindow((Tk_Window) winPtr); } }
int Tk_GetSelection( 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, /* Function to call to process the selection, * once it has been retrieved. */ ClientData clientData) /* Arbitrary value to pass to proc. */ { TkWindow *winPtr = (TkWindow *) tkwin; TkDisplay *dispPtr = winPtr->dispPtr; TkSelectionInfo *infoPtr; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (dispPtr->multipleAtom == None) { TkSelInit(tkwin); } /* * If the selection is owned by a window managed by this process, then * call the retrieval function directly, rather than going through the X * server (it's dangerous to go through the X server in this case because * it could result in deadlock if an INCR-style selection results). */ for (infoPtr = dispPtr->selectionInfoPtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) { if (infoPtr->selection == selection) { break; } } if (infoPtr != NULL) { register TkSelHandler *selPtr; int offset, result, count; char buffer[TK_SEL_BYTES_AT_ONCE+1]; TkSelInProgress ip; for (selPtr = ((TkWindow *) infoPtr->owner)->selHandlerList; selPtr != NULL; selPtr = selPtr->nextPtr) { if (selPtr->target==target && selPtr->selection==selection) { break; } } if (selPtr == NULL) { Atom type; count = TkSelDefaultSelection(infoPtr, target, buffer, TK_SEL_BYTES_AT_ONCE, &type); if (count > TK_SEL_BYTES_AT_ONCE) { Tcl_Panic("selection handler returned too many bytes"); } if (count < 0) { goto cantget; } buffer[count] = 0; result = (*proc)(clientData, interp, buffer); } else { offset = 0; result = TCL_OK; ip.selPtr = selPtr; ip.nextPtr = tsdPtr->pendingPtr; tsdPtr->pendingPtr = &ip; while (1) { count = (selPtr->proc)(selPtr->clientData, offset, buffer, TK_SEL_BYTES_AT_ONCE); if ((count < 0) || (ip.selPtr == NULL)) { tsdPtr->pendingPtr = ip.nextPtr; goto cantget; } if (count > TK_SEL_BYTES_AT_ONCE) { Tcl_Panic("selection handler returned too many bytes"); } buffer[count] = '\0'; result = (*proc)(clientData, interp, buffer); if ((result != TCL_OK) || (count < TK_SEL_BYTES_AT_ONCE) || (ip.selPtr == NULL)) { break; } offset += count; } tsdPtr->pendingPtr = ip.nextPtr; } return result; } /* * The selection is owned by some other process. */ return TkSelGetSelection(interp, tkwin, selection, target, proc, clientData); cantget: Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection), " selection doesn't exist or form \"", Tk_GetAtomName(tkwin, target), "\" not defined", NULL); return TCL_ERROR; }
int TkSelDefaultSelection( TkSelectionInfo *infoPtr, /* Info about selection being retrieved. */ Atom target, /* Desired form of selection. */ char *buffer, /* Place to put selection characters. */ int maxBytes, /* Maximum # of bytes to store at buffer. */ Atom *typePtr) /* Store here the type of the selection, for * use in converting to proper X format. */ { register TkWindow *winPtr = (TkWindow *) infoPtr->owner; TkDisplay *dispPtr = winPtr->dispPtr; if (target == dispPtr->timestampAtom) { if (maxBytes < 20) { return -1; } sprintf(buffer, "0x%x", (unsigned int) infoPtr->time); *typePtr = XA_INTEGER; return strlen(buffer); } if (target == dispPtr->targetsAtom) { register TkSelHandler *selPtr; int length; Tcl_DString ds; if (maxBytes < 50) { return -1; } Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, "MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW", -1); for (selPtr = winPtr->selHandlerList; selPtr != NULL; selPtr = selPtr->nextPtr) { if ((selPtr->selection == infoPtr->selection) && (selPtr->target != dispPtr->applicationAtom) && (selPtr->target != dispPtr->windowAtom)) { const char *atomString = Tk_GetAtomName((Tk_Window) winPtr, selPtr->target); Tcl_DStringAppendElement(&ds, atomString); } } length = Tcl_DStringLength(&ds); if (length >= maxBytes) { Tcl_DStringFree(&ds); return -1; } memcpy(buffer, Tcl_DStringValue(&ds), (unsigned) (1+length)); Tcl_DStringFree(&ds); *typePtr = XA_ATOM; return length; } if (target == dispPtr->applicationAtom) { int length; Tk_Uid name = winPtr->mainPtr->winPtr->nameUid; length = strlen(name); if (maxBytes <= length) { return -1; } strcpy(buffer, name); *typePtr = XA_STRING; return length; } if (target == dispPtr->windowAtom) { int length; char *name = winPtr->pathName; length = strlen(name); if (maxBytes <= length) { return -1; } strcpy(buffer, name); *typePtr = XA_STRING; return length; } return -1; }
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; int 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=GetCurrentScrap(&scrapRef); if (err != noErr) { Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection), " GetCurrentScrap failed.", (char *) NULL); return TCL_ERROR; } err=GetScrapFlavorSize(scrapRef,'TEXT',&length); if (err != noErr) { Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection), " GetScrapFlavorSize failed.", (char *) NULL); return TCL_ERROR; } if (length > 0) { Tcl_DString encodedText; buf = (char *)ckalloc(length+1); buf[length] = 0; err = GetScrapFlavorData(scrapRef, 'TEXT', &length, buf); if (err != noErr) { Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection), " GetScrapFlavorData failed.", (char *) NULL); return TCL_ERROR; } 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", (char *) NULL); return TCL_ERROR; }
int Tk_ClipboardAppend( Tcl_Interp *interp, /* Used for error reporting. */ Tk_Window tkwin, /* Window that selects a display. */ Atom type, /* The desired conversion type for this * clipboard item, e.g. STRING or LENGTH. */ Atom format, /* Format in which the selection information * should be returned to the requestor. */ const char *buffer) /* NULL terminated string containing the data * to be added to the clipboard. */ { TkWindow *winPtr = (TkWindow *) tkwin; TkDisplay *dispPtr = winPtr->dispPtr; TkClipboardTarget *targetPtr; TkClipboardBuffer *cbPtr; /* * If this application doesn't already own the clipboard, clear the * clipboard. If we don't own the clipboard selection, claim it. */ if (dispPtr->clipboardAppPtr != winPtr->mainPtr) { Tk_ClipboardClear(interp, tkwin); } else if (!dispPtr->clipboardActive) { Tk_OwnSelection(dispPtr->clipWindow, dispPtr->clipboardAtom, ClipboardLostSel, dispPtr); dispPtr->clipboardActive = 1; } /* * Check to see if the specified target is already present on the * clipboard. If it isn't, we need to create a new target; otherwise, we * just append the new buffer to the clipboard list. */ for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL; targetPtr = targetPtr->nextPtr) { if (targetPtr->type == type) { break; } } if (targetPtr == NULL) { targetPtr = (TkClipboardTarget *) ckalloc(sizeof(TkClipboardTarget)); targetPtr->type = type; targetPtr->format = format; targetPtr->firstBufferPtr = targetPtr->lastBufferPtr = NULL; targetPtr->nextPtr = dispPtr->clipTargetPtr; dispPtr->clipTargetPtr = targetPtr; Tk_CreateSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom, type, ClipboardHandler, targetPtr, format); } else if (targetPtr->format != format) { Tcl_AppendResult(interp, "format \"", Tk_GetAtomName(tkwin, format), "\" does not match current format \"", Tk_GetAtomName(tkwin, targetPtr->format),"\" for ", Tk_GetAtomName(tkwin, type), NULL); return TCL_ERROR; } /* * Append a new buffer to the buffer chain. */ cbPtr = (TkClipboardBuffer *) ckalloc(sizeof(TkClipboardBuffer)); cbPtr->nextPtr = NULL; if (targetPtr->lastBufferPtr != NULL) { targetPtr->lastBufferPtr->nextPtr = cbPtr; } else { targetPtr->firstBufferPtr = cbPtr; } targetPtr->lastBufferPtr = cbPtr; cbPtr->length = strlen(buffer); cbPtr->buffer = (char *) ckalloc((unsigned) (cbPtr->length + 1)); strcpy(cbPtr->buffer, buffer); TkSelUpdateClipboard((TkWindow *) dispPtr->clipWindow, targetPtr); return TCL_OK; }
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. */ { char *data, *destPtr; Tcl_DString ds; HGLOBAL handle; Tcl_Encoding encoding; int result, locale; if ((selection != Tk_InternAtom(tkwin, "CLIPBOARD")) || (target != XA_STRING) || !OpenClipboard(NULL)) { goto error; } /* * Attempt to get the data in Unicode form if available as this is less * work that CF_TEXT. */ result = TCL_ERROR; if (IsClipboardFormatAvailable(CF_UNICODETEXT)) { handle = GetClipboardData(CF_UNICODETEXT); if (!handle) { CloseClipboard(); goto error; } data = GlobalLock(handle); Tcl_DStringInit(&ds); Tcl_UniCharToUtfDString((Tcl_UniChar *)data, Tcl_UniCharLen((Tcl_UniChar *)data), &ds); GlobalUnlock(handle); } else if (IsClipboardFormatAvailable(CF_TEXT)) { /* * Determine the encoding to use to convert this text. */ if (IsClipboardFormatAvailable(CF_LOCALE)) { handle = GetClipboardData(CF_LOCALE); if (!handle) { CloseClipboard(); goto error; } /* * Get the locale identifier, determine the proper code page to * use, and find the corresponding encoding. */ Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, "cp######", -1); data = GlobalLock(handle); /* * Even though the documentation claims that GetLocaleInfo expects * an LCID, on Windows 9x it really seems to expect a LanguageID. */ locale = LANGIDFROMLCID(*((int*)data)); GetLocaleInfoA(locale, LOCALE_IDEFAULTANSICODEPAGE, Tcl_DStringValue(&ds)+2, Tcl_DStringLength(&ds)-2); GlobalUnlock(handle); encoding = Tcl_GetEncoding(NULL, Tcl_DStringValue(&ds)); Tcl_DStringFree(&ds); } else { encoding = NULL; } /* * Fetch the text and convert it to UTF. */ handle = GetClipboardData(CF_TEXT); if (!handle) { if (encoding) { Tcl_FreeEncoding(encoding); } CloseClipboard(); goto error; } data = GlobalLock(handle); Tcl_ExternalToUtfDString(encoding, data, -1, &ds); GlobalUnlock(handle); if (encoding) { Tcl_FreeEncoding(encoding); } } else { CloseClipboard(); goto error; } /* * Translate CR/LF to LF. */ data = destPtr = Tcl_DStringValue(&ds); while (*data) { if (data[0] == '\r' && data[1] == '\n') { data++; } else { *destPtr++ = *data++; } } *destPtr = '\0'; /* * Pass the data off to the selection procedure. */ result = proc(clientData, interp, Tcl_DStringValue(&ds)); Tcl_DStringFree(&ds); CloseClipboard(); return result; error: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s selection doesn't exist or form \"%s\" not defined", Tk_GetAtomName(tkwin, selection), Tk_GetAtomName(tkwin, target))); Tcl_SetErrorCode(interp, "TK", "SELECTION", "EXISTS", NULL); return TCL_ERROR; }