📄 itk_archetype.c
字号:
/* * ------------------------------------------------------------------------ * PACKAGE: [incr Tk] * DESCRIPTION: Building mega-widgets with [incr Tcl] * * [incr Tk] provides a framework for building composite "mega-widgets" * using [incr Tcl] classes. It defines a set of base classes that are * specialized to create all other widgets. * * This part adds C implementations for some of the methods in the * base class itk::Archetype. * * Itk_ArchComponentCmd <=> itk_component * Itk_ArchOptionCmd <=> itk_option * Itk_ArchInitCmd <=> itk_initialize * Itk_ArchCompAccessCmd <=> component * Itk_ArchConfigureCmd <=> configure * Itk_ArchCgetCmd <=> cget * * Itk_ArchInitOptsCmd <=> _initOptionInfo (used to set things up) * Itk_ArchDeleteOptsCmd <=> _deleteOptionInfo (used to clean things up) * * ======================================================================== * AUTHOR: Michael J. McLennan * Bell Labs Innovations for Lucent Technologies * mmclennan@lucent.com * http://www.tcltk.com/itcl * * RCS: $Id: itk_archetype.c,v 1.1 2003/02/05 10:53:58 mdejong Exp $ * ======================================================================== * Copyright (c) 1993-1998 Lucent Technologies, Inc. * ------------------------------------------------------------------------ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */#include <assert.h>#include "itk.h"/* * Info associated with each Archetype mega-widget: */typedef struct ArchInfo { ItclObject *itclObj; /* object containing this info */ Tk_Window tkwin; /* window representing this mega-widget */ Tcl_HashTable components; /* list of all mega-widget components */ Tcl_HashTable options; /* list of all mega-widget options */ ItkOptList order; /* gives ordering of options */} ArchInfo;/* * Each component widget in an Archetype mega-widget: */typedef struct ArchComponent { ItclMember *member; /* contains protection level for this comp */ Tcl_Command accessCmd; /* access command for component widget */ Tk_Window tkwin; /* Tk window for this component widget */ char *pathName; /* Tk path name for this component widget. We can't use the tkwin pointer after the window has been destroyed so we need to save a copy for use in Itk_ArchCompDeleteCmd() */} ArchComponent;/* * Each option in an Archetype mega-widget: */typedef struct ArchOption { char *switchName; /* command-line switch for this option */ char *resName; /* resource name in X11 database */ char *resClass; /* resource class name in X11 database */ char *init; /* initial value for option */ int flags; /* flags representing option state */ Itcl_List parts; /* parts relating to this option */} ArchOption;/* * Flag bits for ArchOption state: */#define ITK_ARCHOPT_INIT 0x01 /* option has been initialized *//* * Various parts of a composite option in an Archetype mega-widget: */typedef int (Itk_ConfigOptionPartProc) _ANSI_ARGS_((Tcl_Interp *interp, ItclObject *contextObj, ClientData cdata, char* newVal));typedef struct ArchOptionPart { ClientData clientData; /* data associated with this part */ Itk_ConfigOptionPartProc *configProc; /* update when new vals arrive */ Tcl_CmdDeleteProc *deleteProc; /* clean up after clientData */ ClientData from; /* token that indicates who * contributed this option part */} ArchOptionPart;/* * Info kept by the itk::option-parser namespace and shared by * all option processing commands: */typedef struct ArchMergeInfo { Tcl_HashTable usualCode; /* usual option handling code for the * various widget classes */ ArchInfo *archInfo; /* internal option info for mega-widget */ ArchComponent *archComp; /* component being merged into mega-widget */ Tcl_HashTable *optionTable; /* table of valid configuration options * for component being merged */} ArchMergeInfo;/* * Used to capture component widget configuration options when a * new component is being merged into a mega-widget: */typedef struct GenericConfigOpt { char *switchName; /* command-line switch for this option */ char *resName; /* resource name in X11 database */ char *resClass; /* resource class name in X11 database */ char *init; /* initial value for this option */ char *value; /* current value for this option */ char **storage; /* storage for above strings */ ArchOption *integrated; /* integrated into this mega-widget option */ ArchOptionPart *optPart; /* integrated as this option part */} GenericConfigOpt;/* * Options that are propagated by a "configure" method: */typedef struct ConfigCmdline { Tcl_Obj *objv[4]; /* objects representing "configure" command */} ConfigCmdline;/* * FORWARD DECLARATIONS */static void Itk_DelMergeInfo _ANSI_ARGS_((char* cdata));static int Itk_ArchInitOptsCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static void Itk_DelArchInfo _ANSI_ARGS_((ClientData cdata));static int Itk_ArchDeleteOptsCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static int Itk_ArchComponentCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static int Itk_ArchCompAddCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static int Itk_ArchCompDeleteCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static int Itk_ArchOptKeepCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static int Itk_ArchOptIgnoreCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static int Itk_ArchOptRenameCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static int Itk_ArchOptUsualCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static int Itk_ArchInitCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static int Itk_ArchOptionCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static int Itk_ArchOptionAddCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static int Itk_ArchOptionRemoveCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static int Itk_ArchCompAccessCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static int Itk_ArchConfigureCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static int Itk_ArchCgetCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));static int Itk_PropagateOption _ANSI_ARGS_((Tcl_Interp *interp, ItclObject *contextObj, ClientData cdata, char *newval));static int Itk_PropagatePublicVar _ANSI_ARGS_((Tcl_Interp *interp, ItclObject *contextObj, ClientData cdata, char *newval));static int Itk_ArchSetOption _ANSI_ARGS_((Tcl_Interp *interp, ArchInfo *info, char *name, char *value));static int Itk_ArchConfigOption _ANSI_ARGS_((Tcl_Interp *interp, ArchInfo *info, char *name, char *value));static void Itk_ArchOptConfigError _ANSI_ARGS_((Tcl_Interp *interp, ArchInfo *info, ArchOption *archOpt));static void Itk_ArchOptAccessError _ANSI_ARGS_((Tcl_Interp *interp, ArchInfo *info, ArchOption *archOpt));static int Itk_GetArchInfo _ANSI_ARGS_((Tcl_Interp *interp, ItclObject* contextObj, ArchInfo **infoPtr));static ArchComponent* Itk_CreateArchComponent _ANSI_ARGS_(( Tcl_Interp *interp, ArchInfo *info, char *name, ItclClass *cdefn, Tcl_Command accessCmd));static void Itk_DelArchComponent _ANSI_ARGS_((ArchComponent *archComp));static int Itk_GetArchOption _ANSI_ARGS_((Tcl_Interp *interp, ArchInfo *info, char *switchName, char *resName, char *resClass, char *defVal, char *currVal, ArchOption **aoPtr));static void Itk_InitArchOption _ANSI_ARGS_((Tcl_Interp *interp, ArchInfo *info, ArchOption *archOpt, char *defVal, char *currVal));static void Itk_DelArchOption _ANSI_ARGS_((ArchOption *archOpt));static ArchOptionPart* Itk_CreateOptionPart _ANSI_ARGS_(( Tcl_Interp *interp, ClientData cdata, Itk_ConfigOptionPartProc* cproc, Tcl_CmdDeleteProc *dproc, ClientData from));static int Itk_AddOptionPart _ANSI_ARGS_((Tcl_Interp *interp, ArchInfo *info, char *switchName, char *resName, char *resClass, char *defVal, char *currVal, ArchOptionPart *optPart, ArchOption **raOpt));static ArchOptionPart* Itk_FindArchOptionPart _ANSI_ARGS_(( ArchInfo *info, char *switchName, ClientData from));static int Itk_RemoveArchOptionPart _ANSI_ARGS_((ArchInfo *info, char *switchName, ClientData from));static int Itk_IgnoreArchOptionPart _ANSI_ARGS_((ArchInfo *info, GenericConfigOpt *opt));static void Itk_DelOptionPart _ANSI_ARGS_((ArchOptionPart *optPart));static ConfigCmdline* Itk_CreateConfigCmdline _ANSI_ARGS_(( Tcl_Interp *interp, Tcl_Command accessCmd, char *switchName));static void Itk_DeleteConfigCmdline _ANSI_ARGS_((ClientData cdata));static Tcl_HashTable* Itk_CreateGenericOptTable _ANSI_ARGS_((Tcl_Interp *interp, char *options));static void Itk_DelGenericOptTable _ANSI_ARGS_((Tcl_HashTable *tPtr));static GenericConfigOpt* Itk_CreateGenericOpt _ANSI_ARGS_((Tcl_Interp *interp, char *switchName, Tcl_Command accessCmd));static void Itk_DelGenericOpt _ANSI_ARGS_((GenericConfigOpt* opt));static Tcl_HashTable* ItkGetObjsWithArchInfo _ANSI_ARGS_((Tcl_Interp *interp));static void ItkFreeObjsWithArchInfo _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp));/* * ------------------------------------------------------------------------ * Itk_ArchetypeInit() * * Invoked by Itk_Init() whenever a new interpreter is created to * declare the procedures used in the itk::Archetype base class. * ------------------------------------------------------------------------ */intItk_ArchetypeInit(interp) Tcl_Interp *interp; /* interpreter to be updated */{ ArchMergeInfo *mergeInfo; Tcl_Namespace *parserNs; /* * Declare all of the C routines that are integrated into * the Archetype base class. */ if (Itcl_RegisterObjC(interp, "Archetype-init", Itk_ArchInitOptsCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL) != TCL_OK || Itcl_RegisterObjC(interp, "Archetype-delete", Itk_ArchDeleteOptsCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL) != TCL_OK || Itcl_RegisterObjC(interp, "Archetype-itk_component", Itk_ArchComponentCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL) != TCL_OK || Itcl_RegisterObjC(interp, "Archetype-itk_option", Itk_ArchOptionCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL) != TCL_OK || Itcl_RegisterObjC(interp, "Archetype-itk_initialize", Itk_ArchInitCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL) != TCL_OK || Itcl_RegisterObjC(interp, "Archetype-component", Itk_ArchCompAccessCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL) != TCL_OK || Itcl_RegisterObjC(interp, "Archetype-configure",Itk_ArchConfigureCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL) != TCL_OK || Itcl_RegisterObjC(interp, "Archetype-cget",Itk_ArchCgetCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL) != TCL_OK) { return TCL_ERROR; } /* * Create the namespace containing the option parser commands. */ mergeInfo = (ArchMergeInfo*)ckalloc(sizeof(ArchMergeInfo)); Tcl_InitHashTable(&mergeInfo->usualCode, TCL_STRING_KEYS); mergeInfo->archInfo = NULL; mergeInfo->archComp = NULL; mergeInfo->optionTable = NULL; parserNs = Tcl_CreateNamespace(interp, "::itk::option-parser", (ClientData)mergeInfo, Itcl_ReleaseData); if (!parserNs) { Itk_DelMergeInfo((char*)mergeInfo); Tcl_AddErrorInfo(interp, "\n (while initializing itk)"); return TCL_ERROR; } Itcl_PreserveData((ClientData)mergeInfo); Itcl_EventuallyFree((ClientData)mergeInfo, Itk_DelMergeInfo); Tcl_CreateObjCommand(interp, "::itk::option-parser::keep", Itk_ArchOptKeepCmd, (ClientData)mergeInfo, (Tcl_CmdDeleteProc*)NULL); Tcl_CreateObjCommand(interp, "::itk::option-parser::ignore", Itk_ArchOptIgnoreCmd, (ClientData)mergeInfo, (Tcl_CmdDeleteProc*)NULL); Tcl_CreateObjCommand(interp, "::itk::option-parser::rename", Itk_ArchOptRenameCmd, (ClientData)mergeInfo, (Tcl_CmdDeleteProc*)NULL); Tcl_CreateObjCommand(interp, "::itk::option-parser::usual", Itk_ArchOptUsualCmd, (ClientData)mergeInfo, (Tcl_CmdDeleteProc*)NULL); /* * Add the "itk::usual" command to register option handling code. */ Tcl_CreateObjCommand(interp, "::itk::usual", Itk_UsualCmd, (ClientData)mergeInfo, Itcl_ReleaseData); Itcl_PreserveData((ClientData)mergeInfo); return TCL_OK;}/* * ------------------------------------------------------------------------ * Itk_DelMergeInfo() * * Destroys the "merge" info record shared by commands in the * itk::option-parser namespace. Invoked automatically when the * namespace containing the parsing commands is destroyed and there * are no more uses of the data. * ------------------------------------------------------------------------ */static voidItk_DelMergeInfo(cdata) char* cdata; /* data to be destroyed */{ ArchMergeInfo *mergeInfo = (ArchMergeInfo*)cdata; Tcl_HashEntry *entry; Tcl_HashSearch place; Tcl_Obj *codePtr; assert(mergeInfo->optionTable == NULL); entry = Tcl_FirstHashEntry(&mergeInfo->usualCode, &place); while (entry) { codePtr = (Tcl_Obj*)Tcl_GetHashValue(entry); Tcl_DecrRefCount(codePtr); entry = Tcl_NextHashEntry(&place); } Tcl_DeleteHashTable(&mergeInfo->usualCode); ckfree((char*)mergeInfo);}/* * ------------------------------------------------------------------------ * Itk_ArchInitOptsCmd() * * Invoked by [incr Tcl] to handle the itk::Archetype::_initOptionInfo * method. This method should be called out in the constructor for * each object, to initialize the object so that it can be used with * the other access methods in this file. Allocates some extra * data associated with the object at the C-language level. * * Returns TCL_OK/TCL_ERROR to indicate success/failure. * ------------------------------------------------------------------------ *//* ARGSUSED */static int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -