ClientData clientData, int offset, char *buffer,
int maxBytes));
static void ClipboardLostSel _ANSI_ARGS_((ClientData clientData));
+static int ClipboardGetProc _ANSI_ARGS_((ClientData clientData,
+ Tcl_Interp *interp, char *portion));
\f
/*
*----------------------------------------------------------------------
{
TkDisplay *dispPtr = (TkDisplay *) clientData;
size_t length;
- char *p;
+ CONST char *p;
p = dispPtr->clipboardAppPtr->winPtr->nameUid;
length = strlen(p);
/*
*----------------------------------------------------------------------
*
- * Tk_ClipboardCmd --
+ * Tk_ClipboardObjCmd --
*
* This procedure is invoked to process the "clipboard" Tcl
* command. See the user documentation for details on what
*/
int
-Tk_ClipboardCmd(clientData, interp, argc, argv)
+Tk_ClipboardObjCmd(clientData, interp, objc, objv)
ClientData clientData; /* Main window associated with
* interpreter. */
Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- char **argv; /* Argument strings. */
+ int objc; /* Number of arguments. */
+ Tcl_Obj *CONST objv[]; /* Argument strings. */
{
Tk_Window tkwin = (Tk_Window) clientData;
char *path = NULL;
- size_t length;
- int count;
- char c;
- char **args;
+ Atom selection;
+ static CONST char *optionStrings[] = { "append", "clear", "get", NULL };
+ enum options { CLIPBOARD_APPEND, CLIPBOARD_CLEAR, CLIPBOARD_GET };
+ int index, i;
- if (argc < 2) {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " option ?arg arg ...?\"", (char *) NULL);
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
return TCL_ERROR;
}
- c = argv[1][0];
- length = strlen(argv[1]);
- if ((c == 'a') && (strncmp(argv[1], "append", length) == 0)) {
- Atom target, format;
- char *targetName = NULL;
- char *formatName = NULL;
-
- for (count = argc-2, args = argv+2; count > 1; count -= 2, args += 2) {
- if (args[0][0] != '-') {
- break;
+
+ if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ switch ((enum options) index) {
+ case CLIPBOARD_APPEND: {
+ Atom target, format;
+ char *targetName = NULL;
+ char *formatName = NULL;
+ char *string;
+ static CONST char *appendOptionStrings[] = {
+ "-displayof", "-format", "-type", NULL
+ };
+ enum appendOptions { APPEND_DISPLAYOF, APPEND_FORMAT,
+ APPEND_TYPE };
+ int subIndex, length;
+
+ for (i = 2; i < objc - 1; i++) {
+ string = Tcl_GetStringFromObj(objv[i], &length);
+ if (string[0] != '-') {
+ break;
+ }
+
+ /*
+ * If the argument is "--", it signifies the end of arguments.
+ */
+ if (string[1] == '-' && length == 2) {
+ i++;
+ break;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[i], appendOptionStrings,
+ "option", 0, &subIndex) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Increment i so that it points to the value for the flag
+ * instead of the flag itself.
+ */
+
+ i++;
+ if (i >= objc) {
+ Tcl_AppendResult(interp, "value for \"", string,
+ "\" missing", (char *) NULL);
+ return TCL_ERROR;
+ }
+ switch ((enum appendOptions) subIndex) {
+ case APPEND_DISPLAYOF:
+ path = Tcl_GetString(objv[i]);
+ break;
+ case APPEND_FORMAT:
+ formatName = Tcl_GetString(objv[i]);
+ break;
+ case APPEND_TYPE:
+ targetName = Tcl_GetString(objv[i]);
+ break;
+ }
}
- c = args[0][1];
- length = strlen(args[0]);
- if ((c == '-') && (length == 2)) {
- args++;
- count--;
- break;
+ if (objc - i != 1) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?options? data");
+ return TCL_ERROR;
}
- if ((c == 'd') && (strncmp(args[0], "-displayof", length) == 0)) {
- path = args[1];
- } else if ((c == 'f')
- && (strncmp(args[0], "-format", length) == 0)) {
- formatName = args[1];
- } else if ((c == 't')
- && (strncmp(args[0], "-type", length) == 0)) {
- targetName = args[1];
- } else {
- Tcl_AppendResult(interp, "unknown option \"", args[0],
- "\"", (char *) NULL);
+ if (path != NULL) {
+ tkwin = Tk_NameToWindow(interp, path, tkwin);
+ }
+ if (tkwin == NULL) {
return TCL_ERROR;
}
+ if (targetName != NULL) {
+ target = Tk_InternAtom(tkwin, targetName);
+ } else {
+ target = XA_STRING;
+ }
+ if (formatName != NULL) {
+ format = Tk_InternAtom(tkwin, formatName);
+ } else {
+ format = XA_STRING;
+ }
+ return Tk_ClipboardAppend(interp, tkwin, target, format,
+ Tcl_GetString(objv[i]));
}
- if (count != 1) {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " append ?options? data\"", (char *) NULL);
- return TCL_ERROR;
- }
- if (path != NULL) {
- tkwin = Tk_NameToWindow(interp, path, tkwin);
- }
- if (tkwin == NULL) {
- return TCL_ERROR;
- }
- if (targetName != NULL) {
- target = Tk_InternAtom(tkwin, targetName);
- } else {
- target = XA_STRING;
- }
- if (formatName != NULL) {
- format = Tk_InternAtom(tkwin, formatName);
- } else {
- format = XA_STRING;
+ case CLIPBOARD_CLEAR: {
+ static CONST char *clearOptionStrings[] = { "-displayof", NULL };
+ enum clearOptions { CLEAR_DISPLAYOF };
+ int subIndex;
+ if (objc != 2 && objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?");
+ return TCL_ERROR;
+ }
+
+ if (objc == 4) {
+ if (Tcl_GetIndexFromObj(interp, objv[2], clearOptionStrings,
+ "option", 0, &subIndex) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if ((enum clearOptions) subIndex == CLEAR_DISPLAYOF) {
+ path = Tcl_GetString(objv[3]);
+ }
+ }
+ if (path != NULL) {
+ tkwin = Tk_NameToWindow(interp, path, tkwin);
+ }
+ if (tkwin == NULL) {
+ return TCL_ERROR;
+ }
+ return Tk_ClipboardClear(interp, tkwin);
}
- return Tk_ClipboardAppend(interp, tkwin, target, format, args[0]);
- } else if ((c == 'c') && (strncmp(argv[1], "clear", length) == 0)) {
- for (count = argc-2, args = argv+2; count > 0; count -= 2, args += 2) {
- if (args[0][0] != '-') {
- break;
+ case CLIPBOARD_GET: {
+ Atom target;
+ char *targetName = NULL;
+ Tcl_DString selBytes;
+ int result;
+ char *string;
+ static CONST char *getOptionStrings[] = {
+ "-displayof", "-type", NULL
+ };
+ enum getOptions { APPEND_DISPLAYOF, APPEND_TYPE };
+ int subIndex;
+
+ for (i = 2; i < objc; i++) {
+ string = Tcl_GetString(objv[i]);
+ if (string[0] != '-') {
+ break;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[i], getOptionStrings,
+ "option", 0, &subIndex) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ i++;
+ if (i >= objc) {
+ Tcl_AppendResult(interp, "value for \"", string,
+ "\" missing", (char *) NULL);
+ return TCL_ERROR;
+ }
+ switch ((enum getOptions) subIndex) {
+ case APPEND_DISPLAYOF:
+ path = Tcl_GetString(objv[i]);
+ break;
+ case APPEND_TYPE:
+ targetName = Tcl_GetString(objv[i]);
+ break;
+ }
+ }
+ if (path != NULL) {
+ tkwin = Tk_NameToWindow(interp, path, tkwin);
}
- if (count < 2) {
- Tcl_AppendResult(interp, "value for \"", *args,
- "\" missing", (char *) NULL);
+ if (tkwin == NULL) {
return TCL_ERROR;
}
- c = args[0][1];
- length = strlen(args[0]);
- if ((c == 'd') && (strncmp(args[0], "-displayof", length) == 0)) {
- path = args[1];
- } else {
- Tcl_AppendResult(interp, "unknown option \"", args[0],
- "\"", (char *) NULL);
+ selection = Tk_InternAtom(tkwin, "CLIPBOARD");
+
+ if (objc - i > 1) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?options?");
return TCL_ERROR;
+ } else if (objc - i == 1) {
+ target = Tk_InternAtom(tkwin, Tcl_GetString(objv[i]));
+ } else if (targetName != NULL) {
+ target = Tk_InternAtom(tkwin, targetName);
+ } else {
+ target = XA_STRING;
}
+
+ Tcl_DStringInit(&selBytes);
+ result = Tk_GetSelection(interp, tkwin, selection, target,
+ ClipboardGetProc, (ClientData) &selBytes);
+ if (result == TCL_OK) {
+ Tcl_DStringResult(interp, &selBytes);
+ } else {
+ Tcl_DStringFree(&selBytes);
+ }
+ return result;
}
- if (count > 0) {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " clear ?options?\"", (char *) NULL);
- return TCL_ERROR;
- }
- if (path != NULL) {
- tkwin = Tk_NameToWindow(interp, path, tkwin);
- }
- if (tkwin == NULL) {
- return TCL_ERROR;
- }
- return Tk_ClipboardClear(interp, tkwin);
- } else {
- char buf[100 + TCL_INTEGER_SPACE];
-
- sprintf(buf, "bad option \"%.50s\": must be clear or append", argv[1]);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
- return TCL_ERROR;
+ }
+ return TCL_OK;
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkClipCleanup --
+ *
+ * This procedure is called to cleanup resources associated with
+ * claiming clipboard ownership and for receiving selection get
+ * results. This function is called in tkWindow.c. This has to be
+ * called by the display cleanup function because we still need the
+ * access display elements.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Resources are freed - the clipboard may no longer be used.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkClipCleanup(dispPtr)
+ 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;
}
}
\f
if (dispPtr->clipWindow == NULL) {
return TCL_ERROR;
}
+ Tcl_Preserve((ClientData) dispPtr->clipWindow);
atts.override_redirect = True;
Tk_ChangeWindowAttributes(dispPtr->clipWindow, CWOverrideRedirect, &atts);
Tk_MakeWindowExist(dispPtr->clipWindow);
(ClientData) dispPtr, XA_STRING);
return TCL_OK;
}
+\f
+/*
+ *--------------------------------------------------------------
+ *
+ * ClipboardGetProc --
+ *
+ * This procedure is invoked to process pieces of the selection
+ * as they arrive during "clipboard get" commands.
+ *
+ * Results:
+ * Always returns TCL_OK.
+ *
+ * Side effects:
+ * Bytes get appended to the dynamic string pointed to by the
+ * clientData argument.
+ *
+ *--------------------------------------------------------------
+ */
+
+ /* ARGSUSED */
+static int
+ClipboardGetProc(clientData, interp, portion)
+ ClientData clientData; /* Dynamic string holding partially
+ * assembled selection. */
+ Tcl_Interp *interp; /* Interpreter used for error
+ * reporting (not used). */
+ char *portion; /* New information to be appended. */
+{
+ Tcl_DStringAppend((Tcl_DString *) clientData, portion, -1);
+ return TCL_OK;
+}