summaryrefslogtreecommitdiffstats
path: root/carbon/tkMacOSXSend.c
diff options
context:
space:
mode:
Diffstat (limited to 'carbon/tkMacOSXSend.c')
-rw-r--r--carbon/tkMacOSXSend.c506
1 files changed, 0 insertions, 506 deletions
diff --git a/carbon/tkMacOSXSend.c b/carbon/tkMacOSXSend.c
deleted file mode 100644
index df6b2af..0000000
--- a/carbon/tkMacOSXSend.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * tkMacOSXSend.c --
- *
- * This file provides procedures that implement the "send" command,
- * allowing commands to be passed from interpreter to interpreter. This
- * current implementation for the Mac has most functionality stubed out.
- *
- * The current plan, which we have not had time to implement, is for the
- * first Wish app to create a gestalt of type 'WIsH'. This gestalt will
- * point to a table, in system memory, of Tk apps. Each Tk app, when it
- * starts up, will register their name, and process ID, in this table.
- * This will allow us to implement "tk appname".
- *
- * Then the send command will look up the process id of the target app in
- * this table, and send an AppleEvent to that process. The AppleEvent
- * handler is much like the do script handler, except that you have to
- * specify the name of the tk app as well, since there may be many
- * interps in one wish app, and you need to send it to the right one.
- *
- * Implementing this has been on our list of things to do, but what with
- * the demise of Tcl at Sun, and the lack of resources at Scriptics it
- * may not get done for awhile. So this sketch is offered for the brave
- * to attempt if they need the functionality...
- *
- * Copyright (c) 1989-1994 The Regents of the University of California.
- * Copyright (c) 1994-1998 Sun Microsystems, Inc.
- * Copyright 2001, Apple Computer, Inc.
- * Copyright (c) 2005-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.
- */
-
-#include "tkMacOSXInt.h"
-
-/*
- * The following structure is used to keep track of the interpreters
- * registered by this process.
- */
-
-typedef struct RegisteredInterp {
- char *name; /* Interpreter's name (malloc-ed). */
- Tcl_Interp *interp; /* Interpreter associated with name. */
- struct RegisteredInterp *nextPtr;
- /* Next in list of names associated with
- * interps in this process. NULL means end of
- * list. */
-} RegisteredInterp;
-
-/*
- * A registry of all interpreters for a display is kept in a property
- * "InterpRegistry" on the root window of the display. It is organized as a
- * series of zero or more concatenated strings (in no particular order), each
- * of the form
- * window space name '\0'
- * where "window" is the hex id of the comm. window to use to talk to an
- * interpreter named "name".
- *
- * When the registry is being manipulated by an application (e.g. to add or
- * remove an entry), it is loaded into memory using a structure of the
- * following type:
- */
-
-typedef struct NameRegistry {
- TkDisplay *dispPtr; /* Display from which the registry was
- * read. */
- int locked; /* Non-zero means that the display was locked
- * when the property was read in. */
- int modified; /* Non-zero means that the property has been
- * modified, so it needs to be written out
- * when the NameRegistry is closed. */
- unsigned long propLength; /* Length of the property, in bytes. */
- char *property; /* The contents of the property, or NULL if
- * none. See format description above; this is
- * *not* terminated by the first null
- * character. Dynamically allocated. */
- int allocedByX; /* Non-zero means must free property with
- * XFree; zero means use ckfree. */
-} NameRegistry;
-
-static int initialized = false; /* A flag to denote if we have initialized
- * yet. */
-
-static RegisteredInterp *interpListPtr = NULL;
- /* List of all interpreters registered by this
- * process. */
-
-/*
- * The information below is used for communication between processes during
- * "send" commands. Each process keeps a private window, never even mapped,
- * with one property, "Comm". When a command is sent to an interpreter, the
- * command is appended to the comm property of the communication window
- * associated with the interp's process. Similarly, when a result is returned
- * from a sent command, it is also appended to the comm property.
- *
- * Each command and each result takes the form of ASCII text. For a command,
- * the text consists of a zero character followed by several null-terminated
- * ASCII strings. The first string consists of the single letter "c".
- * Subsequent strings have the form "option value" where the following options
- * are supported:
- *
- * -r commWindow serial
- *
- * This option means that a response should be sent to the window whose X
- * identifier is "commWindow" (in hex), and the response should be
- * identified with the serial number given by "serial" (in decimal). If
- * this option isn't specified then the send is asynchronous and no
- * response is sent.
- *
- * -n name
- *
- * "Name" gives the name of the application for which the command is
- * intended. This option must be present.
- *
- * -s script
- *
- * "Script" is the script to be executed. This option must be present.
- *
- * The options may appear in any order. The -n and -s options must be present,
- * but -r may be omitted for asynchronous RPCs. For compatibility with future
- * releases that may add new features, there may be additional options
- * present; as long as they start with a "-" character, they will be ignored.
- *
- *
- * A result also consists of a zero character followed by several null-
- * terminated ASCII strings. The first string consists of the single letter
- * "r". Subsequent strings have the form "option value" where the following
- * options are supported:
- *
- * -s serial
- *
- * Identifies the command for which this is the result. It is the same as
- * the "serial" field from the -s option in the command. This option must
- * be present.
- *
- * -c code
- *
- * "Code" is the completion code for the script, in decimal. If the code
- * is omitted it defaults to TCL_OK.
- *
- * -r result
- *
- * "Result" is the result string for the script, which may be either a
- * result or an error message. If this field is omitted then it defaults
- * to an empty string.
- *
- * -i errorInfo
- *
- * "ErrorInfo" gives a string with which to initialize the errorInfo
- * variable. This option may be omitted; it is ignored unless the
- * completion code is TCL_ERROR.
- *
- * -e errorCode
- *
- * "ErrorCode" gives a string with with to initialize the errorCode
- * variable. This option may be omitted; it is ignored unless the
- * completion code is TCL_ERROR.
- *
- * Options may appear in any order, and only the -s option must be present. As
- * with commands, there may be additional options besides these; unknown
- * options are ignored.
- */
-
-/*
- * Maximum size property that can be read at one time by this module:
- */
-
-#define MAX_PROP_WORDS 100000
-
-/*
- * Forward declarations for procedures defined later in this file:
- */
-
-static int SendInit(Tcl_Interp *interp);
-
-/*
- *--------------------------------------------------------------
- *
- * Tk_SetAppName --
- *
- * This procedure is called to associate an ASCII name with a Tk
- * application. If the application has already been named, the name
- * replaces the old one.
- *
- * Results:
- * The return value is the name actually given to the application. This
- * will normally be the same as name, but if name was already in use for
- * an application then a name of the form "name #2" will be chosen, with
- * a high enough number to make the name unique.
- *
- * Side effects:
- * Registration info is saved, thereby allowing the "send" command to be
- * used later to invoke commands in the application. In addition, the
- * "send" command is created in the application's interpreter. The
- * registration will be removed automatically if the interpreter is
- * deleted or the "send" command is removed.
- *
- *--------------------------------------------------------------
- */
-
-const char *
-Tk_SetAppName(
- Tk_Window tkwin, /* Token for any window in the application to
- * be named: it is just used to identify the
- * application and the display. */
- const char *name) /* The name that will be used to refer to the
- * interpreter in later "send" commands. Must
- * be globally unique. */
-{
- TkWindow *winPtr = (TkWindow *) tkwin;
- Tcl_Interp *interp = winPtr->mainPtr->interp;
- int i, suffix, offset, result;
- RegisteredInterp *riPtr, *prevPtr;
- const char *actualName;
- Tcl_DString dString;
- Tcl_Obj *resultObjPtr, *interpNamePtr;
- char *interpName;
-
- if (!initialized) {
- SendInit(interp);
- }
-
- /*
- * See if the application is already registered; if so, remove its current
- * name from the registry. The deletion of the command will take care of
- * disposing of this entry.
- */
-
- for (riPtr = interpListPtr, prevPtr = NULL; riPtr != NULL;
- prevPtr = riPtr, riPtr = riPtr->nextPtr) {
- if (riPtr->interp == interp) {
- if (prevPtr == NULL) {
- interpListPtr = interpListPtr->nextPtr;
- } else {
- prevPtr->nextPtr = riPtr->nextPtr;
- }
- break;
- }
- }
-
- /*
- * Pick a name to use for the application. Use "name" if it's not already
- * in use. Otherwise add a suffix such as " #2", trying larger and larger
- * numbers until we eventually find one that is unique.
- */
-
- actualName = name;
- suffix = 1;
- offset = 0;
- Tcl_DStringInit(&dString);
-
- TkGetInterpNames(interp, tkwin);
- resultObjPtr = Tcl_GetObjResult(interp);
- Tcl_IncrRefCount(resultObjPtr);
- for (i = 0; ; ) {
- result = Tcl_ListObjIndex(NULL, resultObjPtr, i, &interpNamePtr);
- if (result != TCL_OK || interpNamePtr == NULL) {
- break;
- }
- interpName = Tcl_GetString(interpNamePtr);
- if (strcmp(actualName, interpName) == 0) {
- if (suffix == 1) {
- Tcl_DStringAppend(&dString, name, -1);
- Tcl_DStringAppend(&dString, " #", 2);
- offset = Tcl_DStringLength(&dString);
- Tcl_DStringSetLength(&dString, offset + 10);
- actualName = Tcl_DStringValue(&dString);
- }
- suffix++;
- sprintf(Tcl_DStringValue(&dString) + offset, "%d", suffix);
- i = 0;
- } else {
- i++;
- }
- }
-
- Tcl_DecrRefCount(resultObjPtr);
- Tcl_ResetResult(interp);
-
- /*
- * We have found a unique name. Now add it to the registry.
- */
-
- riPtr = ckalloc(sizeof(RegisteredInterp));
- riPtr->interp = interp;
- riPtr->name = ckalloc(strlen(actualName) + 1);
- riPtr->nextPtr = interpListPtr;
- interpListPtr = riPtr;
- strcpy(riPtr->name, actualName);
-
- /*
- * TODO: DeleteProc
- */
-
- Tcl_CreateObjCommand(interp, "send", Tk_SendObjCmd, riPtr, NULL);
- if (Tcl_IsSafe(interp)) {
- Tcl_HideCommand(interp, "send", "send");
- }
- Tcl_DStringFree(&dString);
-
- return riPtr->name;
-}
-
-/*
- *--------------------------------------------------------------
- *
- * Tk_SendObjCmd --
- *
- * This procedure is invoked to process the "send" Tcl command. See the
- * user documentation for details on what it does.
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * See the user documentation.
- *
- *--------------------------------------------------------------
- */
-
-int
-Tk_SendObjCmd(
- ClientData clientData, /* Used only for deletion */
- Tcl_Interp *interp, /* The interp we are sending from */
- int objc, /* Number of arguments */
- Tcl_Obj *const objv[]) /* The arguments */
-{
- const char *const sendOptions[] = {"-async", "-displayof", "-", NULL};
- char *stringRep, *destName;
- /*int async = 0;*/
- int i, index, firstArg;
- RegisteredInterp *riPtr;
- Tcl_Obj *listObjPtr;
- int result = TCL_OK;
-
- for (i = 1; i < (objc - 1); ) {
- stringRep = Tcl_GetString(objv[i]);
- if (stringRep[0] == '-') {
- if (Tcl_GetIndexFromObj(interp, objv[i], sendOptions, "option", 0,
- &index) != TCL_OK) {
- return TCL_ERROR;
- }
- if (index == 0) {
- /*async = 1;*/
- i++;
- } else if (index == 1) {
- i += 2;
- } else {
- i++;
- }
- } else {
- break;
- }
- }
-
- if (objc < (i + 2)) {
- Tcl_WrongNumArgs(interp, 1, objv,
- "?-option value ...? interpName arg ?arg ...?");
- return TCL_ERROR;
- }
-
- destName = Tcl_GetString(objv[i]);
- firstArg = i + 1;
-
- /*
- * See if the target interpreter is local. If so, execute the command
- * directly without going through the DDE server. The only tricky thing is
- * passing the result from the target interpreter to the invoking
- * interpreter. Watch out: they could be the same!
- */
-
- for (riPtr = interpListPtr; (riPtr != NULL)
- && (strcmp(destName, riPtr->name)); riPtr = riPtr->nextPtr) {
- /*
- * Empty loop body.
- */
- }
-
- if (riPtr != NULL) {
- /*
- * This command is to a local interp. No need to go through the
- * server.
- */
-
- Tcl_Interp *localInterp;
-
- Tcl_Preserve(riPtr);
- localInterp = riPtr->interp;
- Tcl_Preserve(localInterp);
- if (firstArg == (objc - 1)) {
- /*
- * This might be one of those cases where the new parser is
- * faster.
- */
-
- result = Tcl_EvalObjEx(localInterp, objv[firstArg],
- TCL_EVAL_DIRECT);
- } else {
- listObjPtr = Tcl_NewListObj(0, NULL);
- for (i = firstArg; i < objc; i++) {
- Tcl_ListObjAppendList(interp, listObjPtr, objv[i]);
- }
- Tcl_IncrRefCount(listObjPtr);
- result = Tcl_EvalObjEx(localInterp, listObjPtr, TCL_EVAL_DIRECT);
- Tcl_DecrRefCount(listObjPtr);
- }
- if (interp != localInterp) {
- if (result == TCL_ERROR) {
- /* Tcl_Obj *errorObjPtr; */
-
- /*
- * An error occurred, so transfer error information from the
- * destination interpreter back to our interpreter. Must clear
- * interp's result before calling Tcl_AddErrorInfo, since
- * Tcl_AddErrorInfo will store the interp's result in
- * errorInfo before appending riPtr's $errorInfo; we've
- * already got everything we need in riPtr's $errorInfo.
- */
-
- Tcl_ResetResult(interp);
- Tcl_AddErrorInfo(interp, Tcl_GetVar2(localInterp,
- "errorInfo", NULL, TCL_GLOBAL_ONLY));
- /* errorObjPtr = Tcl_GetObjVar2(localInterp, "errorCode", NULL,
- TCL_GLOBAL_ONLY);
- Tcl_SetObjErrorCode(interp, errorObjPtr); */
- }
- Tcl_SetObjResult(interp, Tcl_GetObjResult(localInterp));
- }
- Tcl_Release(riPtr);
- Tcl_Release(localInterp);
- } else {
- /*
- * TODO: This is a non-local request. Send the script to the server
- * and poll it for a result.
- */
- }
-
- return result;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkGetInterpNames --
- *
- * This procedure is invoked to fetch a list of all the interpreter names
- * currently registered for the display of a particular window.
- *
- * Results:
- * A standard Tcl return value. Interp->result will be set to hold a list
- * of all the interpreter names defined for tkwin's display. If an error
- * occurs, then TCL_ERROR is returned and interp->result will hold an
- * error message.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TkGetInterpNames(
- Tcl_Interp *interp, /* Interpreter for returning a result. */
- Tk_Window tkwin) /* Window whose display is to be used for the
- * lookup. */
-{
- Tcl_Obj *listObjPtr;
- RegisteredInterp *riPtr;
-
- listObjPtr = Tcl_NewListObj(0, NULL);
- riPtr = interpListPtr;
- while (riPtr != NULL) {
- Tcl_ListObjAppendElement(interp, listObjPtr,
- Tcl_NewStringObj(riPtr->name, -1));
- riPtr = riPtr->nextPtr;
- }
-
- Tcl_SetObjResult(interp, listObjPtr);
- return TCL_OK;
-}
-
-/*
- *--------------------------------------------------------------
- *
- * SendInit --
- *
- * This procedure is called to initialize the communication channels for
- * sending commands and receiving results.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Sets up various data structures and windows.
- *
- *--------------------------------------------------------------
- */
-
-static int
-SendInit(
- Tcl_Interp *interp) /* Interpreter to use for error reporting (no
- * errors are ever returned, but the
- * interpreter is needed anyway). */
-{
- return TCL_OK;
-}