📄 tkconsole.c
字号:
/* * tkConsole.c -- * * This file implements a Tcl console for systems that may not * otherwise have access to a console. It uses the Text widget * and provides special access via a console command. * * Copyright (c) 1995-1996 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkConsole.c 1.54 97/10/17 10:46:08 */#include "tk.h"#include <string.h>/* * A data structure of the following type holds information for each console * which a handler (i.e. a Tcl command) has been defined for a particular * top-level window. */typedef struct ConsoleInfo { Tcl_Interp *consoleInterp; /* Interpreter for the console. */ Tcl_Interp *interp; /* Interpreter to send console commands. */} ConsoleInfo;static Tcl_Interp *gStdoutInterp = NULL;/* * Forward declarations for procedures defined later in this file: * * The first three will be used in the tk app shells... */ void TkConsoleCreate _ANSI_ARGS_((void));int TkConsoleInit _ANSI_ARGS_((Tcl_Interp *interp));void TkConsolePrint _ANSI_ARGS_((Tcl_Interp *interp, int devId, char *buffer, long size));static int ConsoleCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv));static void ConsoleDeleteProc _ANSI_ARGS_((ClientData clientData));static void ConsoleEventProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr));static int InterpreterCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv));static int ConsoleInput _ANSI_ARGS_((ClientData instanceData, char *buf, int toRead, int *errorCode));static int ConsoleOutput _ANSI_ARGS_((ClientData instanceData, char *buf, int toWrite, int *errorCode));static int ConsoleClose _ANSI_ARGS_((ClientData instanceData, Tcl_Interp *interp));static void ConsoleWatch _ANSI_ARGS_((ClientData instanceData, int mask));static int ConsoleHandle _ANSI_ARGS_((ClientData instanceData, int direction, ClientData *handlePtr));/* * This structure describes the channel type structure for file based IO: */static Tcl_ChannelType consoleChannelType = { "console", /* Type name. */ NULL, /* Always non-blocking.*/ ConsoleClose, /* Close proc. */ ConsoleInput, /* Input proc. */ ConsoleOutput, /* Output proc. */ NULL, /* Seek proc. */ NULL, /* Set option proc. */ NULL, /* Get option proc. */ ConsoleWatch, /* Watch for events on console. */ ConsoleHandle, /* Get a handle from the device. */};/* *---------------------------------------------------------------------- * * TkConsoleCreate -- * * Create the console channels and install them as the standard * channels. All I/O will be discarded until TkConsoleInit is * called to attach the console to a text widget. * * Results: * None. * * Side effects: * Creates the console channel and installs it as the standard * channels. * *---------------------------------------------------------------------- */voidTkConsoleCreate(){ Tcl_Channel consoleChannel; consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console0", (ClientData) TCL_STDIN, TCL_READABLE); if (consoleChannel != NULL) { Tcl_SetChannelOption(NULL, consoleChannel, "-translation", "lf"); Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none"); } Tcl_SetStdChannel(consoleChannel, TCL_STDIN); consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console1", (ClientData) TCL_STDOUT, TCL_WRITABLE); if (consoleChannel != NULL) { Tcl_SetChannelOption(NULL, consoleChannel, "-translation", "lf"); Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none"); } Tcl_SetStdChannel(consoleChannel, TCL_STDOUT); consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console2", (ClientData) TCL_STDERR, TCL_WRITABLE); if (consoleChannel != NULL) { Tcl_SetChannelOption(NULL, consoleChannel, "-translation", "lf"); Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none"); } Tcl_SetStdChannel(consoleChannel, TCL_STDERR);}/* *---------------------------------------------------------------------- * * TkConsoleInit -- * * Initialize the console. This code actually creates a new * application and associated interpreter. This effectivly hides * the implementation from the main application. * * Results: * None. * * Side effects: * A new console it created. * *---------------------------------------------------------------------- */int TkConsoleInit(interp) Tcl_Interp *interp; /* Interpreter to use for prompting. */{ Tcl_Interp *consoleInterp; ConsoleInfo *info; Tk_Window mainWindow = Tk_MainWindow(interp);#ifdef MAC_TCL static char initCmd[] = "source -rsrc {Console}";#else static char initCmd[] = "source $tk_library/console.tcl";#endif consoleInterp = Tcl_CreateInterp(); if (consoleInterp == NULL) { goto error; } /* * Initialized Tcl and Tk. */ if (Tcl_Init(consoleInterp) != TCL_OK) { goto error; } if (Tk_Init(consoleInterp) != TCL_OK) { goto error; } gStdoutInterp = interp; /* * Add console commands to the interp */ info = (ConsoleInfo *) ckalloc(sizeof(ConsoleInfo)); info->interp = interp; info->consoleInterp = consoleInterp; Tcl_CreateCommand(interp, "console", ConsoleCmd, (ClientData) info, (Tcl_CmdDeleteProc *) ConsoleDeleteProc); Tcl_CreateCommand(consoleInterp, "consoleinterp", InterpreterCmd, (ClientData) info, (Tcl_CmdDeleteProc *) NULL); Tk_CreateEventHandler(mainWindow, StructureNotifyMask, ConsoleEventProc, (ClientData) info); Tcl_Preserve((ClientData) consoleInterp); if (Tcl_Eval(consoleInterp, initCmd) == TCL_ERROR) { /* goto error; -- no problem for now... */ printf("Eval error: %s", consoleInterp->result); } Tcl_Release((ClientData) consoleInterp); return TCL_OK; error: if (consoleInterp != NULL) { Tcl_DeleteInterp(consoleInterp); } return TCL_ERROR;}/* *---------------------------------------------------------------------- * * ConsoleOutput-- * * Writes the given output on the IO channel. Returns count of how * many characters were actually written, and an error indication. * * Results: * A count of how many characters were written is returned and an * error indication is returned in an output argument. * * Side effects: * Writes output on the actual channel. * *---------------------------------------------------------------------- */static intConsoleOutput(instanceData, buf, toWrite, errorCode) ClientData instanceData; /* Indicates which device to use. */ char *buf; /* The data buffer. */ int toWrite; /* How many bytes to write? */ int *errorCode; /* Where to store error code. */{ *errorCode = 0; Tcl_SetErrno(0); if (gStdoutInterp != NULL) { TkConsolePrint(gStdoutInterp, (int) instanceData, buf, toWrite); } return toWrite;}/* *---------------------------------------------------------------------- * * ConsoleInput -- * * Read input from the console. Not currently implemented. * * Results: * Always returns EOF. * * Side effects: * None. * *---------------------------------------------------------------------- */ /* ARGSUSED */static intConsoleInput(instanceData, buf, bufSize, errorCode) ClientData instanceData; /* Unused. */ char *buf; /* Where to store data read. */ int bufSize; /* How much space is available * in the buffer? */ int *errorCode; /* Where to store error code. */{ return 0; /* Always return EOF. */}/* *---------------------------------------------------------------------- * * ConsoleClose -- * * Closes the IO channel. * * Results: * Always returns 0 (success). * * Side effects: * Frees the dummy file associated with the channel. * *---------------------------------------------------------------------- */ /* ARGSUSED */static intConsoleClose(instanceData, interp) ClientData instanceData; /* Unused. */ Tcl_Interp *interp; /* Unused. */{ return 0;}/* *---------------------------------------------------------------------- * * ConsoleWatch -- * * Called by the notifier to set up the console device so that * events will be noticed. Since there are no events on the * console, this routine just returns without doing anything. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ /* ARGSUSED */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -