void TkClipCleanup( TkDisplay *dispPtr) /* Display associated with clipboard */ { if (dispPtr->clipWindow != NULL) { Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom, dispPtr->applicationAtom); Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom, dispPtr->windowAtom); Tk_DestroyWindow(dispPtr->clipWindow); Tcl_Release((ClientData) dispPtr->clipWindow); dispPtr->clipWindow = NULL; } }
int Tk_ClipboardClear( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ Tk_Window tkwin) /* Window in application that is clearing * clipboard; identifies application and * display. */ { TkWindow *winPtr = (TkWindow *) tkwin; TkDisplay *dispPtr = winPtr->dispPtr; TkClipboardTarget *targetPtr, *nextTargetPtr; TkClipboardBuffer *cbPtr, *nextCbPtr; if (dispPtr->clipWindow == NULL) { int result; result = TkClipInit(interp, dispPtr); if (result != TCL_OK) { return result; } } /* * Discard any existing clipboard data and delete the selection handler(s) * associated with that data. */ for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL; targetPtr = nextTargetPtr) { for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL; cbPtr = nextCbPtr) { ckfree(cbPtr->buffer); nextCbPtr = cbPtr->nextPtr; ckfree((char *) cbPtr); } nextTargetPtr = targetPtr->nextPtr; Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom, targetPtr->type); ckfree((char *) targetPtr); } dispPtr->clipTargetPtr = NULL; /* * Reclaim the clipboard selection if we lost it. */ if (!dispPtr->clipboardActive) { Tk_OwnSelection(dispPtr->clipWindow, dispPtr->clipboardAtom, ClipboardLostSel, dispPtr); dispPtr->clipboardActive = 1; } dispPtr->clipboardAppPtr = winPtr->mainPtr; return TCL_OK; }
void Tk_DeleteSelHandler( Tk_Window tkwin, /* Token for window. */ Atom selection, /* The selection whose handler is to be * removed. */ Atom target) /* The target whose selection handler is to be * removed. */ { TkWindow *winPtr = (TkWindow *) tkwin; register TkSelHandler *selPtr, *prevPtr; register TkSelInProgress *ipPtr; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * Find the selection handler to be deleted, or return if it doesn't * exist. */ for (selPtr = winPtr->selHandlerList, prevPtr = NULL; ; prevPtr = selPtr, selPtr = selPtr->nextPtr) { if (selPtr == NULL) { return; } if ((selPtr->selection == selection) && (selPtr->target == target)) { break; } } /* * If ConvertSelection is processing this handler, tell it that the * handler is dead. */ for (ipPtr = tsdPtr->pendingPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { if (ipPtr->selPtr == selPtr) { ipPtr->selPtr = NULL; } } /* * Free resources associated with the handler. */ if (prevPtr == NULL) { winPtr->selHandlerList = selPtr->nextPtr; } else { prevPtr->nextPtr = selPtr->nextPtr; } if ((target == XA_STRING) && (winPtr->dispPtr->utf8Atom != (Atom) NULL)) { /* * If the user asked for a STRING handler and we understand * UTF8_STRING, we may have implicitly created a UTF8_STRING handler * for them. Look for it and delete it as necessary. */ TkSelHandler *utf8selPtr; target = winPtr->dispPtr->utf8Atom; for (utf8selPtr = winPtr->selHandlerList; utf8selPtr != NULL; utf8selPtr = utf8selPtr->nextPtr) { if ((utf8selPtr->selection == selection) && (utf8selPtr->target == target)) { break; } } if (utf8selPtr != NULL) { if ((utf8selPtr->format == target) && (utf8selPtr->proc == selPtr->proc) && (utf8selPtr->size == selPtr->size)) { /* * This recursive call is OK, because we've changed the value * of 'target'. */ Tk_DeleteSelHandler(tkwin, selection, target); } } } if (selPtr->proc == HandleTclCommand) { /* * Mark the CommandInfo as deleted and free it if we can. */ ((CommandInfo*)selPtr->clientData)->interp = NULL; Tcl_EventuallyFree(selPtr->clientData, TCL_DYNAMIC); } ckfree((char *) selPtr); }
int Tk_SelectionObjCmd( ClientData clientData, /* Main window associated with * interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_Window tkwin = clientData; char *path = NULL; Atom selection; char *selName = NULL, *string; int count, index; Tcl_Obj **objs; static const char *const optionStrings[] = { "clear", "get", "handle", "own", NULL }; enum options { SELECTION_CLEAR, SELECTION_GET, SELECTION_HANDLE, SELECTION_OWN }; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum options) index) { case SELECTION_CLEAR: { static const char *const clearOptionStrings[] = { "-displayof", "-selection", NULL }; enum clearOptions { CLEAR_DISPLAYOF, CLEAR_SELECTION }; int clearIndex; for (count = objc-2, objs = ((Tcl_Obj **)objv)+2; count > 0; count-=2, objs+=2) { string = Tcl_GetString(objs[0]); if (string[0] != '-') { break; } if (count < 2) { Tcl_AppendResult(interp, "value for \"", string, "\" missing", NULL); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objs[0], clearOptionStrings, "option", 0, &clearIndex) != TCL_OK) { return TCL_ERROR; } switch ((enum clearOptions) clearIndex) { case CLEAR_DISPLAYOF: path = Tcl_GetString(objs[1]); break; case CLEAR_SELECTION: selName = Tcl_GetString(objs[1]); break; } } if (count == 1) { path = Tcl_GetString(objs[0]); } else if (count > 1) { Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?"); return TCL_ERROR; } if (path != NULL) { tkwin = Tk_NameToWindow(interp, path, tkwin); } if (tkwin == NULL) { return TCL_ERROR; } if (selName != NULL) { selection = Tk_InternAtom(tkwin, selName); } else { selection = XA_PRIMARY; } Tk_ClearSelection(tkwin, selection); break; } case SELECTION_GET: { Atom target; char *targetName = NULL; Tcl_DString selBytes; int result; static const char *const getOptionStrings[] = { "-displayof", "-selection", "-type", NULL }; enum getOptions { GET_DISPLAYOF, GET_SELECTION, GET_TYPE }; int getIndex; for (count = objc-2, objs = ((Tcl_Obj **)objv)+2; count>0; count-=2, objs+=2) { string = Tcl_GetString(objs[0]); if (string[0] != '-') { break; } if (count < 2) { Tcl_AppendResult(interp, "value for \"", string, "\" missing", NULL); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objs[0], getOptionStrings, "option", 0, &getIndex) != TCL_OK) { return TCL_ERROR; } switch ((enum getOptions) getIndex) { case GET_DISPLAYOF: path = Tcl_GetString(objs[1]); break; case GET_SELECTION: selName = Tcl_GetString(objs[1]); break; case GET_TYPE: targetName = Tcl_GetString(objs[1]); break; } } if (path != NULL) { tkwin = Tk_NameToWindow(interp, path, tkwin); } if (tkwin == NULL) { return TCL_ERROR; } if (selName != NULL) { selection = Tk_InternAtom(tkwin, selName); } else { selection = XA_PRIMARY; } if (count > 1) { Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?"); return TCL_ERROR; } else if (count == 1) { target = Tk_InternAtom(tkwin, Tcl_GetString(objs[0])); } else if (targetName != NULL) { target = Tk_InternAtom(tkwin, targetName); } else { target = XA_STRING; } Tcl_DStringInit(&selBytes); result = Tk_GetSelection(interp, tkwin, selection, target, SelGetProc, &selBytes); if (result == TCL_OK) { Tcl_DStringResult(interp, &selBytes); } else { Tcl_DStringFree(&selBytes); } return result; } case SELECTION_HANDLE: { Atom target, format; char *targetName = NULL; char *formatName = NULL; register CommandInfo *cmdInfoPtr; int cmdLength; static const char *const handleOptionStrings[] = { "-format", "-selection", "-type", NULL }; enum handleOptions { HANDLE_FORMAT, HANDLE_SELECTION, HANDLE_TYPE }; int handleIndex; for (count = objc-2, objs = ((Tcl_Obj **)objv)+2; count > 0; count-=2, objs+=2) { string = Tcl_GetString(objs[0]); if (string[0] != '-') { break; } if (count < 2) { Tcl_AppendResult(interp, "value for \"", string, "\" missing", NULL); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objs[0],handleOptionStrings, "option", 0, &handleIndex) != TCL_OK) { return TCL_ERROR; } switch ((enum handleOptions) handleIndex) { case HANDLE_FORMAT: formatName = Tcl_GetString(objs[1]); break; case HANDLE_SELECTION: selName = Tcl_GetString(objs[1]); break; case HANDLE_TYPE: targetName = Tcl_GetString(objs[1]); break; } } if ((count < 2) || (count > 4)) { Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...? window command"); return TCL_ERROR; } tkwin = Tk_NameToWindow(interp, Tcl_GetString(objs[0]), tkwin); if (tkwin == NULL) { return TCL_ERROR; } if (selName != NULL) { selection = Tk_InternAtom(tkwin, selName); } else { selection = XA_PRIMARY; } if (count > 2) { target = Tk_InternAtom(tkwin, Tcl_GetString(objs[2])); } else if (targetName != NULL) { target = Tk_InternAtom(tkwin, targetName); } else { target = XA_STRING; } if (count > 3) { format = Tk_InternAtom(tkwin, Tcl_GetString(objs[3])); } else if (formatName != NULL) { format = Tk_InternAtom(tkwin, formatName); } else { format = XA_STRING; } string = Tcl_GetStringFromObj(objs[1], &cmdLength); if (cmdLength == 0) { Tk_DeleteSelHandler(tkwin, selection, target); } else { cmdInfoPtr = (CommandInfo *) ckalloc((unsigned) ( sizeof(CommandInfo) - 3 + cmdLength)); cmdInfoPtr->interp = interp; cmdInfoPtr->charOffset = 0; cmdInfoPtr->byteOffset = 0; cmdInfoPtr->buffer[0] = '\0'; cmdInfoPtr->cmdLength = cmdLength; strcpy(cmdInfoPtr->command, string); Tk_CreateSelHandler(tkwin, selection, target, HandleTclCommand, cmdInfoPtr, format); } return TCL_OK; } case SELECTION_OWN: { register LostCommand *lostPtr; char *script = NULL; int cmdLength; static const char *const ownOptionStrings[] = { "-command", "-displayof", "-selection", NULL }; enum ownOptions { OWN_COMMAND, OWN_DISPLAYOF, OWN_SELECTION }; int ownIndex; for (count = objc-2, objs = ((Tcl_Obj **)objv)+2; count > 0; count-=2, objs+=2) { string = Tcl_GetString(objs[0]); if (string[0] != '-') { break; } if (count < 2) { Tcl_AppendResult(interp, "value for \"", string, "\" missing", NULL); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objs[0], ownOptionStrings, "option", 0, &ownIndex) != TCL_OK) { return TCL_ERROR; } switch ((enum ownOptions) ownIndex) { case OWN_COMMAND: script = Tcl_GetString(objs[1]); break; case OWN_DISPLAYOF: path = Tcl_GetString(objs[1]); break; case OWN_SELECTION: selName = Tcl_GetString(objs[1]); break; } } if (count > 2) { Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...? ?window?"); return TCL_ERROR; } if (selName != NULL) { selection = Tk_InternAtom(tkwin, selName); } else { selection = XA_PRIMARY; } if (count == 0) { TkSelectionInfo *infoPtr; TkWindow *winPtr; if (path != NULL) { tkwin = Tk_NameToWindow(interp, path, tkwin); } if (tkwin == NULL) { return TCL_ERROR; } winPtr = (TkWindow *)tkwin; for (infoPtr = winPtr->dispPtr->selectionInfoPtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) { if (infoPtr->selection == selection) { break; } } /* * Ignore the internal clipboard window. */ if ((infoPtr != NULL) && (infoPtr->owner != winPtr->dispPtr->clipWindow)) { Tcl_SetResult(interp, Tk_PathName(infoPtr->owner), TCL_STATIC); } return TCL_OK; } tkwin = Tk_NameToWindow(interp, Tcl_GetString(objs[0]), tkwin); if (tkwin == NULL) { return TCL_ERROR; } if (count == 2) { script = Tcl_GetString(objs[1]); } if (script == NULL) { Tk_OwnSelection(tkwin, selection, NULL, NULL); return TCL_OK; } cmdLength = strlen(script); lostPtr = (LostCommand *) ckalloc((unsigned) (sizeof(LostCommand) - 3 + cmdLength)); lostPtr->interp = interp; strcpy(lostPtr->command, script); Tk_OwnSelection(tkwin, selection, LostSelection, lostPtr); return TCL_OK; } } return TCL_OK; }