Import Tix 8.4.3.5 (as of svn r86089)

This commit is contained in:
Zachary Ware
2017-05-22 16:16:49 -05:00
parent d239d63057
commit 80ba28babb
769 changed files with 136423 additions and 0 deletions

465
generic/tix.h Normal file
View File

@@ -0,0 +1,465 @@
/*
* tix.h --
*
* This is the standard header file for all tix C code. It
* defines many macros and utility functions to make it easier to
* write TCL commands and TK widgets in C. No more needs to write
* 2000 line functions!
*
* Copyright (c) 1993-1999 Ioi Kim Lam.
* Copyright (c) 2000 Tix Project Group.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tix.h,v 1.17 2008/02/28 04:35:16 hobbs Exp $
*/
#ifndef _TIX_H_
#define _TIX_H_
/*
* For C++ compilers, use extern "C"
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _TK
#include <tk.h>
#endif
#ifndef _TCL
#include <tcl.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifndef CONST84
#define CONST84
#endif
/*
* The following defines are used to indicate the various release levels.
*/
#define TIX_ALPHA_RELEASE 0
#define TIX_BETA_RELEASE 1
#define TIX_FINAL_RELEASE 2
/*
* When version numbers change here, must also go into the following files
* and update the version numbers:
*
* unix/README.txt (example directory name)
* configure.in (1 LOC major/minor/patch), rerun autoconf
* library/Init.tcl (1 LOC major/minor/patch)
* win/makefile.vc (1 LOC major/minor/patch)
* tests/basic.test (version checks)
* tests/README (example executable name)
*/
#define TIX_MAJOR_VERSION 8
#define TIX_MINOR_VERSION 4
#define TIX_RELEASE_LEVEL TIX_FINAL_RELEASE
#define TIX_RELEASE_SERIAL 3
#define TIX_VERSION "8.4"
#define TIX_PATCH_LEVEL "8.4.3"
#define TIX_RELEASE TIX_PATCH_LEVEL
/*
* When building Tix itself, BUILD_tix should be defined by the makefile
* so that all EXTERN declarations get DLLEXPORT; when building apps
* using Tix, BUILD_tix should NOT be defined so that all EXTERN
* declarations get DLLIMPORT as defined in tcl.h
*
* NOTE: This ifdef MUST appear after the include of tcl.h and tk.h
* because the EXTERN declarations in those files need DLLIMPORT.
*/
/*
* These macros are used to control whether functions are being declared for
* import or export. If a function is being declared while it is being built
* to be included in a shared library, then it should have the DLLEXPORT
* storage class. If is being declared for use by a module that is going to
* link against the shared library, then it should have the DLLIMPORT storage
* class. If the symbol is beind declared for a static build or for use from a
* stub library, then the storage class should be empty.
*
* The convention is that a macro called BUILD_xxxx, where xxxx is the
* name of a library we are building, is set on the compile line for sources
* that are to be placed in the library. When this macro is set, the
* storage class will be set to DLLEXPORT. At the end of the header file, the
* storage class will be reset to DLLIMPORt.
*/
#undef TCL_STORAGE_CLASS
#ifdef BUILD_tix
# define TCL_STORAGE_CLASS DLLEXPORT
#else
# ifdef USE_TCL_STUBS
# define TCL_STORAGE_CLASS
# else
# define TCL_STORAGE_CLASS DLLIMPORT
# endif
#endif
#define Tix_FreeProc Tcl_FreeProc
#define TIX_STDIN_ALWAYS 0
#define TIX_STDIN_OPTIONAL 1
#define TIX_STDIN_NONE 2
typedef struct {
CONST84 char *name; /* Name of command. */
int (*cmdProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp,
int argc, CONST84 char **argv));
/* Command procedure. */
} Tix_TclCmd;
/*----------------------------------------------------------------------
*
*
* SUB-COMMAND HANDLING
*
*
*----------------------------------------------------------------------
*/
typedef int (*Tix_CmdProc) _ANSI_ARGS_((ClientData clientData,
Tcl_Interp *interp, int argc, CONST84 char ** argv));
typedef int (*Tix_SubCmdProc) _ANSI_ARGS_((ClientData clientData,
Tcl_Interp *interp, int argc, CONST84 char ** argv));
typedef int (*Tix_CheckArgvProc) _ANSI_ARGS_((ClientData clientData,
Tcl_Interp *interp, int argc, CONST84 char ** argv));
typedef struct _Tix_CmdInfo {
int numSubCmds;
int minargc;
int maxargc;
char * info;
} Tix_CmdInfo;
typedef struct _Tix_SubCmdInfo {
int namelen;
CONST84 char *name;
int minargc;
int maxargc;
Tix_SubCmdProc proc;
CONST84 char *info;
Tix_CheckArgvProc checkArgvProc;
} Tix_SubCmdInfo;
/*
* Tix_ArraySize --
*
* Find out the number of elements inside a C array. The argument "x"
* must be a valid C array. Pointers don't work.
*/
#define Tix_ArraySize(x) (sizeof(x) / sizeof(x[0]))
/*
* This is used for Tix_CmdInfo.maxargc and Tix_SubCmdInfo.maxargc,
* indicating that this command takes a variable number of arguments.
*/
#define TIX_VAR_ARGS -1
/*
* TIX_DEFAULT_LEN --
*
* Use this for Tix_SubCmdInfo.namelen and Tix_ExecSubCmds() will try to
* determine the length of the subcommand name for you.
*/
#define TIX_DEFAULT_LEN -1
/*
* TIX_DEFAULT_SUB_CMD --
*
* Use this for Tix_SubCmdInfo.name. This will match any subcommand name,
* including the empty string, when Tix_ExecSubCmds() finds a subcommand
* to execute.
*/
#define TIX_DEFAULT_SUBCMD 0
/*
* TIX_DECLARE_CMD --
*
* This is just a handy macro to declare a C function to use as a
* command function.
*/
#define TIX_DECLARE_CMD(func) \
int func(ClientData clientData,\
Tcl_Interp *interp, int argc, CONST84 char ** argv)
/*
* TIX_DECLARE_SUBCMD --
*
* This is just a handy macro to declare a C function to use as a
* sub command function.
*/
#define TIX_DECLARE_SUBCMD(func) \
int func(ClientData clientData,\
Tcl_Interp *interp, int argc, CONST84 char ** argv)
/*
* TIX_DEFINE_CMD --
*
* This is just a handy macro to define a C function to use as a
* command function.
*/
#define TIX_DEFINE_CMD(func) \
int func(clientData, interp, argc, argv) \
ClientData clientData; /* Main window associated with \
* interpreter. */ \
Tcl_Interp *interp; /* Current interpreter. */ \
int argc; /* Number of arguments. */ \
CONST84 char **argv; /* Argument strings. */
/*----------------------------------------------------------------------
* Link-list functions --
*
* These functions makes it easy to use link lists in C code.
*
*----------------------------------------------------------------------
*/
typedef struct Tix_ListInfo {
int nextOffset; /* offset of the "next" pointer in a list
* item */
int prevOffset; /* offset of the "next" pointer in a list
* item */
} Tix_ListInfo;
/* Singly-linked list */
typedef struct Tix_LinkList {
int numItems; /* number of items in this list */
char * head; /* (general pointer) head of the list */
char * tail; /* (general pointer) tail of the list */
} Tix_LinkList;
typedef struct Tix_ListIterator {
char * last;
char * curr;
unsigned int started : 1; /* True if the search operation has
* already started for this list */
unsigned int deleted : 1; /* True if a delete operation has been
* performed on the current item (in this
* case the curr pointer has already been
* adjusted
*/
} Tix_ListIterator;
#define Tix_IsLinkListEmpty(list) ((list.numItems) == 0)
#define TIX_UNIQUE 1
#define TIX_UNDEFINED -1
/*----------------------------------------------------------------------
* General Single Link List --
*
* The next pointer can be anywhere inside a link.
*----------------------------------------------------------------------
*/
EXTERN void Tix_LinkListInit _ANSI_ARGS_((Tix_LinkList * lPtr));
EXTERN void Tix_LinkListAppend _ANSI_ARGS_((Tix_ListInfo * infoPtr,
Tix_LinkList * lPtr, char * itemPtr, int flags));
EXTERN void Tix_LinkListStart _ANSI_ARGS_((Tix_ListInfo * infoPtr,
Tix_LinkList * lPtr, Tix_ListIterator * liPtr));
EXTERN void Tix_LinkListNext _ANSI_ARGS_((Tix_ListInfo * infoPtr,
Tix_LinkList * lPtr, Tix_ListIterator * liPtr));
EXTERN void Tix_LinkListDelete _ANSI_ARGS_((Tix_ListInfo * infoPtr,
Tix_LinkList * lPtr, Tix_ListIterator * liPtr));
EXTERN int Tix_LinkListDeleteRange _ANSI_ARGS_((
Tix_ListInfo * infoPtr, Tix_LinkList * lPtr,
char * fromPtr, char * toPtr,
Tix_ListIterator * liPtr));
EXTERN int Tix_LinkListFind _ANSI_ARGS_((
Tix_ListInfo * infoPtr, Tix_LinkList * lPtr,
char * itemPtr, Tix_ListIterator * liPtr));
EXTERN int Tix_LinkListFindAndDelete _ANSI_ARGS_((
Tix_ListInfo * infoPtr, Tix_LinkList * lPtr,
char * itemPtr, Tix_ListIterator * liPtr));
EXTERN void Tix_LinkListInsert _ANSI_ARGS_((
Tix_ListInfo * infoPtr,
Tix_LinkList * lPtr, char * itemPtr,
Tix_ListIterator * liPtr));
EXTERN void Tix_LinkListIteratorInit _ANSI_ARGS_((
Tix_ListIterator * liPtr));
#define Tix_LinkListDone(liPtr) ((liPtr)->curr == NULL)
/*----------------------------------------------------------------------
* Simple Single Link List --
*
* The next pointer is always offset 0 in the link structure.
*----------------------------------------------------------------------
*/
EXTERN void Tix_SimpleListInit _ANSI_ARGS_((Tix_LinkList * lPtr));
EXTERN void Tix_SimpleListAppend _ANSI_ARGS_((
Tix_LinkList * lPtr, char * itemPtr, int flags));
EXTERN void Tix_SimpleListStart _ANSI_ARGS_((
Tix_LinkList * lPtr, Tix_ListIterator * liPtr));
EXTERN void Tix_SimpleListNext _ANSI_ARGS_((
Tix_LinkList * lPtr, Tix_ListIterator * liPtr));
EXTERN void Tix_SimpleListDelete _ANSI_ARGS_((
Tix_LinkList * lPtr, Tix_ListIterator * liPtr));
EXTERN int Tix_SimpleListDeleteRange _ANSI_ARGS_((
Tix_LinkList * lPtr,
char * fromPtr, char * toPtr,
Tix_ListIterator * liPtr));
EXTERN int Tix_SimpleListFind _ANSI_ARGS_((
Tix_LinkList * lPtr,
char * itemPtr, Tix_ListIterator * liPtr));
EXTERN int Tix_SimpleListFindAndDelete _ANSI_ARGS_((
Tix_LinkList * lPtr, char * itemPtr,
Tix_ListIterator * liPtr));
EXTERN void Tix_SimpleListInsert _ANSI_ARGS_((
Tix_LinkList * lPtr, char * itemPtr,
Tix_ListIterator * liPtr));
EXTERN void Tix_SimpleListIteratorInit _ANSI_ARGS_((
Tix_ListIterator * liPtr));
#define Tix_SimpleListDone(liPtr) ((liPtr)->curr == NULL)
/*----------------------------------------------------------------------
*
*
*
* CUSTOM CONFIG OPTIONS
*
*----------------------------------------------------------------------
*/
/*
* These values are similar to the TK_RELIEF_XXX values, except we added
* TIX_RELIEF_SOLID.
*
* TODO: is this option documented??
*/
#define TIX_RELIEF_RAISED 1
#define TIX_RELIEF_FLAT 2
#define TIX_RELIEF_SUNKEN 4
#define TIX_RELIEF_GROOVE 8
#define TIX_RELIEF_RIDGE 16
#define TIX_RELIEF_SOLID 32
typedef int Tix_Relief;
extern Tk_CustomOption tixConfigItemType;
extern Tk_CustomOption tixConfigItemStyle;
extern Tk_CustomOption tixConfigRelief;
/*
* C functions exported by Tix
*/
EXTERN int Tix_ArgcError _ANSI_ARGS_((Tcl_Interp *interp,
int argc, CONST84 char ** argv, int prefixCount,
CONST84 char *message));
EXTERN void Tix_CreateCommands _ANSI_ARGS_((
Tcl_Interp *interp, Tix_TclCmd *commands,
ClientData clientData,
Tcl_CmdDeleteProc *deleteProc));
EXTERN Tk_Window Tix_CreateSubWindow _ANSI_ARGS_((
Tcl_Interp * interp, Tk_Window tkwin,
CONST84 char * subPath));
EXTERN int Tix_DefinePixmap _ANSI_ARGS_((
Tcl_Interp * interp, Tk_Uid name, char **data));
EXTERN void Tix_DrawAnchorLines _ANSI_ARGS_((
Display *display, Drawable drawable,
GC gc, int x, int y, int w, int h));
EXTERN int Tix_EvalArgv _ANSI_ARGS_((
Tcl_Interp * interp, int argc, CONST84 char ** argv));
EXTERN int Tix_ExistMethod _ANSI_ARGS_((Tcl_Interp *interp,
CONST84 char *context, CONST84 char *method));
EXTERN void Tix_Exit _ANSI_ARGS_((Tcl_Interp * interp, int code));
EXTERN Pixmap Tix_GetRenderBuffer _ANSI_ARGS_((Display *display,
Drawable d, int width, int height, int depth));
EXTERN GC Tix_GetAnchorGC _ANSI_ARGS_((Tk_Window tkwin,
XColor *bgColor));
EXTERN int Tix_GlobalVarEval _ANSI_ARGS_(
TCL_VARARGS(Tcl_Interp *,interp));
EXTERN int Tix_HandleSubCmds _ANSI_ARGS_((
Tix_CmdInfo * cmdInfo,
Tix_SubCmdInfo * subCmdInfo,
ClientData clientData, Tcl_Interp *interp,
int argc, CONST84 char **argv));
EXTERN int Tix_Init _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN void Tix_OpenStdin _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN void Tix_SetArgv _ANSI_ARGS_((Tcl_Interp *interp,
int argc, CONST84 char **argv));
EXTERN void Tix_SetRcFileName _ANSI_ARGS_((
Tcl_Interp * interp, CONST84 char * rcFileName));
EXTERN char * Tix_ZAlloc _ANSI_ARGS_((unsigned int nbytes));
/*
* Commands exported by Tix
*
*/
extern TIX_DECLARE_CMD(Tix_CallMethodCmd);
extern TIX_DECLARE_CMD(Tix_ChainMethodCmd);
extern TIX_DECLARE_CMD(Tix_ClassCmd);
extern TIX_DECLARE_CMD(Tix_DoWhenIdleCmd);
extern TIX_DECLARE_CMD(Tix_DoWhenMappedCmd);
extern TIX_DECLARE_CMD(Tix_FileCmd);
extern TIX_DECLARE_CMD(Tix_FlushXCmd);
extern TIX_DECLARE_CMD(Tix_FormCmd);
extern TIX_DECLARE_CMD(Tix_GridCmd);
extern TIX_DECLARE_CMD(Tix_GeometryRequestCmd);
extern TIX_DECLARE_CMD(Tix_Get3DBorderCmd);
extern TIX_DECLARE_CMD(Tix_GetDefaultCmd);
extern TIX_DECLARE_CMD(Tix_GetMethodCmd);
extern TIX_DECLARE_CMD(Tix_HListCmd);
extern TIX_DECLARE_CMD(Tix_HandleOptionsCmd);
extern TIX_DECLARE_CMD(Tix_InputOnlyCmd);
extern TIX_DECLARE_CMD(Tix_ItemStyleCmd);
extern TIX_DECLARE_CMD(Tix_ManageGeometryCmd);
extern TIX_DECLARE_CMD(Tix_MapWindowCmd);
extern TIX_DECLARE_CMD(Tix_MoveResizeWindowCmd);
extern TIX_DECLARE_CMD(Tix_NoteBookFrameCmd);
extern TIX_DECLARE_CMD(Tix_ShellInputCmd);
extern TIX_DECLARE_CMD(Tix_TListCmd);
extern TIX_DECLARE_CMD(Tix_TmpLineCmd);
extern TIX_DECLARE_CMD(Tix_UnmapWindowCmd);
extern TIX_DECLARE_CMD(Tix_MwmCmd);
extern TIX_DECLARE_CMD(Tix_CreateWidgetCmd);
#define SET_RECORD(interp, record, var, value) \
Tcl_SetVar2(interp, record, var, value, TCL_GLOBAL_ONLY)
#define GET_RECORD(interp, record, var) \
Tcl_GetVar2(interp, record, var, TCL_GLOBAL_ONLY)
#define TIX_HASHKEY(k) ((sizeof(k)>sizeof(int))?((char*)&(k)):((char*)(k)))
/*----------------------------------------------------------------------
* Compatibility section
*----------------------------------------------------------------------
*/
#if defined(__WIN32__) && !defined(strcasecmp)
#define strcasecmp _stricmp
#endif
/*
* end block for C++
*/
#ifdef __cplusplus
}
#endif
#endif /* _TIX_H_ */

163
generic/tixAppInit.c Normal file
View File

@@ -0,0 +1,163 @@
/*
* tixAppInit.c --
*
* Provides a default version of the Tcl_AppInit procedure for
* use in wish and similar Tk-based applications.
*
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1994 Sun Microsystems, Inc.
* Copyright (c) 2000 Tix Project Group.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tixAppInit.c,v 1.2 2008/02/28 04:05:29 hobbs Exp $
*/
#ifdef USE_TCL_STUBS
#undef USE_TCL_STUBS
#endif
#ifdef USE_TK_STUBS
#undef USE_TK_STUBS
#endif
#include <tk.h>
#include <tix.h>
#ifdef __WIN32__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#endif
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
/*
* The following variable is a special hack that is needed in order for
* Sun shared libraries to be used for Tcl.
*/
extern int matherr();
int *tclDummyMathPtr = (int *) matherr;
#endif /* UNIX */
#ifndef NO_MAIN
/*
*----------------------------------------------------------------------
*
* main --
*
* This is the main program for the application.
*
* Results:
* None: Tk_Main never returns here, so this procedure never
* returns either.
*
* Side effects:
* Whatever the application does.
*
*----------------------------------------------------------------------
*/
int
main(argc, argv)
int argc; /* Number of command-line arguments. */
char **argv; /* Values of command-line arguments. */
{
Tk_Main(argc, argv, Tcl_AppInit);
return 0; /* Needed only to prevent compiler warning. */
}
#endif /* NO_MAIN */
/*
*----------------------------------------------------------------------
*
* Tcl_AppInit --
*
* This procedure performs application-specific initialization.
* Most applications, especially those that incorporate additional
* packages, will have their own version of this procedure.
*
* Results:
* Returns a standard Tcl completion code, and leaves an error
* message in interp's result if an error occurs.
*
* Side effects:
* Depends on the startup script.
*
*----------------------------------------------------------------------
*/
int
Tcl_AppInit(interp)
Tcl_Interp *interp; /* Interpreter for application. */
{
if (Tcl_Init(interp) == TCL_ERROR) {
goto error;
}
if (Tk_Init(interp) == TCL_ERROR) {
goto error;
}
Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL);
if (Tix_Init(interp) == TCL_ERROR) {
goto error;
}
Tcl_StaticPackage(interp, "Tix", Tix_Init, (Tcl_PackageInitProc *) NULL);
#if defined(__WIN32__) && defined(GUI_MODE_APP)
/*
* Initialize the console only if we are running as an interactive
* application.
*/
if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {
goto error;
}
#endif /* __WIN32__ */
/*
* Call the init procedures for included packages. Each call should
* look like this:
*
* if (Mod_Init(interp) == TCL_ERROR) {
* goto error;
* }
*
* where "Mod" is the name of the module.
*/
/*
* Call Tcl_CreateCommand for application-specific commands, if
* they weren't already created by the init procedures called above.
*/
/*
* Specify a user-specific startup file to invoke if the application
* is run interactively. Typically the startup file is "~/.apprc"
* where "app" is the name of the application. If this line is deleted
* then no user-specific startup file will be run under any conditions.
*/
Tix_SetRcFileName(interp, "~/.tixwishrc");
return TCL_OK;
error:
#if defined(__WIN32__) && defined(GUI_MODE_APP)
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(NULL, Tcl_GetStringResult(interp), "Error in Wish",
MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
ExitProcess(1);
/* we won't reach this, but we need the return */
#endif /* __WIN32__ */
return TCL_ERROR;
}

1988
generic/tixClass.c Normal file

File diff suppressed because it is too large Load Diff

687
generic/tixCmds.c Normal file
View File

@@ -0,0 +1,687 @@
/*
* tixCmds.c --
*
* Implements various TCL commands for Tix. This file contains
* misc small commands, or groups of commands, that are not big
* enough to be put in a separate file.
*
* Copyright (c) 1993-1999 Ioi Kim Lam.
* Copyright (c) 2000 Tix Project Group.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tixCmds.c,v 1.4 2004/03/28 02:44:56 hobbs Exp $
*/
#include <tixPort.h>
#include <tixInt.h>
#include <tixDef.h>
#include <math.h>
TIX_DECLARE_CMD(Tix_ParentWindow);
/*
* Maximum intensity for a color:
*/
#define MAX_INTENSITY ((int) 65535)
/*
* Data structure used by the tixDoWhenIdle command.
*/
typedef struct {
Tcl_Interp * interp;
char * command;
Tk_Window tkwin;
} IdleStruct;
/*
* Data structures used by the tixDoWhenMapped command.
*/
typedef struct _MapCmdLink {
char * command;
struct _MapCmdLink * next;
} MapCmdLink;
typedef struct {
Tcl_Interp * interp;
Tk_Window tkwin;
MapCmdLink * cmds;
} MapEventStruct;
/*
* Global vars
*/
static Tcl_HashTable idleTable; /* hash table for TixDoWhenIdle */
static Tcl_HashTable mapEventTable; /* hash table for TixDoWhenMapped */
/*
* Functions used only in this file.
*/
static void IdleHandler _ANSI_ARGS_((ClientData clientData));
static void EventProc _ANSI_ARGS_((ClientData clientData,
XEvent *eventPtr));
static void MapEventProc _ANSI_ARGS_((ClientData clientData,
XEvent *eventPtr));
static int IsOption _ANSI_ARGS_((CONST84 char *option,
int optArgc, CONST84 char **optArgv));
static XColor * ScaleColor _ANSI_ARGS_((Tk_Window tkwin,
XColor * color, double scale));
static char * NameOfColor _ANSI_ARGS_((XColor * colorPtr));
/*----------------------------------------------------------------------
* Tix_DoWhenIdle --
*
* The difference between "tixDoWhenIdle" and "after" is: the
* "after" handler is called after all other TK Idel Event
* Handler are called. Sometimes this will cause some toplevel
* windows to be mapped before the Idle Event Handler is
* executed.
*
* This behavior of "after" is not suitable for implementing
* geometry managers. Therefore I wrote "tixDoWhenIdle" which is
* an exact TCL interface for Tk_DoWhenIdle()
*----------------------------------------------------------------------
*/
TIX_DEFINE_CMD(Tix_DoWhenIdleCmd)
{
int isNew;
char * command;
static int inited = 0;
IdleStruct * iPtr;
Tk_Window tkwin;
Tcl_HashEntry * hashPtr;
if (!inited) {
Tcl_InitHashTable(&idleTable, TCL_STRING_KEYS);
inited = 1;
}
/*
* parse the arguments
*/
if (strncmp(argv[0], "tixWidgetDoWhenIdle", strlen(argv[0]))== 0) {
if (argc<3) {
return Tix_ArgcError(interp, argc, argv, 1,
"command window ?arg arg ...?");
}
/* tixWidgetDoWhenIdle reqires that the second argument must
* be the name of a mega widget
*/
tkwin=Tk_NameToWindow(interp, argv[2], Tk_MainWindow(interp));
if (tkwin == NULL) {
return TCL_ERROR;
}
} else {
if (argc<2) {
return Tix_ArgcError(interp, argc, argv, 1,
"command ?arg arg ...?");
}
tkwin = NULL;
}
command = Tcl_Merge(argc-1, argv+1);
hashPtr = Tcl_CreateHashEntry(&idleTable, command, &isNew);
if (!isNew) {
ckfree(command);
} else {
iPtr = (IdleStruct *) ckalloc(sizeof(IdleStruct));
iPtr->interp = interp;
iPtr->command = command;
iPtr->tkwin = tkwin;
Tcl_SetHashValue(hashPtr, (char*)iPtr);
if (tkwin) {
/* we just want one event handler for all idle events
* associated with a window. This is done by first calling
* Delete and then Create EventHandler.
*/
Tk_DeleteEventHandler(tkwin, StructureNotifyMask, EventProc,
(ClientData)tkwin);
Tk_CreateEventHandler(tkwin, StructureNotifyMask, EventProc,
(ClientData)tkwin);
}
Tk_DoWhenIdle(IdleHandler, (ClientData) iPtr);
}
return TCL_OK;
}
/*----------------------------------------------------------------------
* Tix_DoWhenMapped
*
* Arranges a command to be called when the window received an
* <Map> event.
*
* argv[1..] = command argvs
*
*----------------------------------------------------------------------
*/
TIX_DEFINE_CMD(Tix_DoWhenMappedCmd)
{
Tcl_HashEntry * hashPtr;
int isNew;
MapEventStruct * mPtr;
MapCmdLink * cmd;
Tk_Window tkwin;
static int inited = 0;
if (argc!=3) {
return Tix_ArgcError(interp, argc, argv, 1, " pathname command");
}
tkwin = Tk_NameToWindow(interp, argv[1], Tk_MainWindow(interp));
if (tkwin == NULL) {
return TCL_ERROR;
}
if (!inited) {
Tcl_InitHashTable(&mapEventTable, TCL_ONE_WORD_KEYS);
inited = 1;
}
hashPtr = Tcl_CreateHashEntry(&mapEventTable, (char*)tkwin, &isNew);
if (!isNew) {
mPtr = (MapEventStruct*) Tcl_GetHashValue(hashPtr);
} else {
mPtr = (MapEventStruct*) ckalloc(sizeof(MapEventStruct));
mPtr->interp = interp;
mPtr->tkwin = tkwin;
mPtr->cmds = 0;
Tcl_SetHashValue(hashPtr, (char*)mPtr);
Tk_CreateEventHandler(tkwin, StructureNotifyMask,
MapEventProc, (ClientData)mPtr);
}
/*
* Add this into a link list
*/
cmd = (MapCmdLink*) ckalloc(sizeof(MapCmdLink));
cmd->command = tixStrDup(argv[2]);
cmd->next = mPtr->cmds;
mPtr->cmds = cmd;
return TCL_OK;
}
/*----------------------------------------------------------------------
* Tix_Get3DBorderCmd
*
* Returns the upper and lower border shades of a color. Returns then
* in a list of two X color names.
*
* The color is not very useful if the display is a mono display:
* it will just return black and white. So a clever program may
* want to check the [tk colormodel] and if it is mono, then
* dither using a bitmap.
*----------------------------------------------------------------------
*/
TIX_DEFINE_CMD(Tix_Get3DBorderCmd)
{
XColor * color, * light, * dark;
Tk_Window tkwin;
Tk_Uid colorUID;
if (argc != 2) {
return Tix_ArgcError(interp, argc, argv, 0, "colorName");
}
tkwin = Tk_MainWindow(interp);
colorUID = Tk_GetUid(argv[1]);
color = Tk_GetColor(interp, tkwin, colorUID);
if (color == NULL) {
return TCL_ERROR;
}
if ((light = ScaleColor(tkwin, color, 1.4)) == NULL) {
return TCL_ERROR;
}
if ((dark = ScaleColor(tkwin, color, 0.6)) == NULL) {
return TCL_ERROR;
}
Tcl_ResetResult(interp);
Tcl_AppendElement(interp, NameOfColor(light));
Tcl_AppendElement(interp, NameOfColor(dark));
Tk_FreeColor(color);
Tk_FreeColor(light);
Tk_FreeColor(dark);
return TCL_OK;
}
/*----------------------------------------------------------------------
* Tix_HandleOptionsCmd
*
*
* argv[1] = recordName
* argv[2] = validOptions
* argv[3] = argList
* if (argv[3][0] == "-nounknown") then
* don't complain about unknown options
*----------------------------------------------------------------------
*/
TIX_DEFINE_CMD(Tix_HandleOptionsCmd)
{
int listArgc;
int optArgc;
CONST84 char ** listArgv = 0;
CONST84 char ** optArgv = 0;
int i, code = TCL_OK;
int noUnknown = 0;
if (argc >= 2 && (strcmp(argv[1], "-nounknown") == 0)) {
noUnknown = 1;
argv[1] = argv[0];
argc --;
argv ++;
}
if (argc!=4) {
return Tix_ArgcError(interp, argc, argv, 2, "w validOptions argList");
}
if (Tcl_SplitList(interp, argv[2], &optArgc, &optArgv ) != TCL_OK) {
code = TCL_ERROR;
goto done;
}
if (Tcl_SplitList(interp, argv[3], &listArgc, &listArgv) != TCL_OK) {
code = TCL_ERROR;
goto done;
}
if ((listArgc %2) == 1) {
if (noUnknown || IsOption(listArgv[listArgc-1], optArgc, optArgv)) {
Tcl_AppendResult(interp, "value for \"", listArgv[listArgc-1],
"\" missing", (char*)NULL);
} else {
Tcl_AppendResult(interp, "unknown option \"", listArgv[listArgc-1],
"\"", (char*)NULL);
}
code = TCL_ERROR;
goto done;
}
for (i=0; i<listArgc; i+=2) {
if (IsOption(listArgv[i], optArgc, optArgv)) {
Tcl_SetVar2(interp, argv[1], listArgv[i], listArgv[i+1], 0);
}
else if (!noUnknown) {
Tcl_AppendResult(interp, "unknown option \"", listArgv[i],
"\"; must be one of \"", argv[2], "\".", NULL);
code = TCL_ERROR;
goto done;
}
}
done:
if (listArgv) {
ckfree((char *) listArgv);
}
if (optArgv) {
ckfree((char *) optArgv);
}
return code;
}
/*----------------------------------------------------------------------
* Tix_SetWindowParent --
*
* Sets the parent of a window. This is normally to change the
* state of toolbar and MDI windows between docking and free
* modes.
*
* Results:
* Standard Tcl results.
*
* Side effects:
* Windows may be re-parented. See user documentation.
*----------------------------------------------------------------------
*/
TIX_DEFINE_CMD(Tix_ParentWindow)
{
Tk_Window mainWin, tkwin, newParent;
int parentId;
if (argc != 3) {
return Tix_ArgcError(interp, argc, argv, 1, "window parent");
}
mainWin = Tk_MainWindow(interp);
if (mainWin == NULL) {
Tcl_SetResult(interp, "interpreter does not have a main window",
TCL_STATIC);
return TCL_ERROR;
}
tkwin = Tk_NameToWindow(interp, argv[1], mainWin);
if (tkwin == NULL) {
return TCL_ERROR;
}
newParent = Tk_NameToWindow(interp, argv[2], mainWin);
if (newParent == NULL) {
if (Tcl_GetInt(interp, argv[2], &parentId) != TCL_OK) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "\"", argv[2],
"\" must be a window pathname or ID", NULL);
return TCL_ERROR;
}
}
return TixpSetWindowParent(interp, tkwin, newParent, parentId);
}
/*----------------------------------------------------------------------
* Tix_TmpLineCmd
*
* Draw a temporary line on the root window
*
* argv[1..] = x1 y1 x2 y2
*----------------------------------------------------------------------
*/
TIX_DEFINE_CMD(Tix_TmpLineCmd)
{
Tk_Window mainWin = (Tk_Window)clientData;
Tk_Window tkwin;
int x1, y1, x2, y2;
if (argc != 5 && argc != 6) {
return Tix_ArgcError(interp, argc, argv, 0,
"tixTmpLine x1 y1 x2 y2 ?window?");
}
if (Tcl_GetInt(interp, argv[1], &x1) != TCL_OK) {
return TCL_ERROR;
}
if (Tcl_GetInt(interp, argv[2], &y1) != TCL_OK) {
return TCL_ERROR;
}
if (Tcl_GetInt(interp, argv[3], &x2) != TCL_OK) {
return TCL_ERROR;
}
if (Tcl_GetInt(interp, argv[4], &y2) != TCL_OK) {
return TCL_ERROR;
}
if (argc == 6) {
/*
* argv[5] tells which display to draw the tmp lines on, in
* case the application has opened more than one displays. If
* this argv[5] is omitted, draws to the display where the
* main window is on.
*/
tkwin = Tk_NameToWindow(interp, argv[5], mainWin);
if (tkwin == NULL) {
return TCL_ERROR;
}
} else {
tkwin = Tk_MainWindow(interp);
}
TixpDrawTmpLine(x1, y1, x2, y2, tkwin);
return TCL_OK;
}
/*----------------------------------------------------------------------
* EventProc --
*
* Monitors events sent to a window associated with a
* tixWidgetDoWhenIdle command. If this window is destroyed,
* remove the idle handlers associated with this window.
*----------------------------------------------------------------------
*/
static void EventProc(clientData, eventPtr)
ClientData clientData;
XEvent *eventPtr;
{
Tk_Window tkwin = (Tk_Window)clientData;
Tcl_HashSearch hSearch;
Tcl_HashEntry * hashPtr;
IdleStruct * iPtr;
if (eventPtr->type != DestroyNotify) {
return;
}
/* Iterate over all the entries in the hash table */
for (hashPtr = Tcl_FirstHashEntry(&idleTable, &hSearch);
hashPtr;
hashPtr = Tcl_NextHashEntry(&hSearch)) {
iPtr = (IdleStruct *)Tcl_GetHashValue(hashPtr);
if (iPtr->tkwin == tkwin) {
Tcl_DeleteHashEntry(hashPtr);
Tk_CancelIdleCall(IdleHandler, (ClientData) iPtr);
ckfree((char*)iPtr->command);
ckfree((char*)iPtr);
}
}
}
/*----------------------------------------------------------------------
* IdleHandler --
*
* Called when Tk is idle. Dispatches all commands registered by
* tixDoWhenIdle and tixWidgetDoWhenIdle.
*----------------------------------------------------------------------
*/
static void IdleHandler(clientData)
ClientData clientData; /* TCL command to evaluate */
{
Tcl_HashEntry * hashPtr;
IdleStruct * iPtr;
iPtr = (IdleStruct *) clientData;
/*
* Clean up the hash table. Note that we have to do this BEFORE
* calling the TCL command. Otherwise if the TCL command tries
* to register itself again, it will fail in Tix_DoWhenIdleCmd()
* because the command is still in the hashtable
*/
hashPtr = Tcl_FindHashEntry(&idleTable, iPtr->command);
if (hashPtr) {
Tcl_DeleteHashEntry(hashPtr);
} else {
/* Probably some kind of error */
return;
}
if (Tcl_GlobalEval(iPtr->interp, iPtr->command) != TCL_OK) {
if (iPtr->tkwin != NULL) {
Tcl_AddErrorInfo(iPtr->interp,
"\n (idle event handler executed by tixWidgetDoWhenIdle)");
} else {
Tcl_AddErrorInfo(iPtr->interp,
"\n (idle event handler executed by tixDoWhenIdle)");
}
Tk_BackgroundError(iPtr->interp);
}
ckfree((char*)iPtr->command);
ckfree((char*)iPtr);
}
/*----------------------------------------------------------------------
* IsOption --
*
* Checks whether the string pointed by "option" is one of the
* options given by the "optArgv" array.
*----------------------------------------------------------------------
*/
static int IsOption(option, optArgc, optArgv)
CONST84 char *option; /* Number of arguments. */
int optArgc; /* Number of arguments. */
CONST84 char **optArgv; /* Argument strings. */
{
int i;
for (i=0; i<optArgc; i++) {
if (strcmp(option, optArgv[i]) == 0) {
return 1;
}
}
return 0;
}
static void MapEventProc(clientData, eventPtr)
ClientData clientData; /* TCL command to evaluate */
XEvent *eventPtr; /* Information about event. */
{
Tcl_HashEntry * hashPtr;
MapEventStruct * mPtr;
MapCmdLink * cmd;
if (eventPtr->type != MapNotify) {
return;
}
mPtr = (MapEventStruct *) clientData;
Tk_DeleteEventHandler(mPtr->tkwin, StructureNotifyMask,
MapEventProc, (ClientData)mPtr);
/* Clean up the hash table.
*/
if ((hashPtr = Tcl_FindHashEntry(&mapEventTable, (char*)mPtr->tkwin))) {
Tcl_DeleteHashEntry(hashPtr);
}
for (cmd = mPtr->cmds; cmd; ) {
MapCmdLink * old;
/* Execute the event handler */
if (Tcl_GlobalEval(mPtr->interp, cmd->command) != TCL_OK) {
Tcl_AddErrorInfo(mPtr->interp,
"\n (event handler executed by tixDoWhenMapped)");
Tk_BackgroundError(mPtr->interp);
}
/* Delete the link */
old = cmd;
cmd = cmd->next;
ckfree(old->command);
ckfree((char*)old);
}
/* deallocate the mapEventStruct */
ckfree((char*)mPtr);
}
static char *
NameOfColor(colorPtr)
XColor * colorPtr;
{
static char string[20];
char *ptr;
sprintf(string, "#%4x%4x%4x", colorPtr->red, colorPtr->green,
colorPtr->blue);
for (ptr = string; *ptr; ptr++) {
if (*ptr == ' ') {
*ptr = '0';
}
}
return string;
}
static XColor *
ScaleColor(tkwin, color, scale)
Tk_Window tkwin;
XColor * color;
double scale;
{
int r, g, b;
XColor test;
r = (int)((float)(color->red) * scale);
g = (int)((float)(color->green) * scale);
b = (int)((float)(color->blue) * scale);
if (r > MAX_INTENSITY) { r = MAX_INTENSITY; }
if (g > MAX_INTENSITY) { g = MAX_INTENSITY; }
if (b > MAX_INTENSITY) { b = MAX_INTENSITY; }
test.red = (unsigned short) r;
test.green = (unsigned short) g;
test.blue = (unsigned short) b;
return Tk_GetColorByValue(tkwin, &test);
}
/*----------------------------------------------------------------------
* Tix_GetDefaultCmd
*
* Implements the tixGetDefault command.
*
* Returns values for various default configuration options,
* as defined in tixDef.h and tkDefault.h.
*
* This command makes it possible to define default options
* for the Tcl-implemented widgets according to platform-
* specific values set in the C header files.
*
* Note: there is no reason to make this an ObjCmd because the
* same Tcl command is unlikely to be executed twice. The old
* style "string" command is more compact and less prone to
* programming errors.
*----------------------------------------------------------------------
*/
TIX_DEFINE_CMD(Tix_GetDefaultCmd)
{
unsigned int i;
# define OPT(x) {#x, x}
static char *table[][2] = {
OPT(ACTIVE_BG),
OPT(CTL_FONT),
OPT(DISABLED),
OPT(HIGHLIGHT),
OPT(INDICATOR),
OPT(MENU_BG),
OPT(MENU_FG),
OPT(NORMAL_BG),
OPT(NORMAL_FG),
OPT(SELECT_BG),
OPT(SELECT_FG),
OPT(TEXT_FG),
OPT(TROUGH),
OPT(TIX_EDITOR_BG),
OPT(TIX_BORDER_WIDTH),
OPT(TIX_HIGHLIGHT_THICKNESS),
};
if (argc != 2) {
return Tix_ArgcError(interp, argc, argv, 1, "optionName");
}
for (i=0; i<Tix_ArraySize(table); i++) {
if (strcmp(argv[1], table[i][0]) == 0) {
Tcl_SetResult(interp, table[i][1], TCL_STATIC);
return TCL_OK;
}
}
Tcl_AppendResult(interp, "unknown option \"", argv[1],
"\"", NULL);
return TCL_ERROR;
}

64
generic/tixCompat.c Normal file
View File

@@ -0,0 +1,64 @@
/* $Id: tixCompat.c,v 1.2 2001/01/08 06:15:32 ioilam Exp $ */
/*
* tixCompat.c --
*
* Some compatibility functions for Tix.
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#include <tixPort.h>
#include <tixInt.h>
/*
* strdup is not a POSIX call and is not supported on many platforms.
*/
char * tixStrDup(s)
CONST char * s;
{
size_t len = strlen(s)+1;
char * new_string;
new_string = (char*)ckalloc(len);
strcpy(new_string, s);
return new_string;
}
#ifdef NO_STRCASECMP
int tixStrCaseCmp _ANSI_ARGS_((CONST char * a, CONST char * b));
int tixStrCaseCmp(a, b)
CONST char * a;
CONST char * b;
{
while (1) {
if (*a== 0 && *b==0) {
return 0;
}
if (*a==0) {
return (1);
}
if (*b==0) {
return (-1);
}
if (tolower(*a)>tolower(*b)) {
return (-1);
}
if (tolower(*b)>tolower(*a)) {
return (1);
}
a++; b++;
}
}
#endif /* NO_STRCASECMP */

839
generic/tixDItem.c Normal file
View File

@@ -0,0 +1,839 @@
/*
* tixDItem.c --
*
* This file implements the "Display Items" in the Tix library.
*
* Since many Tix widgets use the same type of display items, for
* example, text items, image items, or text-image items (used in
* HList, TList and Table), it makes sense to provide a set of
* common routines to support these display items. Code re-use is
* the major issue: we don't want to re-define almost the same
* configSpecs again and again in different widgets. Therefore,
* all display items provide common methods to configure,
* display, calculate geometry, etc.
*
*
* Copyright (c) 1993-1999 Ioi Kim Lam.
* Copyright (c) 2000-2001 Tix Project Group.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tixDItem.c,v 1.3 2004/03/28 02:44:56 hobbs Exp $
*/
#include <tixPort.h>
#include <tixInt.h>
static int DItemParseProc _ANSI_ARGS_((ClientData clientData,
Tcl_Interp *interp, Tk_Window tkwin, CONST84 char *value,
char *widRec, int offset));
static char *DItemPrintProc _ANSI_ARGS_((
ClientData clientData, Tk_Window tkwin, char *widRec,
int offset, Tcl_FreeProc **freeProcPtr));
/*----------------------------------------------------------------------
*
*
* PUBLIC INTERFACE
*
*
* The following functions are called by widget implementors
*
*----------------------------------------------------------------------
*/
/* Tix_AddDItemType, Tix_GetDItemType --
*
*
* Maintain a list of item types, each identifies by a unique string
* name;
*/
static Tix_DItemInfo * diTypes = NULL;
void Tix_AddDItemType(diTypePtr)
Tix_DItemInfo * diTypePtr;
{
diTypePtr->next = diTypes;
diTypes = diTypePtr;
}
Tix_DItemInfo * Tix_GetDItemType(interp, type)
Tcl_Interp * interp;
CONST84 char * type;
{
Tix_DItemInfo * diTypePtr;
for (diTypePtr = diTypes; diTypePtr; diTypePtr = diTypePtr->next) {
if (strcmp(type, diTypePtr->name)==0) {
return diTypePtr;
}
}
if (interp) {
Tcl_AppendResult(interp, "unknown display type \"", type, "\"", NULL);
}
return NULL;
}
/*----------------------------------------------------------------------
* Tix_DItemCreate --
*
* Create a display item according to the "type" string.
*
*----------------------------------------------------------------------
*/
Tix_DItem * Tix_DItemCreate(ddPtr, type)
Tix_DispData * ddPtr;
CONST84 char * type;
{
Tix_DItemInfo * diTypePtr;
if ((diTypePtr = Tix_GetDItemType(ddPtr->interp, type)) == NULL) {
return NULL;
}
return diTypePtr->createProc(ddPtr, diTypePtr);
}
/*----------------------------------------------------------------------
* Tix_DItemConfigure --
*
* Configures a display item.
*
*----------------------------------------------------------------------
*/
int Tix_DItemConfigure(iPtr, argc, argv, flags)
Tix_DItem * iPtr;
int argc;
CONST84 char ** argv;
int flags;
{
return iPtr->base.diTypePtr->configureProc(iPtr, argc, argv, flags);
}
/*
*----------------------------------------------------------------------
*
* Tix_DItemDisplay --
*
* Display a DItem. {x, y, width, height} specifies a region
* for to display this item in. {xOffset, yOffset} gives the
* offset of the top-left corner of the item relative to
* the top-left corder of the region.
*
* Background and foreground of the item are displayed according
* to the flags parameter.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
Tix_DItemDisplay(drawable, iPtr, x, y, width, height, xOffset, yOffset,flags)
Drawable drawable;
Tix_DItem * iPtr;
int x;
int y;
int width;
int height;
int xOffset;
int yOffset;
int flags;
{
iPtr->base.diTypePtr->displayProc(drawable, iPtr, x, y,
width, height, xOffset, yOffset, flags);
}
void Tix_DItemFree(iPtr)
Tix_DItem * iPtr;
{
iPtr->base.diTypePtr->freeProc(iPtr);
/*
* When it comes to here, iPtr is no longer a valid pointer!
*/
}
void Tix_DItemCalculateSize(iPtr)
Tix_DItem * iPtr;
{
iPtr->base.diTypePtr->calculateSizeProc(iPtr);
}
char * Tix_DItemComponent(iPtr, x, y)
Tix_DItem * iPtr;
int x;
int y;
{
return (iPtr->base.diTypePtr->componentProc(iPtr, x, y));
}
/*----------------------------------------------------------------------
* Tix_FreeArgumentList --
*
* Free the argument lists allocated by Tix_SplitConfig;
*----------------------------------------------------------------------
*/
void
Tix_FreeArgumentList(argListPtr)
Tix_ArgumentList *argListPtr;
{
int i;
for (i=0; i<argListPtr->numLists; i++) {
ckfree((char*)argListPtr->arg[i].argv);
}
if (argListPtr->arg != argListPtr->preAlloc) {
ckfree((char*)argListPtr->arg);
}
}
/*----------------------------------------------------------------------
* Tix_SplitConfig --
*
* Split the command line arguments according for several configurable
* objects.
*----------------------------------------------------------------------
*/
int
Tix_SplitConfig(interp, tkwin, specsList, numLists, argc, argv, argListPtr)
Tcl_Interp * interp;
Tk_Window tkwin;
Tk_ConfigSpec ** specsList; /* a list of two or more config spec
* arrays */
int numLists;
int argc;
CONST84 char ** argv;
Tix_ArgumentList * argListPtr;
{
Tix_Argument *arg;
int i, n, code = TCL_OK;
Tk_ConfigSpec *specPtr;
size_t len;
int found;
if (argc % 2) {
Tcl_AppendResult(interp, "value for \"", argv[argc-1],
"\" missing", (char *) NULL);
return TCL_ERROR;
}
if (numLists > FIXED_SIZE) {
arg = (Tix_Argument*)ckalloc(numLists * sizeof(Tix_Argument));
} else {
arg = argListPtr->preAlloc;
}
argListPtr->arg = arg;
argListPtr->numLists = numLists;
for (i=0; i<numLists; i++) {
arg[i].argc = 0;
arg[i].argv = (CONST84 char**)ckalloc(argc * sizeof(char*));
}
/* Split the arguments for the appropriate objects */
for (n=0; n<argc; n+=2) {
len = strlen(argv[n]);
found = 0;
for (i=0; i<numLists; i++) {
for (specPtr=specsList[i];
specPtr->type != TK_CONFIG_END;
specPtr++) {
if (specPtr->argvName == NULL) {
continue;
}
if (strncmp(argv[n], specPtr->argvName, len) == 0) {
arg[i].argv[arg[i].argc++] = argv[n ];
arg[i].argv[arg[i].argc++] = argv[n+1];
found = 1;
break;
}
}
}
if (found == 0) {
Tcl_AppendResult(interp, "unknown option \"", argv[n],
"\"", (char *) NULL);
code = TCL_ERROR;
goto done;
}
}
done:
if (code == TCL_ERROR) {
Tix_FreeArgumentList(argListPtr);
}
return code;
}
int
Tix_MultiConfigureInfo(interp, tkwin, specsList, numLists, widgRecList,
argvName, flags, request)
Tcl_Interp *interp; /* Interpreter for error reporting. */
Tk_Window tkwin; /* Window corresponding to widgRec. */
Tk_ConfigSpec **specsList; /* Describes legal options. */
int numLists;
CONST84 char **widgRecList; /* Record whose fields contain current
* values for options. */
CONST84 char *argvName; /* If non-NULL, indicates a single option
* whose info is to be returned. Otherwise
* info is returned for all options. */
int flags; /* Used to specify additional flags
* that must be present in config specs
* for them to be considered. */
int request;
{
int i, found;
Tk_ConfigSpec *specPtr;
Tcl_DString dString;
size_t len;
CONST84 char *result;
if (argvName != NULL) {
len = strlen(argvName);
for (found=0,i=0; i<numLists; i++) {
for (specPtr=specsList[i];
specPtr->type != TK_CONFIG_END;
specPtr++) {
if (specPtr->argvName == NULL) {
continue;
}
if (strncmp(argvName, specPtr->argvName, len) == 0) {
found = 1;
goto done;
}
}
}
done:
if (!found) {
Tcl_AppendResult(interp, "unknown option \"", argvName,
"\"", (char *) NULL);
return TCL_ERROR;
}
if (request == TIX_CONFIG_INFO) {
if (widgRecList[i] != NULL) {
return Tk_ConfigureInfo(interp, tkwin, specsList[i],
(char *) widgRecList[i], argvName, flags);
} else {
return TCL_OK;
}
} else {
if (widgRecList[i] != NULL) {
return Tk_ConfigureValue(interp, tkwin, specsList[i],
(char *) widgRecList[i], argvName, flags);
} else {
return TCL_OK;
}
}
}
Tcl_DStringInit(&dString);
for (i=0; i<numLists; i++) {
if (i != 0) {
Tcl_DStringAppend(&dString, " ", 1);
}
if (widgRecList[i] != NULL) {
Tk_ConfigureInfo(interp, tkwin, specsList[i],
(char *) widgRecList[i], NULL, flags);
}
result = Tcl_GetStringResult(interp);
Tcl_DStringAppend(&dString, result, (int) strlen(result));
}
Tcl_ResetResult(interp);
Tcl_DStringResult(interp, &dString);
Tcl_DStringFree(&dString);
return TCL_OK;
}
/*----------------------------------------------------------------------
* Tix_ConfigureValue2 --
*
*
* Returns the config information of a entry element (of an HList,
* for example) and its display item.
*----------------------------------------------------------------------
*/
int
Tix_ConfigureValue2(interp, tkwin, entRec, entConfigSpecs, iPtr,
argvName, flags)
Tcl_Interp *interp; /* Interpreter for error reporting. */
Tk_Window tkwin; /* Window corresponding to widgRec. */
CONST84 char * entRec;
Tk_ConfigSpec *entConfigSpecs; /* Describes legal options of the entry */
Tix_DItem * iPtr; /* points to the entry's data record */
CONST84 char *argvName; /* If non-NULL, indicates a single option
* whose info is to be returned. Otherwise
* info is returned for all options. */
int flags; /* Used to specify additional flags
* that must be present in config specs
* for them to be considered. */
{
Tk_ConfigSpec *specsList[2];
CONST84 char *widgRecList[2];
specsList[0] = entConfigSpecs;
specsList[1] = Tix_DItemConfigSpecs(iPtr);
widgRecList[1] = (CONST84 char*)iPtr;
widgRecList[0] = entRec;
return Tix_MultiConfigureInfo(interp, tkwin, specsList, 2, widgRecList,
argvName, flags, TIX_CONFIG_VALUE);
}
/*----------------------------------------------------------------------
* Tix_ConfigureInfo2 --
*
*
* Returns the config information of a entry element (of an HList,
* for example) and its display item.
*----------------------------------------------------------------------
*/
int
Tix_ConfigureInfo2(interp, tkwin, entRec, entConfigSpecs, iPtr,
argvName, flags)
Tcl_Interp *interp; /* Interpreter for error reporting. */
Tk_Window tkwin; /* Window corresponding to widgRec. */
CONST84 char * entRec;
Tk_ConfigSpec *entConfigSpecs; /* Describes legal options of the entry */
Tix_DItem * iPtr; /* points to the entry's data record */
CONST84 char *argvName; /* If non-NULL, indicates a single option
* whose info is to be returned. Otherwise
* info is returned for all options. */
int flags; /* Used to specify additional flags
* that must be present in config specs
* for them to be considered. */
{
Tk_ConfigSpec *specsList[2];
CONST84 char *widgRecList[2];
specsList[0] = entConfigSpecs;
specsList[1] = Tix_DItemConfigSpecs(iPtr);
widgRecList[1] = (CONST84 char*)iPtr;
widgRecList[0] = (CONST84 char*)entRec;
return Tix_MultiConfigureInfo(interp, tkwin, specsList, 2, widgRecList,
argvName, flags, TIX_CONFIG_INFO);
}
int
Tix_WidgetConfigure2(interp, tkwin, entRec, entConfigSpecs, iPtr,
argc, argv, flags, forced, sizeChanged_ret)
Tcl_Interp *interp; /* Interpreter for error reporting. */
Tk_Window tkwin; /* Window corresponding to widgRec. */
CONST84 char * entRec;
Tk_ConfigSpec *entConfigSpecs; /* Describes legal options of the entry */
Tix_DItem * iPtr; /* points to the entry's data record */
int argc;
CONST84 char ** argv;
int flags;
int forced; /* forced configure of DItem? */
int * sizeChanged_ret;
{
Tix_ArgumentList argList;
Tk_ConfigSpec *specsList[2];
CONST84 char *widgRecList[2];
int code = TCL_OK;
int dummy;
if (sizeChanged_ret == NULL) {
sizeChanged_ret = &dummy;
}
specsList[0] = entConfigSpecs;
specsList[1] = Tix_DItemConfigSpecs(iPtr);
widgRecList[0] = (CONST84 char*)entRec;
widgRecList[1] = (CONST84 char*)iPtr;
if (Tix_SplitConfig(interp, tkwin, specsList,
2, argc, argv, &argList) != TCL_OK) {
return TCL_ERROR;
}
/* Handle the info specific to the entry */
if (argList.arg[0].argc > 0) {
if (Tk_ConfigureWidget(interp, tkwin,
entConfigSpecs, argList.arg[0].argc, argList.arg[0].argv,
(char*)entRec, flags) != TCL_OK) {
code = TCL_ERROR;
goto done;
}
}
if (iPtr == NULL) {
goto done;
}
if (argList.arg[1].argc > 0 || forced) {
int oldSize[2];
oldSize[0] = iPtr->base.size[0];
oldSize[1] = iPtr->base.size[1];
if (Tix_DItemConfigure(iPtr, argList.arg[1].argc,
argList.arg[1].argv, flags) != TCL_OK) {
code = TCL_ERROR;
goto done;
}
if (oldSize[0] != iPtr->base.size[0] ||
oldSize[1] != iPtr->base.size[1]) {
* sizeChanged_ret = 1;
} else {
* sizeChanged_ret = 0;
}
}
done:
Tix_FreeArgumentList(&argList);
return code;
}
/*----------------------------------------------------------------------
*
* The Tix Customed Config Options
*
*----------------------------------------------------------------------
*/
/*
* The global data structures to use in widget configSpecs arrays
*
* These are declared in <tixConfig.h>
*/
Tk_CustomOption tixConfigItemType = {
DItemParseProc, DItemPrintProc, 0,
};
/*----------------------------------------------------------------------
* DItemParseProc --
*
* Parse the text string and store the Tix_DItemType information
* inside the widget record.
*----------------------------------------------------------------------
*/
static int DItemParseProc(clientData, interp, tkwin, value, widRec,offset)
ClientData clientData;
Tcl_Interp *interp;
Tk_Window tkwin;
CONST84 char *value;
char *widRec;
int offset;
{
Tix_DItemInfo *newPtr;
Tix_DItemInfo **ptr = (Tix_DItemInfo **)(widRec + offset);
if (value == NULL) {
newPtr = NULL;
} else {
newPtr = Tix_GetDItemType(interp, value);
if (newPtr == NULL) {
return TCL_ERROR;
}
}
*ptr = newPtr;
return TCL_OK;
}
static char *DItemPrintProc(clientData, tkwin, widRec,offset, freeProcPtr)
ClientData clientData;
Tk_Window tkwin;
char *widRec;
int offset;
Tcl_FreeProc **freeProcPtr;
{
Tix_DItemInfo *diTypePtr = *((Tix_DItemInfo**)(widRec+offset));
if (diTypePtr != NULL) {
return diTypePtr->name;
} else {
return 0;
}
}
/*----------------------------------------------------------------------
*
*
* PRIVATE INTERFACE
*
*
* The following functions are called by display type implementors
*
*----------------------------------------------------------------------
*/
/* The priority is selected > disabled > active > normal */
void
TixGetColorDItemGC(iPtr, backGC_ret, foreGC_ret, anchorGC_ret, flags)
Tix_DItem * iPtr;
GC * backGC_ret;
GC * foreGC_ret;
GC * anchorGC_ret;
int flags;
{
TixColorStyle * stylePtr = (TixColorStyle *) iPtr->base.stylePtr;
GC dummy;
int bg = 0;
if (backGC_ret == NULL) {
backGC_ret = &dummy;
}
if (foreGC_ret == NULL) {
foreGC_ret = &dummy;
}
if (anchorGC_ret == NULL) {
anchorGC_ret = &dummy;
}
if (flags & TIX_DITEM_SELECTED_FG) {
*foreGC_ret = stylePtr->colors[TIX_DITEM_SELECTED].foreGC;
}
else if (flags & TIX_DITEM_DISABLED_FG) {
*foreGC_ret = stylePtr->colors[TIX_DITEM_DISABLED].foreGC;
}
else if (flags & TIX_DITEM_ACTIVE_FG) {
*foreGC_ret = stylePtr->colors[TIX_DITEM_ACTIVE].foreGC;
}
else if (flags & TIX_DITEM_NORMAL_FG) {
*foreGC_ret = stylePtr->colors[TIX_DITEM_NORMAL].foreGC;
}
else {
*foreGC_ret = None;
}
if (flags & TIX_DITEM_SELECTED_BG) {
bg = TIX_DITEM_SELECTED;
} else if (flags & TIX_DITEM_DISABLED_BG) {
bg = TIX_DITEM_DISABLED;
} else if (flags & TIX_DITEM_ACTIVE_BG) {
bg = TIX_DITEM_ACTIVE;
} else if (flags & TIX_DITEM_NORMAL_BG) {
bg = TIX_DITEM_NORMAL;
} else {
bg = -1;
}
if (bg != -1) {
*backGC_ret = stylePtr->colors[bg].backGC;
} else {
*backGC_ret = None;
}
if ((flags & TIX_DITEM_ANCHOR) && (bg != -1)) {
*anchorGC_ret = stylePtr->colors[bg].anchorGC;
} else {
*anchorGC_ret = None;
}
}
/*----------------------------------------------------------------------
* TixDItemGetAnchor --
*
* Calculate the position of the element according to its anchor
*----------------------------------------------------------------------
*/
void
TixDItemGetAnchor(anchor, x, y, cav_w, cav_h, width, height, x_ret, y_ret)
Tk_Anchor anchor;
int x;
int y;
int cav_w;
int cav_h;
int width;
int height;
int * x_ret;
int * y_ret;
{
if (width > cav_w) {
* x_ret = x;
} else {
int rem = cav_w - width;
switch (anchor) {
case TK_ANCHOR_NW: case TK_ANCHOR_W: case TK_ANCHOR_SW:
* x_ret = x;
break;
case TK_ANCHOR_N: case TK_ANCHOR_CENTER: case TK_ANCHOR_S:
* x_ret = x + rem/2;
break;
default:
* x_ret = x + rem;
}
}
if (height > cav_h) {
* y_ret = y;
}
else {
int rem = cav_h - height;
switch (anchor) {
case TK_ANCHOR_NW: case TK_ANCHOR_N: case TK_ANCHOR_NE:
* y_ret = y;
break;
case TK_ANCHOR_W: case TK_ANCHOR_CENTER: case TK_ANCHOR_E:
* y_ret = y + rem/2;
if ((rem % 2) == 1) {
/* Usually it looks better if we shift down one pixel
* if the hight of the region is an odd number of pixels
*/
* y_ret += 1;
}
break;
default:
* y_ret = y + rem;
}
}
}
int
Tix_DItemFillNormalBG(drawable, subRegPtr, iPtr, x, y, width, height,
xOffset, yOffset, flags)
Drawable drawable; /* Where to display this item */
TixpSubRegion *subRegPtr;
Tix_DItem * iPtr; /* Item to display */
int x; /* x pos of top-left corner of region
* to display item in */
int y; /* y pos of top-left corner of region */
int width; /* width of region */
int height; /* height of region */
int xOffset; /* X offset of item within region */
int yOffset; /* Y offset of item within region */
int flags; /* Controls how fg/bg/anchor lines are
* drawn */
{
GC gc;
if ((flags & TIX_DITEM_NORMAL_BG) == 0) {
return 0;
}
if (width == iPtr->base.size[0] && height == iPtr->base.size[1] &&
xOffset == 0 && yOffset == 0 &&
(flags & TIX_DITEM_OTHER_BG) != 0) {
/*
* The background area will be filled by another bg color, so
* there's no need to fill it with NORMAL_BG here.
*/
return 0;
}
gc = iPtr->base.stylePtr->colors[TIX_DITEM_NORMAL].backGC;
if (gc != None) {
TixpSubRegFillRectangle(iPtr->base.ddPtr->display, drawable,
gc, subRegPtr, x, y, width, height);
return 1;
}
return 0;
}
/*
*----------------------------------------------------------------------
*
* Tix_DItemDrawBackground --
*
* Display the background color of the item. The background and
* foreground of the item are displayed according to the flags
* parameter:
*
* If TIX_DITEM_NORMAL_BG is specified in flags, the entire {x, y,
* width, height} region is filled with the NORMAL_BG.
*
* If one of the following is specified, a filled highlight rect
* is drawn around the selectable area of the item.
*
* TIX_DITEM_ACTIVE_BG
* TIX_DITEM_SELECTED_BG
* TIX_DITEM_DISABLED_BG
*
* In addition, if TIX_DITEM_ANCHOR is specified in flags, an
* anchor rectangle is drawn around the selectable area of the
* item.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
Tix_DItemDrawBackground(drawable, subRegPtr, iPtr, x, y, width, height,
xOffset, yOffset, flags)
Drawable drawable; /* Where to display this item */
TixpSubRegion *subRegPtr;
Tix_DItem * iPtr; /* Item to display */
int x; /* x pos of top-left corner of region
* to display item in */
int y; /* y pos of top-left corner of region */
int width; /* width of region */
int height; /* height of region */
int xOffset; /* X offset of item within region */
int yOffset; /* Y offset of item within region */
int flags; /* Controls how fg/bg/anchor lines are
* drawn */
{
Display * display = iPtr->base.ddPtr->display;
GC backGC, anchorGC;
int bodyX, bodyY, bodyW, bodyH;
TixGetColorDItemGC(iPtr, &backGC, NULL, &anchorGC, flags);
/*
* Fill the entire region with the normal background color first
* (if necessary).
*/
Tix_DItemFillNormalBG(drawable, subRegPtr, iPtr, x, y, width, height,
xOffset, yOffset, flags);
/*
* Calculate the location of the item body.
*/
TixDItemGetAnchor(iPtr->base.stylePtr->anchor, x, y, width, height,
iPtr->base.size[0], iPtr->base.size[1], &x, &y);
x += xOffset;
y += yOffset;
bodyX = x + iPtr->base.selX;
bodyY = y + iPtr->base.selY;
bodyW = iPtr->base.selW;
bodyH = iPtr->base.selH;
/*
* Fill the selected background and draw anchor lines only around
* the item body itself
*/
if ((flags & TIX_DITEM_OTHER_BG) && (backGC != None)) {
TixpSubRegSetClip(display, subRegPtr, backGC);
TixpSubRegFillRectangle(display, drawable, backGC,
subRegPtr, bodyX, bodyY, bodyW, bodyH);
TixpSubRegUnsetClip(display, subRegPtr, backGC);
}
if (anchorGC != None) {
TixpSubRegSetClip(display, subRegPtr, anchorGC);
TixpSubRegDrawAnchorLines(display, drawable,
anchorGC, subRegPtr, bodyX, bodyY, bodyW, bodyH);
TixpSubRegUnsetClip(display, subRegPtr, anchorGC);
}
}

69
generic/tixDef.h Normal file
View File

@@ -0,0 +1,69 @@
/*
* tixDef.h --
*
* This file defines the defaults for all options for all of
* the Tix widgets.
*
* Copyright (c) 1993-1999 Ioi Kim Lam.
* Copyright (c) 2000 Tix Project Group.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tixDef.h,v 1.6 2004/03/28 02:44:56 hobbs Exp $
*/
#ifndef TIX_DEFAULT
#define TIX_DEFAULT
/*
* The definitions below provide symbolic names for the default colors.
* NORMAL_BG - Normal background color.
* ACTIVE_BG - Background color when widget is active.
* SELECT_BG - Background color for selected text.
* TROUGH - Background color for troughs in scales and scrollbars.
* INDICATOR - Color for indicator when button is selected.
* DISABLED - Foreground color when widget is disabled.
*/
#define BLACK "Black"
#define WHITE "White"
#if defined(__WIN32__) || defined(_WIN32)
/*
* Defaults from Tk
*/
#define CTL_FONT "{MS Sans Serif} 8"
#define NORMAL_BG "SystemButtonFace"
#define NORMAL_FG "SystemButtonText"
#define ACTIVE_BG NORMAL_BG
#define TEXT_FG "SystemWindowText"
#define SELECT_BG "SystemHighlight"
#define SELECT_FG "SystemHighlightText"
#define TROUGH "SystemScrollbar"
#define INDICATOR "SystemWindow"
#define DISABLED "SystemDisabledText"
#define MENU_BG "SystemMenu"
#define MENU_FG "SystemMenuText"
#define HIGHLIGHT "SystemWindowFrame"
# include <tixWinDefault.h>
#else
# if defined(MAC_TCL)
# include <tixMacDefault.h>
# else
#define NORMAL_BG "#d9d9d9"
#define ACTIVE_BG "#ececec"
#define SELECT_BG "#c3c3c3"
#define TROUGH "#c3c3c3"
#define INDICATOR "#b03060"
#define DISABLED "#a3a3a3"
# include <tixUnixDefault.h>
# endif
#endif
#endif /* TIX_DEFAULT */

839
generic/tixDiITxt.c Normal file
View File

@@ -0,0 +1,839 @@
/*
* tixDiITxt.c --
*
* This file implements one of the "Display Items" in the Tix library :
* Image-text display items.
*
* Copyright (c) 1993-1999 Ioi Kim Lam.
* Copyright (c) 2000-2001 Tix Project Group.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tixDiITxt.c,v 1.6 2004/03/28 02:44:56 hobbs Exp $
*/
#include <tixPort.h>
#include <tk.h>
#include <tixInt.h>
#include <tixDef.h>
#define DEF_IMAGETEXTITEM_BITMAP ""
#define DEF_IMAGETEXTITEM_IMAGE ""
#define DEF_IMAGETEXTITEM_TYPE "imagetext"
#define DEF_IMAGETEXTITEM_SHOWIMAGE "1"
#define DEF_IMAGETEXTITEM_SHOWTEXT "1"
#define DEF_IMAGETEXTITEM_STYLE ""
#define DEF_IMAGETEXTITEM_TEXT ""
#define DEF_IMAGETEXTITEM_UNDERLINE "-1"
static Tk_ConfigSpec imageTextItemConfigSpecs[] = {
{TK_CONFIG_BITMAP, "-bitmap", "bitmap", "Bitmap",
DEF_IMAGETEXTITEM_BITMAP, Tk_Offset(TixImageTextItem, bitmap),
TK_CONFIG_NULL_OK},
{TK_CONFIG_STRING, "-image", "image", "Image",
DEF_IMAGETEXTITEM_IMAGE, Tk_Offset(TixImageTextItem, imageString),
TK_CONFIG_NULL_OK},
{TK_CONFIG_CUSTOM, "-itemtype", "itemType", "ItemType",
DEF_IMAGETEXTITEM_TYPE, Tk_Offset(TixImageTextItem, diTypePtr),
0, &tixConfigItemType},
{TK_CONFIG_INT, "-showimage", "showImage", "ShowImage",
DEF_IMAGETEXTITEM_SHOWIMAGE, Tk_Offset(TixImageTextItem, showImage), 0},
{TK_CONFIG_INT, "-showtext", "showText", "ShowText",
DEF_IMAGETEXTITEM_SHOWTEXT, Tk_Offset(TixImageTextItem, showText), 0},
{TK_CONFIG_CUSTOM, "-style", "imageTextStyle", "ImageTextStyle",
DEF_IMAGETEXTITEM_STYLE, Tk_Offset(TixImageTextItem, stylePtr),
TK_CONFIG_NULL_OK, &tixConfigItemStyle},
{TK_CONFIG_STRING, "-text", "text", "Text",
DEF_IMAGETEXTITEM_TEXT, Tk_Offset(TixImageTextItem, text),
TK_CONFIG_NULL_OK},
{TK_CONFIG_INT, "-underline", "underline", "Underline",
DEF_IMAGETEXTITEM_UNDERLINE, Tk_Offset(TixImageTextItem, underline), 0},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, 0}
};
/*----------------------------------------------------------------------
*
* Configuration options for Text Styles
*
*----------------------------------------------------------------------
*/
#define DEF_IMAGETEXTSTYLE_NORMAL_FG_COLOR NORMAL_FG
#define DEF_IMAGETEXTSTYLE_NORMAL_FG_MONO BLACK
#define DEF_IMAGETEXTSTYLE_NORMAL_BG_COLOR TIX_EDITOR_BG
#define DEF_IMAGETEXTSTYLE_NORMAL_BG_MONO WHITE
#define DEF_IMAGETEXTSTYLE_ACTIVE_FG_COLOR NORMAL_FG
#define DEF_IMAGETEXTSTYLE_ACTIVE_FG_MONO WHITE
#define DEF_IMAGETEXTSTYLE_ACTIVE_BG_COLOR TIX_EDITOR_BG
#define DEF_IMAGETEXTSTYLE_ACTIVE_BG_MONO BLACK
#define DEF_IMAGETEXTSTYLE_SELECTED_FG_COLOR SELECT_FG
#define DEF_IMAGETEXTSTYLE_SELECTED_FG_MONO WHITE
#define DEF_IMAGETEXTSTYLE_SELECTED_BG_COLOR SELECT_BG
#define DEF_IMAGETEXTSTYLE_SELECTED_BG_MONO BLACK
#define DEF_IMAGETEXTSTYLE_DISABLED_FG_COLOR BLACK
#define DEF_IMAGETEXTSTYLE_DISABLED_FG_MONO BLACK
#define DEF_IMAGETEXTSTYLE_DISABLED_BG_COLOR TIX_EDITOR_BG
#define DEF_IMAGETEXTSTYLE_DISABLED_BG_MONO WHITE
#define DEF_IMAGETEXTSTYLE_FONT CTL_FONT
#define DEF_IMAGETEXTSTYLE_GAP "4"
#define DEF_IMAGETEXTSTYLE_PADX "2"
#define DEF_IMAGETEXTSTYLE_PADY "2"
#define DEF_IMAGETEXTSTYLE_JUSTIFY "left"
#define DEF_IMAGETEXTSTYLE_WLENGTH "0"
#define DEF_IMAGETEXTSTYLE_ANCHOR "w"
static Tk_ConfigSpec imageTextStyleConfigSpecs[] = {
{TK_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor",
DEF_IMAGETEXTSTYLE_ANCHOR, Tk_Offset(TixImageTextStyle, anchor), 0},
{TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
(char *) NULL, 0, 0},
{TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL,
(char *) NULL, 0, 0},
{TK_CONFIG_FONT, "-font", "font", "Font",
DEF_IMAGETEXTSTYLE_FONT, Tk_Offset(TixImageTextStyle, font), 0},
{TK_CONFIG_PIXELS, "-gap", "gap", "Gap",
DEF_IMAGETEXTSTYLE_GAP, Tk_Offset(TixImageTextStyle, gap), 0},
{TK_CONFIG_JUSTIFY, "-justify", "justify", "Justyfy",
DEF_IMAGETEXTSTYLE_JUSTIFY, Tk_Offset(TixImageTextStyle, justify),
TK_CONFIG_NULL_OK},
{TK_CONFIG_PIXELS, "-padx", "padX", "Pad",
DEF_IMAGETEXTSTYLE_PADX, Tk_Offset(TixImageTextStyle, pad[0]), 0},
{TK_CONFIG_PIXELS, "-pady", "padY", "Pad",
DEF_IMAGETEXTSTYLE_PADY, Tk_Offset(TixImageTextStyle, pad[1]), 0},
{TK_CONFIG_PIXELS, "-wraplength", "wrapLength", "WrapLength",
DEF_IMAGETEXTSTYLE_WLENGTH, Tk_Offset(TixImageTextStyle, wrapLength),
0},
/* The following is automatically generated */
{TK_CONFIG_COLOR,"-background","background","Background",
DEF_IMAGETEXTSTYLE_NORMAL_BG_COLOR,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_NORMAL].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-background","background","Background",
DEF_IMAGETEXTSTYLE_NORMAL_BG_MONO,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_NORMAL].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-foreground","foreground","Foreground",
DEF_IMAGETEXTSTYLE_NORMAL_FG_COLOR,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_NORMAL].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-foreground","foreground","Foreground",
DEF_IMAGETEXTSTYLE_NORMAL_FG_MONO,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_NORMAL].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-activebackground","activeBackground","ActiveBackground",
DEF_IMAGETEXTSTYLE_ACTIVE_BG_COLOR,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_ACTIVE].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-activebackground","activeBackground","ActiveBackground",
DEF_IMAGETEXTSTYLE_ACTIVE_BG_MONO,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_ACTIVE].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-activeforeground","activeForeground","ActiveForeground",
DEF_IMAGETEXTSTYLE_ACTIVE_FG_COLOR,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_ACTIVE].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-activeforeground","activeForeground","ActiveForeground",
DEF_IMAGETEXTSTYLE_ACTIVE_FG_MONO,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_ACTIVE].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-selectbackground","selectBackground","SelectBackground",
DEF_IMAGETEXTSTYLE_SELECTED_BG_COLOR,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_SELECTED].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-selectbackground","selectBackground","SelectBackground",
DEF_IMAGETEXTSTYLE_SELECTED_BG_MONO,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_SELECTED].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-selectforeground","selectForeground","SelectForeground",
DEF_IMAGETEXTSTYLE_SELECTED_FG_COLOR,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_SELECTED].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-selectforeground","selectForeground","SelectForeground",
DEF_IMAGETEXTSTYLE_SELECTED_FG_MONO,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_SELECTED].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-disabledbackground","disabledBackground","DisabledBackground",
DEF_IMAGETEXTSTYLE_DISABLED_BG_COLOR,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_DISABLED].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-disabledbackground","disabledBackground","DisabledBackground",
DEF_IMAGETEXTSTYLE_DISABLED_BG_MONO,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_DISABLED].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-disabledforeground","disabledForeground","DisabledForeground",
DEF_IMAGETEXTSTYLE_DISABLED_FG_COLOR,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_DISABLED].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-disabledforeground","disabledForeground","DisabledForeground",
DEF_IMAGETEXTSTYLE_DISABLED_FG_MONO,
Tk_Offset(TixImageTextStyle,colors[TIX_DITEM_DISABLED].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, 0}
};
/*----------------------------------------------------------------------
* Forward declarations for procedures defined later in this file:
*----------------------------------------------------------------------
*/
static void ImageProc _ANSI_ARGS_((ClientData clientData,
int x, int y, int width, int height,
int imgWidth, int imgHeight));
static void Tix_ImageTextItemCalculateSize _ANSI_ARGS_((
Tix_DItem * iPtr));
static char * Tix_ImageTextItemComponent _ANSI_ARGS_((
Tix_DItem * iPtr, int x, int y));
static int Tix_ImageTextItemConfigure _ANSI_ARGS_((
Tix_DItem * iPtr, int argc, CONST84 char ** argv,
int flags));
static Tix_DItem * Tix_ImageTextItemCreate _ANSI_ARGS_((
Tix_DispData * ddPtr, Tix_DItemInfo * diTypePtr));
static void Tix_ImageTextItemDisplay _ANSI_ARGS_((
Drawable drawable, Tix_DItem * iPtr,
int x, int y, int width, int height,
int xOffset, int yOffset, int flag));
static void Tix_ImageTextItemFree _ANSI_ARGS_((
Tix_DItem * iPtr));
static void Tix_ImageTextItemLostStyle _ANSI_ARGS_((
Tix_DItem * iPtr));
static void Tix_ImageTextItemStyleChanged _ANSI_ARGS_((
Tix_DItem * iPtr));
static int Tix_ImageTextStyleConfigure _ANSI_ARGS_((
Tix_DItemStyle* style, int argc, CONST84 char ** argv,
int flags));
static Tix_DItemStyle * Tix_ImageTextStyleCreate _ANSI_ARGS_((
Tcl_Interp *interp, Tk_Window tkwin,
Tix_DItemInfo * diTypePtr, char * name));
static void Tix_ImageTextStyleFree _ANSI_ARGS_((
Tix_DItemStyle* style));
static void Tix_ImageTextStyleSetTemplate _ANSI_ARGS_((
Tix_DItemStyle* style,
Tix_StyleTemplate * tmplPtr));
Tix_DItemInfo tix_ImageTextItemType = {
"imagetext", /* type */
TIX_DITEM_IMAGETEXT,
Tix_ImageTextItemCreate, /* createProc */
Tix_ImageTextItemConfigure,
Tix_ImageTextItemCalculateSize,
Tix_ImageTextItemComponent,
Tix_ImageTextItemDisplay,
Tix_ImageTextItemFree,
Tix_ImageTextItemStyleChanged,
Tix_ImageTextItemLostStyle,
Tix_ImageTextStyleCreate,
Tix_ImageTextStyleConfigure,
Tix_ImageTextStyleFree,
Tix_ImageTextStyleSetTemplate,
imageTextItemConfigSpecs,
imageTextStyleConfigSpecs,
NULL, /*next */
};
/*----------------------------------------------------------------------
* Tix_ImageText --
*
*
*----------------------------------------------------------------------
*/
static Tix_DItem * Tix_ImageTextItemCreate(ddPtr, diTypePtr)
Tix_DispData * ddPtr;
Tix_DItemInfo * diTypePtr;
{
TixImageTextItem * itPtr;
itPtr = (TixImageTextItem*) ckalloc(sizeof(TixImageTextItem));
itPtr->diTypePtr = diTypePtr;
itPtr->ddPtr = ddPtr;
itPtr->stylePtr = NULL;
itPtr->clientData = 0;
itPtr->size[0] = 0;
itPtr->size[1] = 0;
itPtr->bitmap = None;
itPtr->bitmapW = 0;
itPtr->bitmapH = 0;
itPtr->imageString = NULL;
itPtr->image = NULL;
itPtr->imageW = 0;
itPtr->imageH = 0;
itPtr->numChars = 0; /* TODO: this is currently not used */
itPtr->text = NULL;
itPtr->textW = 0;
itPtr->textH = 0;
itPtr->underline = -1;
itPtr->showImage = 1;
itPtr->showText = 1;
return (Tix_DItem *)itPtr;
}
static void Tix_ImageTextItemFree(iPtr)
Tix_DItem * iPtr;
{
TixImageTextItem * itPtr = (TixImageTextItem *) iPtr;
if (itPtr->image) {
Tk_FreeImage(itPtr->image);
}
if (itPtr->stylePtr) {
TixDItemStyleFree(iPtr, (Tix_DItemStyle*)itPtr->stylePtr);
}
Tk_FreeOptions(imageTextItemConfigSpecs, (char *)itPtr,
itPtr->ddPtr->display, 0);
ckfree((char*)itPtr);
}
static int Tix_ImageTextItemConfigure(iPtr, argc, argv, flags)
Tix_DItem * iPtr;
int argc;
CONST84 char ** argv;
int flags;
{
TixImageTextItem * itPtr = (TixImageTextItem *) iPtr;
TixImageTextStyle * oldStyle = itPtr->stylePtr;
if (Tk_ConfigureWidget(itPtr->ddPtr->interp, itPtr->ddPtr->tkwin,
imageTextItemConfigSpecs,
argc, argv, (char *)itPtr, flags) != TCL_OK) {
return TCL_ERROR;
}
if (itPtr->stylePtr == NULL) {
itPtr->stylePtr = (TixImageTextStyle*)TixGetDefaultDItemStyle(
itPtr->ddPtr, &tix_ImageTextItemType, iPtr, NULL);
}
/*
* Free the old images for the widget, if there were any.
*/
if (itPtr->image != NULL) {
Tk_FreeImage(itPtr->image);
itPtr->image = NULL;
}
if (itPtr->imageString != NULL) {
itPtr->image = Tk_GetImage(itPtr->ddPtr->interp, itPtr->ddPtr->tkwin,
itPtr->imageString, ImageProc, (ClientData) itPtr);
if (itPtr->image == NULL) {
return TCL_ERROR;
}
}
if (oldStyle != NULL && itPtr->stylePtr != oldStyle) {
Tix_ImageTextItemStyleChanged(iPtr);
}
else {
Tix_ImageTextItemCalculateSize((Tix_DItem*)itPtr);
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* Tix_ImageTextItemDisplay --
*
* Display an imagetext item. {x, y, width, height} specifies a
* region for to display this item in. {xOffset, yOffset} gives
* the offset of the top-left corner of the text item relative
* to the top-left corder of the region.
*
* Background and foreground of the item are displayed according
* to the flags parameter.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static void
Tix_ImageTextItemDisplay(drawable, iPtr, x, y, width, height,
xOffset, yOffset, flags)
Drawable drawable; /* Where to display this item */
Tix_DItem * iPtr; /* Item to display */
int x; /* x pos of top-left corner of region
* to display item in */
int y; /* y pos of top-left corner of region */
int width; /* width of region */
int height; /* height of region */
int xOffset; /* X offset of item within region */
int yOffset; /* Y offset of item within region */
int flags; /* Controls how fg/bg/anchor lines are
* drawn */
{
TixImageTextItem *itPtr = (TixImageTextItem *)iPtr;
GC foreGC, bitmapGC;
TixpSubRegion subReg;
Display * display = itPtr->ddPtr->display;
if ((width <= 0) || (height <= 0)) {
return;
}
TixGetColorDItemGC(iPtr, NULL, &foreGC, NULL, flags);
TixpStartSubRegionDraw(display, drawable, foreGC,
&subReg, 0, 0, x, y, width, height,
itPtr->size[0] + xOffset, itPtr->size[1] + yOffset);
Tix_DItemDrawBackground(drawable, &subReg, iPtr, x, y, width, height,
xOffset, yOffset, flags);
/*
* Calculate the location of the item body according to anchor settings.
*/
TixDItemGetAnchor(iPtr->base.stylePtr->anchor, x, y, width, height,
iPtr->base.size[0], iPtr->base.size[1], &x, &y);
x += xOffset;
y += yOffset;
/*
* Draw the foreground items
*/
if (itPtr->image != NULL) {
int bitY;
bitY = itPtr->size[1] - itPtr->imageH - 2*itPtr->stylePtr->pad[1];
if (bitY > 0) {
bitY = bitY / 2 + (bitY %2);
} else {
bitY = 0;
}
if (itPtr->showImage && foreGC != None) {
TixpSubRegDrawImage(&subReg, itPtr->image, 0, 0,
itPtr->imageW, itPtr->imageH, drawable,
x + itPtr->stylePtr->pad[0],
y + itPtr->stylePtr->pad[1] + bitY);
}
x += itPtr->imageW + itPtr->stylePtr->gap;
}
else if (itPtr->bitmap != None) {
int bitY;
bitY = itPtr->size[1] - itPtr->bitmapH - 2*itPtr->stylePtr->pad[1];
if (bitY > 0) {
bitY = bitY / 2 + (bitY %2);
} else {
bitY = 0;
}
if (itPtr->showImage && foreGC != None) {
if ((flags & TIX_DITEM_ALL_BG) != 0) {
/*
* If we draw the background, the bitmap is never
* displayed as selected, so we choose the normal GC.
*/
bitmapGC = itPtr->stylePtr->colors[TIX_DITEM_NORMAL].foreGC;
} else {
/*
* The caller has already drawn the background. foreGC
* is the most compatible GC to be used with the background.
*/
bitmapGC = foreGC;
}
TixpSubRegDrawBitmap(display, drawable, bitmapGC,
&subReg, itPtr->bitmap, 0, 0,
itPtr->bitmapW, itPtr->bitmapH,
x + itPtr->stylePtr->pad[0],
y + itPtr->stylePtr->pad[1] + bitY,
1);
}
x += itPtr->bitmapW + itPtr->stylePtr->gap;
}
if (itPtr->text && itPtr->showText && foreGC != None) {
int textY;
textY = itPtr->size[1] - itPtr->textH - 2*itPtr->stylePtr->pad[1];
if (textY > 0) {
textY = textY / 2 + (textY %2);
} else {
textY = 0;
}
TixpSubRegDisplayText(display, drawable, foreGC, &subReg,
itPtr->stylePtr->font, itPtr->text, -1,
x + itPtr->stylePtr->pad[0],
y + itPtr->stylePtr->pad[1] + textY,
itPtr->textW,
itPtr->stylePtr->justify,
itPtr->underline);
}
TixpEndSubRegionDraw(display, drawable, foreGC,
&subReg);
}
static void
Tix_ImageTextItemCalculateSize(iPtr)
Tix_DItem * iPtr;
{
TixImageTextItem *itPtr = (TixImageTextItem *)iPtr;
char * text;
itPtr->size[0] = 0;
itPtr->size[1] = 0;
/*
* Note: the size of the image or the text are used even when
* the showImage or showText options are off. These two options are
* used to "blank" the respective components temporarily without
* affecting the geometry of the ditem. The main is to indicate
* transfer during drag+drop.
*
* If you want the image or text to completely disappear, config them
* to NULL
*/
if (itPtr->image != NULL) {
Tk_SizeOfImage(itPtr->image, &itPtr->imageW, &itPtr->imageH);
itPtr->size[0] = itPtr->imageW + itPtr->stylePtr->gap;
itPtr->size[1] = itPtr->imageH;
}
else if (itPtr->bitmap != None) {
Tk_SizeOfBitmap(itPtr->ddPtr->display, itPtr->bitmap, &itPtr->bitmapW,
&itPtr->bitmapH);
itPtr->size[0] = itPtr->bitmapW + itPtr->stylePtr->gap;
itPtr->size[1] = itPtr->bitmapH;
}
text = itPtr->text;
if (text == NULL || text[0] == '\0') {
/*
* Use one space character so that the height of the item
* would be the same as a regular small item, and the width
* of the item won't be too tiny.
*/
text = " ";
}
TixComputeTextGeometry(itPtr->stylePtr->font, text,
-1, itPtr->stylePtr->wrapLength,
&itPtr->textW, &itPtr->textH);
itPtr->size[0] += itPtr->textW;
if (itPtr->textH > itPtr->size[1]) {
itPtr->size[1] = itPtr->textH;
}
itPtr->size[0] += 2*itPtr->stylePtr->pad[0];
itPtr->size[1] += 2*itPtr->stylePtr->pad[1];
itPtr->selX = 0;
itPtr->selY = 0;
itPtr->selW = itPtr->size[0];
itPtr->selH = itPtr->size[1];
if (itPtr->image != NULL) {
itPtr->selX = itPtr->imageW + itPtr->stylePtr->gap;
itPtr->selW -= itPtr->selX;
} else if (itPtr->bitmap != None) {
itPtr->selX = itPtr->bitmapW + itPtr->stylePtr->gap;
itPtr->selW -= itPtr->selX;
}
}
static char * Tix_ImageTextItemComponent(iPtr, x, y)
Tix_DItem * iPtr;
int x;
int y;
{
/* TODO: Unimplemented */
#if 0
TixImageTextItem *itPtr = (TixImageTextItem *)iPtr;
#endif
static char * body = "body";
return body;
}
static void Tix_ImageTextItemStyleChanged(iPtr)
Tix_DItem * iPtr;
{
TixImageTextItem *itPtr = (TixImageTextItem *)iPtr;
if (itPtr->stylePtr == NULL) {
/* Maybe we haven't set the style to default style yet */
return;
}
Tix_ImageTextItemCalculateSize(iPtr);
if (itPtr->ddPtr->sizeChangedProc != NULL) {
itPtr->ddPtr->sizeChangedProc(iPtr);
}
}
static void Tix_ImageTextItemLostStyle(iPtr)
Tix_DItem * iPtr;
{
TixImageTextItem *itPtr = (TixImageTextItem *)iPtr;
itPtr->stylePtr = (TixImageTextStyle*)TixGetDefaultDItemStyle(
itPtr->ddPtr, &tix_ImageTextItemType, iPtr, NULL);
Tix_ImageTextItemStyleChanged(iPtr);
}
/*
*----------------------------------------------------------------------
*
* ImageProc --
*
* This procedure is invoked by the image code whenever the manager
* for an image does something that affects the size of contents
* of an image displayed in this widget.
*
* Results:
* None.
*
* Side effects:
* Arranges for the HList to get redisplayed.
*
*----------------------------------------------------------------------
*/
static void
ImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
ClientData clientData; /* Pointer to widget record. */
int x, y; /* Upper left pixel (within image)
* that must be redisplayed. */
int width, height; /* Dimensions of area to redisplay
* (may be <= 0). */
int imgWidth, imgHeight; /* New dimensions of image. */
{
TixImageTextItem *itPtr = (TixImageTextItem *)clientData;
Tix_ImageTextItemCalculateSize((Tix_DItem *)itPtr);
if (itPtr->ddPtr->sizeChangedProc != NULL) {
itPtr->ddPtr->sizeChangedProc((Tix_DItem *)itPtr);
}
}
/*----------------------------------------------------------------------
*
*
* Display styles
*
*
*----------------------------------------------------------------------
*/
static Tix_DItemStyle *
Tix_ImageTextStyleCreate(interp, tkwin, diTypePtr, name)
Tcl_Interp * interp;
Tk_Window tkwin;
char * name;
Tix_DItemInfo * diTypePtr;
{
TixImageTextStyle * stylePtr =
(TixImageTextStyle *)ckalloc(sizeof(TixImageTextStyle));
stylePtr->font = NULL;
stylePtr->gap = 0;
stylePtr->justify = TK_JUSTIFY_LEFT;
stylePtr->wrapLength = 0;
return (Tix_DItemStyle *)stylePtr;
}
static int
Tix_ImageTextStyleConfigure(style, argc, argv, flags)
Tix_DItemStyle *style;
int argc;
CONST84 char ** argv;
int flags;
{
TixImageTextStyle * stylePtr = (TixImageTextStyle *)style;
XGCValues gcValues;
GC newGC;
int i, isNew;
if (stylePtr->font == NULL) {
isNew = 1;
} else {
isNew = 0;
}
/*
* TODO: gap, wrapLength, etc changes: need to call TixDItemStyleChanged
*/
if (!(flags &TIX_DONT_CALL_CONFIG)) {
if (Tk_ConfigureWidget(stylePtr->interp, stylePtr->tkwin,
imageTextStyleConfigSpecs,
argc, argv, (char *)stylePtr, flags) != TCL_OK) {
return TCL_ERROR;
}
}
gcValues.font = TixFontId(stylePtr->font);
gcValues.graphics_exposures = False;
for (i=0; i<4; i++) {
/*
* Foreground GC
*/
gcValues.background = stylePtr->colors[i].bg->pixel;
gcValues.foreground = stylePtr->colors[i].fg->pixel;
newGC = Tk_GetGC(stylePtr->tkwin,
GCFont|GCForeground|GCBackground|GCGraphicsExposures, &gcValues);
if (stylePtr->colors[i].foreGC != None) {
Tk_FreeGC(Tk_Display(stylePtr->tkwin),
stylePtr->colors[i].foreGC);
}
stylePtr->colors[i].foreGC = newGC;
/*
* Background GC
*/
gcValues.foreground = stylePtr->colors[i].bg->pixel;
newGC = Tk_GetGC(stylePtr->tkwin,
GCFont|GCForeground|GCGraphicsExposures, &gcValues);
if (stylePtr->colors[i].backGC != None) {
Tk_FreeGC(Tk_Display(stylePtr->tkwin),
stylePtr->colors[i].backGC);
}
stylePtr->colors[i].backGC = newGC;
/*
* Anchor GC
*/
newGC = Tix_GetAnchorGC(stylePtr->tkwin,
stylePtr->colors[i].bg);
if (stylePtr->colors[i].anchorGC != None) {
Tk_FreeGC(Tk_Display(stylePtr->tkwin),
stylePtr->colors[i].anchorGC);
}
stylePtr->colors[i].anchorGC = newGC;
}
if (!isNew) {
TixDItemStyleChanged(stylePtr->diTypePtr, (Tix_DItemStyle *)stylePtr);
}
return TCL_OK;
}
static void Tix_ImageTextStyleFree(style)
Tix_DItemStyle *style;
{
TixImageTextStyle * stylePtr = (TixImageTextStyle *)style;
Tk_FreeOptions(imageTextStyleConfigSpecs, (char *)stylePtr,
Tk_Display(stylePtr->tkwin), 0);
ckfree((char *)stylePtr);
}
static int bg_flags [4] = {
TIX_DITEM_NORMAL_BG,
TIX_DITEM_ACTIVE_BG,
TIX_DITEM_SELECTED_BG,
TIX_DITEM_DISABLED_BG
};
static int fg_flags [4] = {
TIX_DITEM_NORMAL_FG,
TIX_DITEM_ACTIVE_FG,
TIX_DITEM_SELECTED_FG,
TIX_DITEM_DISABLED_FG
};
static void
Tix_ImageTextStyleSetTemplate(style, tmplPtr)
Tix_DItemStyle* style;
Tix_StyleTemplate * tmplPtr;
{
TixImageTextStyle * stylePtr = (TixImageTextStyle *)style;
int i;
if (tmplPtr->flags & TIX_DITEM_FONT) {
if (stylePtr->font != NULL) {
TixFreeFont(stylePtr->font);
}
stylePtr->font = TixGetFont(
stylePtr->interp, stylePtr->tkwin,
TixNameOfFont(tmplPtr->font));
}
if (tmplPtr->flags & TIX_DITEM_PADX) {
stylePtr->pad[0] = tmplPtr->pad[0];
}
if (tmplPtr->flags & TIX_DITEM_PADY) {
stylePtr->pad[1] = tmplPtr->pad[1];
}
for (i=0; i<4; i++) {
if (tmplPtr->flags & bg_flags[i]) {
if (stylePtr->colors[i].bg != NULL) {
Tk_FreeColor(stylePtr->colors[i].bg);
}
stylePtr->colors[i].bg = Tk_GetColor(
stylePtr->interp, stylePtr->tkwin,
Tk_NameOfColor(tmplPtr->colors[i].bg));
}
}
for (i=0; i<4; i++) {
if (tmplPtr->flags & fg_flags[i]) {
if (stylePtr->colors[i].fg != NULL) {
Tk_FreeColor(stylePtr->colors[i].fg);
}
stylePtr->colors[i].fg = Tk_GetColor(
stylePtr->interp, stylePtr->tkwin,
Tk_NameOfColor(tmplPtr->colors[i].fg));
}
}
Tix_ImageTextStyleConfigure(style, 0, 0, TIX_DONT_CALL_CONFIG);
}

623
generic/tixDiImg.c Normal file
View File

@@ -0,0 +1,623 @@
/*
* tixDiImgTxt.c --
*
* This file implements one of the "Display Items" in the Tix library :
* Image-text display items.
*
* Copyright (c) 1993-1999 Ioi Kim Lam.
* Copyright (c) 2000-2001 Tix Project Group.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tixDiImg.c,v 1.4 2004/03/28 02:44:56 hobbs Exp $
*/
#include <tixPort.h>
#include <tixInt.h>
#include <tixDef.h>
/*
* If the item has a really small text, or no text at all, use
* this size. This makes the drawing of selection more sane.
*/
#define MIN_IMAGE_WIDTH 2
#define MIN_IMAGE_HEIGHT 2
#define DEF_IMAGEITEM_BITMAP ""
#define DEF_IMAGEITEM_IMAGE ""
#define DEF_IMAGEITEM_TYPE "image"
#define DEF_IMAGEITEM_SHOWIMAGE "1"
#define DEF_IMAGEITEM_SHOWTEXT "1"
#define DEF_IMAGEITEM_STYLE ""
#define DEF_IMAGEITEM_TEXT ""
#define DEF_IMAGEITEM_UNDERLINE "-1"
static Tk_ConfigSpec imageItemConfigSpecs[] = {
{TK_CONFIG_STRING, "-image", "image", "Image",
DEF_IMAGEITEM_IMAGE, Tk_Offset(TixImageItem, imageString),
TK_CONFIG_NULL_OK},
{TK_CONFIG_CUSTOM, "-itemtype", "itemType", "ItemType",
DEF_IMAGEITEM_TYPE, Tk_Offset(TixImageItem, diTypePtr),
0, &tixConfigItemType},
{TK_CONFIG_CUSTOM, "-style", "imageStyle", "ImageStyle",
DEF_IMAGEITEM_STYLE, Tk_Offset(TixImageItem, stylePtr),
TK_CONFIG_NULL_OK, &tixConfigItemStyle},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, 0}
};
/*----------------------------------------------------------------------
*
* Configuration options for Text Styles
*
*----------------------------------------------------------------------
*/
#define DEF_IMAGESTYLE_NORMAL_FG_COLOR NORMAL_FG
#define DEF_IMAGESTYLE_NORMAL_FG_MONO BLACK
#define DEF_IMAGESTYLE_NORMAL_BG_COLOR TIX_EDITOR_BG
#define DEF_IMAGESTYLE_NORMAL_BG_MONO WHITE
#define DEF_IMAGESTYLE_ACTIVE_FG_COLOR NORMAL_FG
#define DEF_IMAGESTYLE_ACTIVE_FG_MONO WHITE
#define DEF_IMAGESTYLE_ACTIVE_BG_COLOR TIX_EDITOR_BG
#define DEF_IMAGESTYLE_ACTIVE_BG_MONO BLACK
#define DEF_IMAGESTYLE_SELECTED_FG_COLOR SELECT_FG
#define DEF_IMAGESTYLE_SELECTED_FG_MONO WHITE
#define DEF_IMAGESTYLE_SELECTED_BG_COLOR SELECT_BG
#define DEF_IMAGESTYLE_SELECTED_BG_MONO BLACK
#define DEF_IMAGESTYLE_DISABLED_FG_COLOR NORMAL_FG
#define DEF_IMAGESTYLE_DISABLED_FG_MONO BLACK
#define DEF_IMAGESTYLE_DISABLED_BG_COLOR TIX_EDITOR_BG
#define DEF_IMAGESTYLE_DISABLED_BG_MONO WHITE
#define DEF_IMAGESTYLE_PADX "0"
#define DEF_IMAGESTYLE_PADY "0"
#define DEF_IMAGESTYLE_ANCHOR "w"
static Tk_ConfigSpec imageStyleConfigSpecs[] = {
{TK_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor",
DEF_IMAGESTYLE_ANCHOR, Tk_Offset(TixImageStyle, anchor), 0},
{TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
(char *) NULL, 0, 0},
{TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL,
(char *) NULL, 0, 0},
{TK_CONFIG_PIXELS, "-padx", "padX", "Pad",
DEF_IMAGESTYLE_PADX, Tk_Offset(TixImageStyle, pad[0]), 0},
{TK_CONFIG_PIXELS, "-pady", "padY", "Pad",
DEF_IMAGESTYLE_PADY, Tk_Offset(TixImageStyle, pad[1]), 0},
/* The following was automatically generated */
{TK_CONFIG_COLOR,"-background","background","Background",
DEF_IMAGESTYLE_NORMAL_BG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_NORMAL].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-background","background","Background",
DEF_IMAGESTYLE_NORMAL_BG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_NORMAL].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-foreground","foreground","Foreground",
DEF_IMAGESTYLE_NORMAL_FG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_NORMAL].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-foreground","foreground","Foreground",
DEF_IMAGESTYLE_NORMAL_FG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_NORMAL].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-activebackground","activeBackground","ActiveBackground",
DEF_IMAGESTYLE_ACTIVE_BG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_ACTIVE].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-activebackground","activeBackground","ActiveBackground",
DEF_IMAGESTYLE_ACTIVE_BG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_ACTIVE].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-activeforeground","activeForeground","ActiveForeground",
DEF_IMAGESTYLE_ACTIVE_FG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_ACTIVE].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-activeforeground","activeForeground","ActiveForeground",
DEF_IMAGESTYLE_ACTIVE_FG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_ACTIVE].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-selectbackground","selectBackground","SelectBackground",
DEF_IMAGESTYLE_SELECTED_BG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_SELECTED].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-selectbackground","selectBackground","SelectBackground",
DEF_IMAGESTYLE_SELECTED_BG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_SELECTED].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-selectforeground","selectForeground","SelectForeground",
DEF_IMAGESTYLE_SELECTED_FG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_SELECTED].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-selectforeground","selectForeground","SelectForeground",
DEF_IMAGESTYLE_SELECTED_FG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_SELECTED].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-disabledbackground","disabledBackground","DisabledBackground",
DEF_IMAGESTYLE_DISABLED_BG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_DISABLED].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-disabledbackground","disabledBackground","DisabledBackground",
DEF_IMAGESTYLE_DISABLED_BG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_DISABLED].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-disabledforeground","disabledForeground","DisabledForeground",
DEF_IMAGESTYLE_DISABLED_FG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_DISABLED].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-disabledforeground","disabledForeground","DisabledForeground",
DEF_IMAGESTYLE_DISABLED_FG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_DISABLED].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, 0}
};
/*----------------------------------------------------------------------
* Forward declarations for procedures defined later in this file:
*----------------------------------------------------------------------
*/
static void ImageProc _ANSI_ARGS_((ClientData clientData,
int x, int y, int width, int height,
int imgWidth, int imgHeight));
static void Tix_ImageItemCalculateSize _ANSI_ARGS_((
Tix_DItem * iPtr));
static char * Tix_ImageItemComponent _ANSI_ARGS_((
Tix_DItem * iPtr, int x, int y));
static int Tix_ImageItemConfigure _ANSI_ARGS_((
Tix_DItem * iPtr, int argc, CONST84 char ** argv,
int flags));
static Tix_DItem * Tix_ImageItemCreate _ANSI_ARGS_((
Tix_DispData * ddPtr, Tix_DItemInfo * diTypePtr));
static void Tix_ImageItemDisplay _ANSI_ARGS_((
Drawable drawable, Tix_DItem * iPtr,
int x, int y, int width, int height,
int xOffset, int yOffset, int flag));
static void Tix_ImageItemFree _ANSI_ARGS_((
Tix_DItem * iPtr));
static void Tix_ImageItemLostStyle _ANSI_ARGS_((
Tix_DItem * iPtr));
static void Tix_ImageItemStyleChanged _ANSI_ARGS_((
Tix_DItem * iPtr));
static int Tix_ImageStyleConfigure _ANSI_ARGS_((
Tix_DItemStyle* style, int argc, CONST84 char ** argv,
int flags));
static Tix_DItemStyle * Tix_ImageStyleCreate _ANSI_ARGS_((
Tcl_Interp *interp, Tk_Window tkwin,
Tix_DItemInfo * diTypePtr, char * name));
static void Tix_ImageStyleFree _ANSI_ARGS_((
Tix_DItemStyle* style));
static void Tix_ImageStyleSetTemplate _ANSI_ARGS_((
Tix_DItemStyle* style,
Tix_StyleTemplate * tmplPtr));
Tix_DItemInfo tix_ImageItemType = {
"image", /* type */
TIX_DITEM_IMAGE,
Tix_ImageItemCreate, /* createProc */
Tix_ImageItemConfigure,
Tix_ImageItemCalculateSize,
Tix_ImageItemComponent,
Tix_ImageItemDisplay,
Tix_ImageItemFree,
Tix_ImageItemStyleChanged,
Tix_ImageItemLostStyle,
Tix_ImageStyleCreate, /* styleCreateProc */
Tix_ImageStyleConfigure,
Tix_ImageStyleFree,
Tix_ImageStyleSetTemplate,
imageItemConfigSpecs,
imageStyleConfigSpecs,
NULL, /*next */
};
/*----------------------------------------------------------------------
* Tix_Image --
*
*
*----------------------------------------------------------------------
*/
static Tix_DItem * Tix_ImageItemCreate(ddPtr, diTypePtr)
Tix_DispData * ddPtr;
Tix_DItemInfo * diTypePtr;
{
TixImageItem * itPtr;
itPtr = (TixImageItem*) ckalloc(sizeof(TixImageItem));
itPtr->diTypePtr = diTypePtr;
itPtr->ddPtr = ddPtr;
itPtr->stylePtr = NULL;
itPtr->clientData = 0;
itPtr->size[0] = 0;
itPtr->size[1] = 0;
itPtr->imageString = NULL;
itPtr->image = NULL;
itPtr->imageW = 0;
itPtr->imageH = 0;
return (Tix_DItem *)itPtr;
}
static void Tix_ImageItemFree(iPtr)
Tix_DItem * iPtr;
{
TixImageItem * itPtr = (TixImageItem *) iPtr;
if (itPtr->image) {
Tk_FreeImage(itPtr->image);
}
if (itPtr->stylePtr) {
TixDItemStyleFree(iPtr, (Tix_DItemStyle*)itPtr->stylePtr);
}
Tk_FreeOptions(imageItemConfigSpecs, (char *)itPtr,
itPtr->ddPtr->display, 0);
ckfree((char*)itPtr);
}
static int Tix_ImageItemConfigure(iPtr, argc, argv, flags)
Tix_DItem * iPtr;
int argc;
CONST84 char ** argv;
int flags;
{
TixImageItem * itPtr = (TixImageItem *) iPtr;
TixImageStyle * oldStyle = itPtr->stylePtr;
if (Tk_ConfigureWidget(itPtr->ddPtr->interp, itPtr->ddPtr->tkwin,
imageItemConfigSpecs,
argc, argv, (char *)itPtr, flags) != TCL_OK) {
return TCL_ERROR;
}
if (itPtr->stylePtr == NULL) {
itPtr->stylePtr = (TixImageStyle*)TixGetDefaultDItemStyle(
itPtr->ddPtr, &tix_ImageItemType, iPtr, NULL);
}
/*
* Free the old images for the widget, if there were any.
*/
if (itPtr->image != NULL) {
Tk_FreeImage(itPtr->image);
itPtr->image = NULL;
}
if (itPtr->imageString != NULL) {
itPtr->image = Tk_GetImage(itPtr->ddPtr->interp, itPtr->ddPtr->tkwin,
itPtr->imageString, ImageProc, (ClientData) itPtr);
if (itPtr->image == NULL) {
return TCL_ERROR;
}
}
if (oldStyle != NULL && itPtr->stylePtr != oldStyle) {
Tix_ImageItemStyleChanged(iPtr);
}
else {
Tix_ImageItemCalculateSize((Tix_DItem*)itPtr);
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* Tix_ImageItemDisplay --
*
* Display an image item. {x, y, width, height} specifies a
* region for to display this item in. {xOffset, yOffset} gives
* the offset of the top-left corner of the image item relative
* to the top-left corder of the region.
*
* Background and foreground of the item are displayed according
* to the flags parameter.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static void
Tix_ImageItemDisplay(drawable, iPtr, x, y, width, height, xOffset, yOffset,
flags)
Drawable drawable;
Tix_DItem * iPtr;
int x;
int y;
int width;
int height;
int flags;
{
TixImageItem *itPtr = (TixImageItem *)iPtr;
Display * display = itPtr->ddPtr->display;
TixpSubRegion subReg;
GC foreGC;
if ((width <= 0) || (height <= 0)) {
return;
}
TixGetColorDItemGC(iPtr, NULL, &foreGC, NULL, flags);
TixpStartSubRegionDraw(display, drawable, foreGC,
&subReg, 0, 0, x, y, width, height,
itPtr->size[0] + xOffset, itPtr->size[1] + yOffset);
Tix_DItemDrawBackground(drawable, &subReg, iPtr, x, y, width, height,
xOffset, yOffset, flags);
/*
* Calculate the location of the image according to anchor settings.
*/
TixDItemGetAnchor(iPtr->base.stylePtr->anchor, x, y, width, height,
iPtr->base.size[0], iPtr->base.size[1], &x, &y);
if (itPtr->image != NULL) {
/*
* Draw the image.
*/
int bitY;
bitY = itPtr->size[1] - itPtr->imageH - 2*itPtr->stylePtr->pad[1];
if (bitY > 0) {
bitY = bitY / 2;
} else {
bitY = 0;
}
x += xOffset;
y += yOffset;
TixpSubRegDrawImage(&subReg, itPtr->image, 0, 0, itPtr->imageW,
itPtr->imageH, drawable,
x + itPtr->stylePtr->pad[0],
y + itPtr->stylePtr->pad[1] + bitY);
}
TixpEndSubRegionDraw(display, drawable, foreGC,
&subReg);
}
static void
Tix_ImageItemCalculateSize(iPtr)
Tix_DItem * iPtr;
{
TixImageItem *itPtr = (TixImageItem *)iPtr;
itPtr->size[0] = 0;
itPtr->size[1] = 0;
if (itPtr->image != NULL) {
Tk_SizeOfImage(itPtr->image, &itPtr->imageW, &itPtr->imageH);
itPtr->size[0] = itPtr->imageW;
itPtr->size[1] = itPtr->imageH;
} else {
itPtr->size[0] = MIN_IMAGE_WIDTH;
itPtr->size[0] = MIN_IMAGE_HEIGHT;
}
itPtr->size[0] += 2*itPtr->stylePtr->pad[0];
itPtr->size[1] += 2*itPtr->stylePtr->pad[1];
itPtr->selX = 0;
itPtr->selY = 0;
itPtr->selW = itPtr->size[0];
itPtr->selH = itPtr->size[1];
}
static char * Tix_ImageItemComponent(iPtr, x, y)
Tix_DItem * iPtr;
int x;
int y;
{
#if 0
TixImageItem *itPtr = (TixImageItem *)iPtr;
#endif
static char * body = "body";
return body;
}
static void Tix_ImageItemStyleChanged(iPtr)
Tix_DItem * iPtr;
{
TixImageItem *itPtr = (TixImageItem *)iPtr;
if (itPtr->stylePtr == NULL) {
/* Maybe we haven't set the style to default style yet */
return;
}
Tix_ImageItemCalculateSize(iPtr);
if (itPtr->ddPtr->sizeChangedProc != NULL) {
itPtr->ddPtr->sizeChangedProc(iPtr);
}
}
static void Tix_ImageItemLostStyle(iPtr)
Tix_DItem * iPtr;
{
TixImageItem *itPtr = (TixImageItem *)iPtr;
itPtr->stylePtr = (TixImageStyle*)TixGetDefaultDItemStyle(
itPtr->ddPtr, &tix_ImageItemType, iPtr, NULL);
Tix_ImageItemStyleChanged(iPtr);
}
/*
*----------------------------------------------------------------------
*
* ImageProc --
*
* This procedure is invoked by the image code whenever the manager
* for an image does something that affects the size of contents
* of an image displayed in this widget.
*
* Results:
* None.
*
* Side effects:
* Arranges for the HList to get redisplayed.
*
*----------------------------------------------------------------------
*/
static void
ImageProc(clientData, x, y, width, height, imgWidth, imgHeight)
ClientData clientData; /* Pointer to widget record. */
int x, y; /* Upper left pixel (within image)
* that must be redisplayed. */
int width, height; /* Dimensions of area to redisplay
* (may be <= 0). */
int imgWidth, imgHeight; /* New dimensions of image. */
{
TixImageItem *itPtr = (TixImageItem *)clientData;
Tix_ImageItemCalculateSize((Tix_DItem *)itPtr);
if (itPtr->ddPtr->sizeChangedProc != NULL) {
itPtr->ddPtr->sizeChangedProc((Tix_DItem *)itPtr);
}
}
/*----------------------------------------------------------------------
*
*
* Display styles
*
*
*----------------------------------------------------------------------
*/
static Tix_DItemStyle *
Tix_ImageStyleCreate(interp, tkwin, diTypePtr, name)
Tcl_Interp * interp;
Tk_Window tkwin;
char * name;
Tix_DItemInfo * diTypePtr;
{
TixImageStyle * stylePtr =
(TixImageStyle *)ckalloc(sizeof(TixImageStyle));
return (Tix_DItemStyle *)stylePtr;
}
static int
Tix_ImageStyleConfigure(style, argc, argv, flags)
Tix_DItemStyle *style;
int argc;
CONST84 char ** argv;
int flags;
{
TixImageStyle * stylePtr = (TixImageStyle *)style;
int oldPadX;
int oldPadY;
oldPadX = stylePtr->pad[0];
oldPadY = stylePtr->pad[1];
if (!(flags &TIX_DONT_CALL_CONFIG)) {
if (Tk_ConfigureWidget(stylePtr->interp, stylePtr->tkwin,
imageStyleConfigSpecs,
argc, argv, (char *)stylePtr, flags) != TCL_OK) {
return TCL_ERROR;
}
}
TixDItemStyleConfigureGCs(style);
if (oldPadX != stylePtr->pad[0] || oldPadY != stylePtr->pad[1]) {
TixDItemStyleChanged(stylePtr->diTypePtr, (Tix_DItemStyle *)stylePtr);
}
return TCL_OK;
}
static void Tix_ImageStyleFree(style)
Tix_DItemStyle *style;
{
TixImageStyle * stylePtr = (TixImageStyle *)style;
Tk_FreeOptions(imageStyleConfigSpecs, (char *)stylePtr,
Tk_Display(stylePtr->tkwin), 0);
ckfree((char *)stylePtr);
}
static int bg_flags [4] = {
TIX_DITEM_NORMAL_BG,
TIX_DITEM_ACTIVE_BG,
TIX_DITEM_SELECTED_BG,
TIX_DITEM_DISABLED_BG
};
static int fg_flags [4] = {
TIX_DITEM_NORMAL_FG,
TIX_DITEM_ACTIVE_FG,
TIX_DITEM_SELECTED_FG,
TIX_DITEM_DISABLED_FG
};
static void
Tix_ImageStyleSetTemplate(style, tmplPtr)
Tix_DItemStyle* style;
Tix_StyleTemplate * tmplPtr;
{
TixImageStyle * stylePtr = (TixImageStyle *)style;
int i;
if (tmplPtr->flags & TIX_DITEM_PADX) {
stylePtr->pad[0] = tmplPtr->pad[0];
}
if (tmplPtr->flags & TIX_DITEM_PADY) {
stylePtr->pad[1] = tmplPtr->pad[1];
}
for (i=0; i<4; i++) {
if (tmplPtr->flags & bg_flags[i]) {
if (stylePtr->colors[i].bg != NULL) {
Tk_FreeColor(stylePtr->colors[i].bg);
}
stylePtr->colors[i].bg = Tk_GetColor(
stylePtr->interp, stylePtr->tkwin,
Tk_NameOfColor(tmplPtr->colors[i].bg));
}
}
for (i=0; i<4; i++) {
if (tmplPtr->flags & fg_flags[i]) {
if (stylePtr->colors[i].fg != NULL) {
Tk_FreeColor(stylePtr->colors[i].fg);
}
stylePtr->colors[i].fg = Tk_GetColor(
stylePtr->interp, stylePtr->tkwin,
Tk_NameOfColor(tmplPtr->colors[i].fg));
}
}
Tix_ImageStyleConfigure(style, 0, 0, TIX_DONT_CALL_CONFIG);
}

1070
generic/tixDiStyle.c Normal file

File diff suppressed because it is too large Load Diff

651
generic/tixDiText.c Normal file
View File

@@ -0,0 +1,651 @@
/*
* tixDiText.c --
*
* This file implements one of the "Display Items" in the Tix library :
* Text display items.
*
* Copyright (c) 1993-1999 Ioi Kim Lam.
* Copyright (c) 2000-2001 Tix Project Group.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tixDiText.c,v 1.7 2004/03/28 02:44:56 hobbs Exp $
*/
#include <tixPort.h>
#include <tixInt.h>
#include <tixDef.h>
/*
* If the item has a really small text, or no text at all, use
* this size. This makes the drawing of selection lines more sane.
*/
#define MIN_TEXT_WIDTH 2
#define MIN_TEXT_HEIGHT 2
/*----------------------------------------------------------------------
*
* Configuration options for Text Items
*
*----------------------------------------------------------------------
*/
static Tk_ConfigSpec textItemConfigSpecs[] = {
{TK_CONFIG_CUSTOM, "-itemtype", "itemType", "ItemType",
DEF_TEXTITEM_TYPE, Tk_Offset(TixTextItem, diTypePtr),
0, &tixConfigItemType},
{TK_CONFIG_CUSTOM, "-style", "textStyle", "TextStyle",
DEF_TEXTITEM_STYLE, Tk_Offset(TixTextItem, stylePtr),
TK_CONFIG_NULL_OK, &tixConfigItemStyle},
{TK_CONFIG_STRING, "-text", "text", "Text",
DEF_TEXTITEM_TEXT, Tk_Offset(TixTextItem, text),
TK_CONFIG_NULL_OK},
{TK_CONFIG_INT, "-underline", "underline", "Underline",
DEF_TEXTITEM_UNDERLINE, Tk_Offset(TixTextItem, underline), 0},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, 0}
};
/*----------------------------------------------------------------------
*
* Configuration options for Text Styles
*
*----------------------------------------------------------------------
*/
static Tk_ConfigSpec textStyleConfigSpecs[] = {
{TK_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor",
DEF_TEXTSTYLE_ANCHOR, Tk_Offset(TixTextStyle, anchor), 0},
{TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
(char *) NULL, 0, 0},
#if 0
/* %bordercolor not used */
{TK_CONFIG_COLOR,"-bordercolor","borderColor","BorderColor",
DEF_TEXTSTYLE_BORDER_COLOR_COLOR, Tk_Offset(TixTextStyle, borderColor),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-bordercolor","borderColor","BorderColor",
DEF_TEXTSTYLE_BORDER_COLOR_MONO, Tk_Offset(TixTextStyle, borderColor),
TK_CONFIG_MONO_ONLY},
#endif
{TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL,
(char *) NULL, 0, 0},
{TK_CONFIG_FONT, "-font", "font", "Font",
DEF_TEXTSTYLE_FONT, Tk_Offset(TixTextStyle, font), 0},
{TK_CONFIG_JUSTIFY, "-justify", "justify", "Justyfy",
DEF_TEXTSTYLE_JUSTIFY, Tk_Offset(TixTextStyle, justify),
TK_CONFIG_NULL_OK},
{TK_CONFIG_PIXELS, "-padx", "padX", "Pad",
DEF_TEXTSTYLE_PADX, Tk_Offset(TixTextStyle, pad[0]), 0},
{TK_CONFIG_PIXELS, "-pady", "padY", "Pad",
DEF_TEXTSTYLE_PADY, Tk_Offset(TixTextStyle, pad[1]), 0},
{TK_CONFIG_PIXELS, "-wraplength", "wrapLength", "WrapLength",
DEF_TEXTSTYLE_WLENGTH, Tk_Offset(TixTextStyle, wrapLength), 0},
/* The following is automatically generated */
{TK_CONFIG_COLOR,"-background","background","Background",
DEF_TEXTSTYLE_NORMAL_BG_COLOR,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_NORMAL].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-background","background","Background",
DEF_TEXTSTYLE_NORMAL_BG_MONO,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_NORMAL].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-foreground","foreground","Foreground",
DEF_TEXTSTYLE_NORMAL_FG_COLOR,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_NORMAL].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-foreground","foreground","Foreground",
DEF_TEXTSTYLE_NORMAL_FG_MONO,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_NORMAL].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-activebackground","activeBackground","ActiveBackground",
DEF_TEXTSTYLE_ACTIVE_BG_COLOR,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_ACTIVE].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-activebackground","activeBackground","ActiveBackground",
DEF_TEXTSTYLE_ACTIVE_BG_MONO,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_ACTIVE].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-activeforeground","activeForeground","ActiveForeground",
DEF_TEXTSTYLE_ACTIVE_FG_COLOR,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_ACTIVE].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-activeforeground","activeForeground","ActiveForeground",
DEF_TEXTSTYLE_ACTIVE_FG_MONO,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_ACTIVE].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-selectbackground","selectBackground","SelectBackground",
DEF_TEXTSTYLE_SELECTED_BG_COLOR,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_SELECTED].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-selectbackground","selectBackground","SelectBackground",
DEF_TEXTSTYLE_SELECTED_BG_MONO,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_SELECTED].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-selectforeground","selectForeground","SelectForeground",
DEF_TEXTSTYLE_SELECTED_FG_COLOR,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_SELECTED].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-selectforeground","selectForeground","SelectForeground",
DEF_TEXTSTYLE_SELECTED_FG_MONO,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_SELECTED].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-disabledbackground","disabledBackground","DisabledBackground",
DEF_TEXTSTYLE_DISABLED_BG_COLOR,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_DISABLED].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-disabledbackground","disabledBackground","DisabledBackground",
DEF_TEXTSTYLE_DISABLED_BG_MONO,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_DISABLED].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-disabledforeground","disabledForeground","DisabledForeground",
DEF_TEXTSTYLE_DISABLED_FG_COLOR,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_DISABLED].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-disabledforeground","disabledForeground","DisabledForeground",
DEF_TEXTSTYLE_DISABLED_FG_MONO,
Tk_Offset(TixTextStyle,colors[TIX_DITEM_DISABLED].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, 0}
};
/*----------------------------------------------------------------------
* Forward declarations for procedures defined later in this file:
*----------------------------------------------------------------------
*/
static void Tix_TextItemCalculateSize _ANSI_ARGS_((
Tix_DItem * iPtr));
static char * Tix_TextItemComponent _ANSI_ARGS_((
Tix_DItem * iPtr, int x, int y));
static int Tix_TextItemConfigure _ANSI_ARGS_((
Tix_DItem * iPtr, int argc, CONST84 char ** argv,
int flags));
static Tix_DItem * Tix_TextItemCreate _ANSI_ARGS_((
Tix_DispData * ddPtr, Tix_DItemInfo * diTypePtr));
static void Tix_TextItemDisplay _ANSI_ARGS_((
Drawable drawable, Tix_DItem * iPtr,
int x, int y, int width, int height,
int xOffset, int yOffset, int flags));
static void Tix_TextItemFree _ANSI_ARGS_((
Tix_DItem * iPtr));
static void Tix_TextItemLostStyle _ANSI_ARGS_((
Tix_DItem * iPtr));
static void Tix_TextItemStyleChanged _ANSI_ARGS_((
Tix_DItem * iPtr));
static int Tix_TextStyleConfigure _ANSI_ARGS_((
Tix_DItemStyle* style, int argc, CONST84 char ** argv,
int flags));
static Tix_DItemStyle * Tix_TextStyleCreate _ANSI_ARGS_((
Tcl_Interp *interp, Tk_Window tkwin,
Tix_DItemInfo * diTypePtr, char * name));
static void Tix_TextStyleFree _ANSI_ARGS_((
Tix_DItemStyle* style));
static void Tix_TextStyleSetTemplate _ANSI_ARGS_((
Tix_DItemStyle* style,
Tix_StyleTemplate * tmplPtr));
Tix_DItemInfo tix_TextItemType = {
"text", /* type */
TIX_DITEM_TEXT,
Tix_TextItemCreate, /* createProc */
Tix_TextItemConfigure,
Tix_TextItemCalculateSize,
Tix_TextItemComponent,
Tix_TextItemDisplay,
Tix_TextItemFree,
Tix_TextItemStyleChanged,
Tix_TextItemLostStyle,
Tix_TextStyleCreate,
Tix_TextStyleConfigure,
Tix_TextStyleFree,
Tix_TextStyleSetTemplate,
textItemConfigSpecs,
textStyleConfigSpecs,
NULL, /*next */
};
/*----------------------------------------------------------------------
* Tix_TextItemCreate --
*
*
*----------------------------------------------------------------------
*/
static Tix_DItem * Tix_TextItemCreate(ddPtr, diTypePtr)
Tix_DispData * ddPtr;
Tix_DItemInfo * diTypePtr;
{
TixTextItem * itPtr;
itPtr = (TixTextItem*) ckalloc(sizeof(TixTextItem));
itPtr->diTypePtr = &tix_TextItemType;
itPtr->ddPtr = ddPtr;
itPtr->stylePtr = (TixTextStyle*)TixGetDefaultDItemStyle(
itPtr->ddPtr, &tix_TextItemType,
(Tix_DItem*)itPtr, NULL);
itPtr->clientData = 0;
itPtr->size[0] = 0;
itPtr->size[1] = 0;
itPtr->selX = 0;
itPtr->selY = 0;
itPtr->selW = 0;
itPtr->selH = 0;
itPtr->numChars = 0;
itPtr->text = NULL;
itPtr->textW = 0;
itPtr->textH = 0;
itPtr->underline = -1;
return (Tix_DItem *)itPtr;
}
static void Tix_TextItemFree(iPtr)
Tix_DItem * iPtr;
{
TixTextItem * itPtr = (TixTextItem *) iPtr;
if (itPtr->stylePtr) {
TixDItemStyleFree(iPtr, (Tix_DItemStyle*)itPtr->stylePtr);
}
Tk_FreeOptions(textItemConfigSpecs, (char *)itPtr,
itPtr->ddPtr->display, 0);
ckfree((char*)itPtr);
}
static int
Tix_TextItemConfigure(iPtr, argc, argv, flags)
Tix_DItem * iPtr;
int argc;
CONST84 char ** argv;
int flags;
{
TixTextItem * itPtr = (TixTextItem *) iPtr;
TixTextStyle * oldStyle = itPtr->stylePtr;
if (Tk_ConfigureWidget(itPtr->ddPtr->interp, itPtr->ddPtr->tkwin,
textItemConfigSpecs,
argc, argv, (char *)itPtr, flags) != TCL_OK) {
return TCL_ERROR;
}
if (itPtr->stylePtr == NULL) {
itPtr->stylePtr = (TixTextStyle*)TixGetDefaultDItemStyle(
itPtr->ddPtr, &tix_TextItemType, iPtr, NULL);
}
if (oldStyle != NULL && itPtr->stylePtr != oldStyle) {
Tix_TextItemStyleChanged(iPtr);
}
else {
Tix_TextItemCalculateSize((Tix_DItem*)itPtr);
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* Tix_TextItemDisplay --
*
* Display a text item. {x, y, width, height} specifies a region
* for to display this item in. {xOffset, yOffset} gives the
* offset of the top-left corner of the text item relative to
* the top-left corder of the region.
*
* Background and foreground of the item are displayed according
* to the flags parameter.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static void
Tix_TextItemDisplay(drawable, iPtr, x, y, width, height, xOffset, yOffset,
flags)
Drawable drawable;
Tix_DItem * iPtr;
int x;
int y;
int width;
int height;
int xOffset;
int yOffset;
int flags;
{
TixTextItem *itPtr = (TixTextItem *)iPtr;
Display * display = iPtr->base.ddPtr->display;
TixpSubRegion subReg;
GC foreGC;
if ((width <= 0) || (height <= 0)) {
return;
}
TixGetColorDItemGC(iPtr, NULL, &foreGC, NULL, flags);
TixpStartSubRegionDraw(display, drawable, foreGC,
&subReg, 0, 0, x, y, width, height,
itPtr->size[0] + xOffset, itPtr->size[1] + yOffset);
Tix_DItemDrawBackground(drawable, &subReg, iPtr, x, y, width, height,
xOffset, yOffset, flags);
/*
* Calculate the location of the text according to anchor settings.
*/
TixDItemGetAnchor(iPtr->base.stylePtr->anchor, x, y, width, height,
iPtr->base.size[0], iPtr->base.size[1], &x, &y);
if (foreGC != None && itPtr->text != NULL) {
/*
* Draw the text
*/
x += itPtr->stylePtr->pad[0] + xOffset;
y += itPtr->stylePtr->pad[1] + yOffset;
TixpSubRegDisplayText(display, drawable, foreGC,
&subReg, itPtr->stylePtr->font, itPtr->text,
itPtr->numChars, x, y, itPtr->textW, itPtr->stylePtr->justify,
itPtr->underline);
}
TixpEndSubRegionDraw(display, drawable, foreGC,
&subReg);
}
/*
*----------------------------------------------------------------------
*
* Tix_TextItemComponent --
*
* Identifies the sub-component of this text item at the given
* {x, y} location. Text items are not divided into sub-components
* so the string "body" is always returned.
*
* The returned string is statically allocated.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static char *
Tix_TextItemComponent(iPtr, x, y)
Tix_DItem * iPtr;
int x;
int y;
{
static char * body = "body";
return body;
}
static void
Tix_TextItemCalculateSize(iPtr)
Tix_DItem * iPtr;
{
TixTextItem *itPtr = (TixTextItem *)iPtr;
char * text = itPtr->text;
if (text == NULL || *text == '\0') {
/*
* Use one space character so that the height of the item
* would be the same as a regular small item, and the width
* of the item won't be too tiny.
*/
text = " ";
}
itPtr->numChars = -1;
TixComputeTextGeometry(itPtr->stylePtr->font, text, -1,
itPtr->stylePtr->wrapLength, &itPtr->textW, &itPtr->textH);
itPtr->size[0] = itPtr->textW;
itPtr->size[1] = itPtr->textH;
itPtr->size[0] += 2*itPtr->stylePtr->pad[0];
itPtr->size[1] += 2*itPtr->stylePtr->pad[1];
itPtr->selX = 0;
itPtr->selY = 0;
itPtr->selW = itPtr->size[0];
itPtr->selH = itPtr->size[1];
}
static void
Tix_TextItemStyleChanged(iPtr)
Tix_DItem * iPtr;
{
TixTextItem *itPtr = (TixTextItem *)iPtr;
if (itPtr->stylePtr == NULL) {
/* Maybe we haven't set the style to default style yet */
return;
}
Tix_TextItemCalculateSize(iPtr);
if (itPtr->ddPtr->sizeChangedProc != NULL) {
itPtr->ddPtr->sizeChangedProc(iPtr);
}
}
static void
Tix_TextItemLostStyle(iPtr)
Tix_DItem * iPtr;
{
TixTextItem *itPtr = (TixTextItem *)iPtr;
itPtr->stylePtr = (TixTextStyle*)TixGetDefaultDItemStyle(
itPtr->ddPtr, &tix_TextItemType, iPtr, NULL);
Tix_TextItemStyleChanged(iPtr);
}
/*----------------------------------------------------------------------
*
*
* Display styles
*
*
*----------------------------------------------------------------------
*/
static Tix_DItemStyle *
Tix_TextStyleCreate(interp, tkwin, diTypePtr, name)
Tcl_Interp * interp;
Tk_Window tkwin;
char * name;
Tix_DItemInfo * diTypePtr;
{
TixTextStyle * stylePtr = (TixTextStyle *)ckalloc(sizeof(TixTextStyle));
stylePtr->font = NULL;
stylePtr->justify = TK_JUSTIFY_LEFT;
stylePtr->wrapLength = 0;
return (Tix_DItemStyle *)stylePtr;
}
static int
Tix_TextStyleConfigure(style, argc, argv, flags)
Tix_DItemStyle *style;
int argc;
CONST84 char ** argv;
int flags;
{
TixTextStyle * stylePtr = (TixTextStyle *)style;
XGCValues gcValues;
GC newGC;
int i, isNew;
if (stylePtr->font == NULL) {
isNew = 1;
} else {
isNew = 0;
}
/*
* TODO: gap, wrapLength, etc changes: need to call TixDItemStyleChanged
*/
if (!(flags &TIX_DONT_CALL_CONFIG)) {
if (Tk_ConfigureWidget(stylePtr->interp, stylePtr->tkwin,
textStyleConfigSpecs,
argc, argv, (char *)stylePtr, flags) != TCL_OK) {
return TCL_ERROR;
}
}
gcValues.font = TixFontId(stylePtr->font);
gcValues.graphics_exposures = False;
for (i=0; i<4; i++) {
/*
* Foreground GC
*/
gcValues.background = stylePtr->colors[i].bg->pixel;
gcValues.foreground = stylePtr->colors[i].fg->pixel;
newGC = Tk_GetGC(stylePtr->tkwin,
GCFont|GCForeground|GCBackground|GCGraphicsExposures, &gcValues);
if (stylePtr->colors[i].foreGC != None) {
Tk_FreeGC(Tk_Display(stylePtr->tkwin),
stylePtr->colors[i].foreGC);
}
stylePtr->colors[i].foreGC = newGC;
/*
* Background GC
*/
gcValues.foreground = stylePtr->colors[i].bg->pixel;
newGC = Tk_GetGC(stylePtr->tkwin,
GCFont|GCForeground|GCGraphicsExposures, &gcValues);
if (stylePtr->colors[i].backGC != None) {
Tk_FreeGC(Tk_Display(stylePtr->tkwin),
stylePtr->colors[i].backGC);
}
stylePtr->colors[i].backGC = newGC;
/*
* Anchor GC
*/
newGC = Tix_GetAnchorGC(stylePtr->tkwin,
stylePtr->colors[i].bg);
if (stylePtr->colors[i].anchorGC != None) {
Tk_FreeGC(Tk_Display(stylePtr->tkwin),
stylePtr->colors[i].anchorGC);
}
stylePtr->colors[i].anchorGC = newGC;
}
if (!isNew) {
TixDItemStyleChanged(stylePtr->diTypePtr, (Tix_DItemStyle *)stylePtr);
}
return TCL_OK;
}
static void
Tix_TextStyleFree(style)
Tix_DItemStyle *style;
{
TixTextStyle * stylePtr = (TixTextStyle *)style;
Tk_FreeOptions(textStyleConfigSpecs, (char *)stylePtr,
Tk_Display(stylePtr->tkwin), 0);
ckfree((char *)stylePtr);
}
static int bg_flags [4] = {
TIX_DITEM_NORMAL_BG,
TIX_DITEM_ACTIVE_BG,
TIX_DITEM_SELECTED_BG,
TIX_DITEM_DISABLED_BG
};
static int fg_flags [4] = {
TIX_DITEM_NORMAL_FG,
TIX_DITEM_ACTIVE_FG,
TIX_DITEM_SELECTED_FG,
TIX_DITEM_DISABLED_FG
};
static void
Tix_TextStyleSetTemplate(style, tmplPtr)
Tix_DItemStyle* style;
Tix_StyleTemplate * tmplPtr;
{
TixTextStyle * stylePtr = (TixTextStyle *)style;
int i;
if (tmplPtr->flags & TIX_DITEM_FONT) {
if (stylePtr->font != NULL) {
TixFreeFont(stylePtr->font);
}
stylePtr->font = TixGetFont(
stylePtr->interp, stylePtr->tkwin,
TixNameOfFont(tmplPtr->font));
}
if (tmplPtr->flags & TIX_DITEM_PADX) {
stylePtr->pad[0] = tmplPtr->pad[0];
}
if (tmplPtr->flags & TIX_DITEM_PADY) {
stylePtr->pad[1] = tmplPtr->pad[1];
}
for (i=0; i<4; i++) {
if (tmplPtr->flags & bg_flags[i]) {
if (stylePtr->colors[i].bg != NULL) {
Tk_FreeColor(stylePtr->colors[i].bg);
}
stylePtr->colors[i].bg = Tk_GetColor(
stylePtr->interp, stylePtr->tkwin,
Tk_NameOfColor(tmplPtr->colors[i].bg));
}
}
for (i=0; i<4; i++) {
if (tmplPtr->flags & fg_flags[i]) {
if (stylePtr->colors[i].fg != NULL) {
Tk_FreeColor(stylePtr->colors[i].fg);
}
stylePtr->colors[i].fg = Tk_GetColor(
stylePtr->interp, stylePtr->tkwin,
Tk_NameOfColor(tmplPtr->colors[i].fg));
}
}
Tix_TextStyleConfigure(style, 0, 0, TIX_DONT_CALL_CONFIG);
}

934
generic/tixDiWin.c Normal file
View File

@@ -0,0 +1,934 @@
/*
* tixDiWin.c --
*
* This file implements one of the "Display Items" in the Tix library :
* WindowItem display items.
*
* Copyright (c) 1993-1999 Ioi Kim Lam.
* Copyright (c) 2000-2001 Tix Project Group.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tixDiWin.c,v 1.3 2004/03/28 02:44:56 hobbs Exp $
*/
#include <tixPort.h>
#include <tixInt.h>
#include <tixDef.h>
/*----------------------------------------------------------------------
*
* Data structures used by this file
*
*----------------------------------------------------------------------
*/
/*----------------------------------------------------------------------
*
* Private data definition
*
*----------------------------------------------------------------------
*/
static Tix_ListInfo mapWinListInfo = {
Tk_Offset(TixWindowItem, next),
TIX_UNDEFINED,
};
#define DEF_WINDOWITEM_WINDOW ""
#define DEF_WINDOWITEM_STYLE ""
#define DEF_WINDOWITEM_TYPE "window"
static Tk_ConfigSpec windowItemConfigSpecs[] = {
{TK_CONFIG_CUSTOM, "-itemtype", "itemType", "ItemType",
DEF_WINDOWITEM_TYPE, Tk_Offset(TixWindowItem, diTypePtr),
0, &tixConfigItemType},
{TK_CONFIG_CUSTOM, "-style", "windowStyle", "WindowStyle",
DEF_WINDOWITEM_STYLE, Tk_Offset(TixWindowItem, stylePtr),
TK_CONFIG_NULL_OK, &tixConfigItemStyle},
{TK_CONFIG_SYNONYM, "-widget", (char *) NULL, (char *) NULL,
(char *)NULL, 0, 0},
{TK_CONFIG_WINDOW, "-window", "window", "Window",
DEF_WINDOWITEM_WINDOW, Tk_Offset(TixWindowItem, tkwin), 0},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, 0}
};
/*----------------------------------------------------------------------
*
* Configuration options for Window Styles
*
*----------------------------------------------------------------------
*/
#define DEF_WINDOWSTYLE_PADX "0"
#define DEF_WINDOWSTYLE_PADY "0"
#define DEF_WINDOWSTYLE_ANCHOR "w"
#define SELECTED_BG SELECT_BG
#define DISABLED_BG DISABLED
#define DEF_WINDOWSTYLE_NORMAL_FG_COLOR BLACK
#define DEF_WINDOWSTYLE_NORMAL_FG_MONO BLACK
#define DEF_WINDOWSTYLE_NORMAL_BG_COLOR NORMAL_BG
#define DEF_WINDOWSTYLE_NORMAL_BG_MONO WHITE
#define DEF_WINDOWSTYLE_ACTIVE_FG_COLOR BLACK
#define DEF_WINDOWSTYLE_ACTIVE_FG_MONO WHITE
#define DEF_WINDOWSTYLE_ACTIVE_BG_COLOR ACTIVE_BG
#define DEF_WINDOWSTYLE_ACTIVE_BG_MONO BLACK
#define DEF_WINDOWSTYLE_SELECTED_FG_COLOR BLACK
#define DEF_WINDOWSTYLE_SELECTED_FG_MONO WHITE
#define DEF_WINDOWSTYLE_SELECTED_BG_COLOR SELECTED_BG
#define DEF_WINDOWSTYLE_SELECTED_BG_MONO BLACK
#define DEF_WINDOWSTYLE_DISABLED_FG_COLOR BLACK
#define DEF_WINDOWSTYLE_DISABLED_FG_MONO BLACK
#define DEF_WINDOWSTYLE_DISABLED_BG_COLOR DISABLED_BG
#define DEF_WINDOWSTYLE_DISABLED_BG_MONO WHITE
static Tk_ConfigSpec windowStyleConfigSpecs[] = {
{TK_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor",
DEF_WINDOWSTYLE_ANCHOR, Tk_Offset(TixWindowStyle, anchor), 0},
{TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
(char *) NULL, 0, 0},
{TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL,
(char *) NULL, 0, 0},
{TK_CONFIG_PIXELS, "-padx", "padX", "Pad",
DEF_WINDOWSTYLE_PADX, Tk_Offset(TixWindowStyle, pad[0]), 0},
{TK_CONFIG_PIXELS, "-pady", "padY", "Pad",
DEF_WINDOWSTYLE_PADY, Tk_Offset(TixWindowStyle, pad[1]), 0},
/* The following was automatically generated */
{TK_CONFIG_COLOR,"-background","background","Background",
DEF_WINDOWSTYLE_NORMAL_BG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_NORMAL].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-background","background","Background",
DEF_WINDOWSTYLE_NORMAL_BG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_NORMAL].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-foreground","foreground","Foreground",
DEF_WINDOWSTYLE_NORMAL_FG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_NORMAL].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-foreground","foreground","Foreground",
DEF_WINDOWSTYLE_NORMAL_FG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_NORMAL].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-activebackground","activeBackground","ActiveBackground",
DEF_WINDOWSTYLE_ACTIVE_BG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_ACTIVE].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-activebackground","activeBackground","ActiveBackground",
DEF_WINDOWSTYLE_ACTIVE_BG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_ACTIVE].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-activeforeground","activeForeground","ActiveForeground",
DEF_WINDOWSTYLE_ACTIVE_FG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_ACTIVE].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-activeforeground","activeForeground","ActiveForeground",
DEF_WINDOWSTYLE_ACTIVE_FG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_ACTIVE].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-selectbackground","selectBackground","SelectBackground",
DEF_WINDOWSTYLE_SELECTED_BG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_SELECTED].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-selectbackground","selectBackground","SelectBackground",
DEF_WINDOWSTYLE_SELECTED_BG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_SELECTED].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-selectforeground","selectForeground","SelectForeground",
DEF_WINDOWSTYLE_SELECTED_FG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_SELECTED].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-selectforeground","selectForeground","SelectForeground",
DEF_WINDOWSTYLE_SELECTED_FG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_SELECTED].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-disabledbackground","disabledBackground","DisabledBackground",
DEF_WINDOWSTYLE_DISABLED_BG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_DISABLED].bg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-disabledbackground","disabledBackground","DisabledBackground",
DEF_WINDOWSTYLE_DISABLED_BG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_DISABLED].bg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_COLOR,"-disabledforeground","disabledForeground","DisabledForeground",
DEF_WINDOWSTYLE_DISABLED_FG_COLOR,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_DISABLED].fg),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_COLOR,"-disabledforeground","disabledForeground","DisabledForeground",
DEF_WINDOWSTYLE_DISABLED_FG_MONO,
Tk_Offset(TixImageStyle,colors[TIX_DITEM_DISABLED].fg),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, 0}
};
/*----------------------------------------------------------------------
* Forward declarations for procedures defined later in this file:
*----------------------------------------------------------------------
*/
static void SubWindowLostSlaveProc _ANSI_ARGS_((
ClientData clientData, Tk_Window tkwin));
static void SubWindowRequestProc _ANSI_ARGS_((
ClientData clientData, Tk_Window tkwin));
static void SubWindowStructureProc _ANSI_ARGS_((
ClientData clientData, XEvent *eventPtr));
static char * Tix_WindowItemComponent _ANSI_ARGS_((
Tix_DItem * iPtr, int x, int y));
static void Tix_WindowItemCalculateSize _ANSI_ARGS_((
Tix_DItem * iPtr));
static int Tix_WindowItemConfigure _ANSI_ARGS_((
Tix_DItem * iPtr, int argc, CONST84 char ** argv,
int flags));
static Tix_DItem * Tix_WindowItemCreate _ANSI_ARGS_((
Tix_DispData * ddPtr, Tix_DItemInfo * diTypePtr));
static void Tix_WindowItemDisplay _ANSI_ARGS_((
Drawable drawable, Tix_DItem * iPtr,
int x, int y, int width, int height,
int xOffset, int yOffset, int flags));
static void Tix_WindowItemFree _ANSI_ARGS_((
Tix_DItem * iPtr));
static void Tix_WindowItemLostStyle _ANSI_ARGS_((
Tix_DItem * iPtr));
static void Tix_WindowItemStyleChanged _ANSI_ARGS_((
Tix_DItem * iPtr));
static void Tix_WindowItemUnmap _ANSI_ARGS_((
TixWindowItem *itPtr));
static int Tix_WindowStyleConfigure _ANSI_ARGS_((
Tix_DItemStyle* style, int argc, CONST84 char ** argv,
int flags));
static Tix_DItemStyle * Tix_WindowStyleCreate _ANSI_ARGS_((
Tcl_Interp *interp, Tk_Window tkwin,
Tix_DItemInfo * diTypePtr, char * name));
static void Tix_WindowStyleFree _ANSI_ARGS_((
Tix_DItemStyle* style));
static void Tix_WindowStyleSetTemplate _ANSI_ARGS_((
Tix_DItemStyle* style,
Tix_StyleTemplate * tmplPtr));
static void UnmanageWindow _ANSI_ARGS_((Tix_DItem * iPtr,
Tk_Window tkwin));
static void ManageWindow _ANSI_ARGS_((Tix_DItem * iPtr,
Tk_Window tkwin));
Tix_DItemInfo tix_WindowItemType = {
"window", /* type */
TIX_DITEM_WINDOW,
Tix_WindowItemCreate, /* createProc */
Tix_WindowItemConfigure,
Tix_WindowItemCalculateSize,
Tix_WindowItemComponent,
Tix_WindowItemDisplay,
Tix_WindowItemFree,
Tix_WindowItemStyleChanged,
Tix_WindowItemLostStyle,
Tix_WindowStyleCreate,
Tix_WindowStyleConfigure,
Tix_WindowStyleFree,
Tix_WindowStyleSetTemplate,
windowItemConfigSpecs,
windowStyleConfigSpecs,
NULL, /*next */
};
/*
* The structure below defines the official type record for the
* placer:
*/
static Tk_GeomMgr windowItemGeomType = {
"tixWindowItem", /* name */
SubWindowRequestProc, /* requestProc */
SubWindowLostSlaveProc, /* lostSlaveProc */
};
/*----------------------------------------------------------------------
* Tix_WindowItemCreate --
*
*
*----------------------------------------------------------------------
*/
static Tix_DItem * Tix_WindowItemCreate(ddPtr, diTypePtr)
Tix_DispData * ddPtr;
Tix_DItemInfo * diTypePtr;
{
TixWindowItem * itPtr;
itPtr = (TixWindowItem*) ckalloc(sizeof(TixWindowItem));
itPtr->diTypePtr = diTypePtr;
itPtr->ddPtr = ddPtr;
itPtr->stylePtr = NULL;
itPtr->clientData = 0;
itPtr->size[0] = 0;
itPtr->size[1] = 0;
itPtr->tkwin = NULL;
return (Tix_DItem *)itPtr;
}
/* %% */
static void Tix_WindowItemFree(iPtr)
Tix_DItem * iPtr;
{
TixWindowItem * itPtr = (TixWindowItem *) iPtr;
if (itPtr->tkwin) {
Tk_DeleteEventHandler(itPtr->tkwin, StructureNotifyMask,
SubWindowStructureProc, (ClientData) itPtr);
Tk_ManageGeometry(itPtr->tkwin, (Tk_GeomMgr *)NULL,
(ClientData) NULL);
Tk_UnmapWindow(itPtr->tkwin);
}
if (itPtr->stylePtr) {
TixDItemStyleFree(iPtr, (Tix_DItemStyle*)itPtr->stylePtr);
}
Tk_FreeOptions(windowItemConfigSpecs, (char *)itPtr,
itPtr->ddPtr->display, 0);
ckfree((char*)itPtr);
}
/*----------------------------------------------------------------------
* ManageWindow --
*
* Associate this sub-window with the window item.
*
* Side effect:
* itPtr->tkwin is changed.
*----------------------------------------------------------------------
*/
static void
ManageWindow(iPtr, tkwin)
Tix_DItem * iPtr;
Tk_Window tkwin;
{
TixWindowItem * itPtr = (TixWindowItem *) iPtr;
Tk_CreateEventHandler(tkwin, StructureNotifyMask,
SubWindowStructureProc, (ClientData) itPtr);
Tk_ManageGeometry(tkwin, &windowItemGeomType,
(ClientData) itPtr);
itPtr->tkwin = tkwin;
}
/*----------------------------------------------------------------------
* UnmanageWindow --
*
* Disassociate this sub-window from the window item.
*
* Note:
* the tkwin parameter may not equal to itPtr->tkwin.
*----------------------------------------------------------------------
*/
static void
UnmanageWindow(iPtr, tkwin)
Tix_DItem * iPtr;
Tk_Window tkwin;
{
TixWindowItem * itPtr = (TixWindowItem *) iPtr;
Tk_DeleteEventHandler(tkwin, StructureNotifyMask,
SubWindowStructureProc, (ClientData) itPtr);
Tk_ManageGeometry(tkwin, (Tk_GeomMgr *)NULL,
(ClientData) NULL);
Tk_UnmapWindow(tkwin);
}
static int Tix_WindowItemConfigure(iPtr, argc, argv, flags)
Tix_DItem * iPtr;
int argc;
CONST84 char ** argv;
int flags;
{
TixWindowItem * itPtr = (TixWindowItem *) iPtr;
TixWindowStyle * oldStyle = itPtr->stylePtr;
Tk_Window oldWindow;
oldWindow = itPtr->tkwin;
if (Tk_ConfigureWidget(itPtr->ddPtr->interp, itPtr->ddPtr->tkwin,
windowItemConfigSpecs,
argc, argv, (char *)itPtr, flags) != TCL_OK) {
return TCL_ERROR;
}
if (itPtr->stylePtr == NULL) {
itPtr->stylePtr = (TixWindowStyle*)TixGetDefaultDItemStyle(
itPtr->ddPtr, &tix_WindowItemType, iPtr, NULL);
}
if (oldWindow != itPtr->tkwin) {
if (oldWindow != NULL) {
UnmanageWindow(iPtr, oldWindow);
}
if (itPtr->tkwin != NULL) {
/*
* Make sure that the master window is the parent of the
* window associated with the item.
* Also, don't allow a top-level window to be
* managed inside a master window.
*/
if (Tk_Parent(itPtr->tkwin) != itPtr->ddPtr->tkwin) {
Tcl_AppendResult(itPtr->ddPtr->interp, "can't use ",
Tk_PathName(itPtr->tkwin),
" in a window item of the master widget: must be a child",
" of ", Tk_PathName(itPtr->ddPtr->tkwin), (char *) NULL);
goto badWindow;
}
if (((Tk_FakeWin *) (itPtr->tkwin))->flags & TK_TOP_LEVEL) {
Tcl_AppendResult(itPtr->ddPtr->interp,
"can't manage toplevel window",
Tk_PathName(itPtr->tkwin),
" as a window item of ", Tk_PathName(itPtr->ddPtr->tkwin),
(char *) NULL);
goto badWindow;
}
ManageWindow(iPtr, itPtr->tkwin);
}
}
if (oldStyle != NULL && itPtr->stylePtr != oldStyle) {
Tix_WindowItemStyleChanged(iPtr);
}
else {
Tix_WindowItemCalculateSize((Tix_DItem*)itPtr);
}
return TCL_OK;
badWindow:
itPtr->tkwin = NULL;
return TCL_ERROR;
}
/*
*----------------------------------------------------------------------
*
* Tix_WindowItemDisplay --
*
* Display an window item. {x, y, width, height} specifies a
* region for to display this item in. {xOffset, yOffset} gives
* the offset of the top-left corner of the window item relative
* to the top-left corder of the region.
*
* Background and foreground of the item are displayed according
* to the flags parameter.
*
* Results:
* None.
*
* Side effects:
* The geometry management calls such as Tk_MoveResizeWindow()
* may cause repaints in the parent window that owns this item,
* but it shouldn't enter an infinite loop.
* Tk_MoveResizeWindow (or the underlying windowing system?) will
* supress repaint events if the window's geometry is not changed
* by the Tk_MoveResizeWindow call.
*
*----------------------------------------------------------------------
*/
static void
Tix_WindowItemDisplay(drawable, iPtr, x, y, width, height, xOffset, yOffset,
flags)
Drawable drawable;
Tix_DItem * iPtr;
int x;
int y;
int width;
int height;
int flags;
{
TixWindowItem *itPtr = (TixWindowItem *)iPtr;
Display * display = itPtr->ddPtr->display;
TixpSubRegion subReg;
GC foreGC;
int winX, winY, winH, winW;
if (itPtr->tkwin == NULL) {
return;
}
TixGetColorDItemGC(iPtr, NULL, &foreGC, NULL, flags);
TixpStartSubRegionDraw(display, drawable, foreGC,
&subReg, 0, 0, x, y, width, height,
itPtr->size[0] + xOffset, itPtr->size[1] + yOffset);
Tix_DItemDrawBackground(drawable, &subReg, iPtr, x, y, width, height,
xOffset, yOffset, flags);
/*
* Calculate the location of the window according to anchor settings.
*/
TixDItemGetAnchor(itPtr->stylePtr->anchor, x, y, width, height,
itPtr->size[0], itPtr->size[1], &x, &y);
winX = xOffset + itPtr->stylePtr->pad[0];
winY = yOffset + itPtr->stylePtr->pad[1];
winW = itPtr->size[0] - 2*itPtr->stylePtr->pad[0];
winH = itPtr->size[1] - 2*itPtr->stylePtr->pad[1];
if (winW + winX > width) {
winW = width - winX;
}
if (winH + winY > height) {
winH = height - winY;
}
winX += x;
winY += y;
if (width < 1 || height < 1 || winW < 1 || winH < 1) {
if (itPtr->ddPtr->tkwin != Tk_Parent(itPtr->tkwin)) {
Tk_UnmaintainGeometry(itPtr->tkwin, itPtr->ddPtr->tkwin);
}
Tk_UnmapWindow(itPtr->tkwin);
} else {
if (itPtr->ddPtr->tkwin == Tk_Parent(itPtr->tkwin)) {
Tk_MapWindow(itPtr->tkwin);
Tk_MoveResizeWindow(itPtr->tkwin, winX, winY, winW, winH);
} else {
Tk_MaintainGeometry(itPtr->tkwin, itPtr->ddPtr->tkwin,
winX, winY, winW, winH);
}
}
TixpEndSubRegionDraw(display, drawable, foreGC,
&subReg);
}
static void
Tix_WindowItemCalculateSize(iPtr)
Tix_DItem * iPtr;
{
TixWindowItem *itPtr = (TixWindowItem*)iPtr;
if (itPtr->tkwin != NULL) {
itPtr->size[0] = Tk_ReqWidth (itPtr->tkwin);
itPtr->size[1] = Tk_ReqHeight(itPtr->tkwin);
} else {
itPtr->size[0] = 0;
itPtr->size[1] = 0;
}
itPtr->size[0] += 2*itPtr->stylePtr->pad[0];
itPtr->size[1] += 2*itPtr->stylePtr->pad[1];
itPtr->selX = 0;
itPtr->selY = 0;
itPtr->selW = itPtr->size[0];
itPtr->selH = itPtr->size[1];
}
static char * Tix_WindowItemComponent(iPtr, x, y)
Tix_DItem * iPtr;
int x;
int y;
{
#if 0
TixWindowItem *itPtr = (TixWindowItem *)iPtr;
#endif
static char * body = "body";
return body;
}
static void Tix_WindowItemStyleChanged(iPtr)
Tix_DItem * iPtr;
{
TixWindowItem *itPtr = (TixWindowItem *)iPtr;
if (itPtr->stylePtr == NULL) {
/* Maybe we haven't set the style to default style yet */
return;
}
Tix_WindowItemCalculateSize(iPtr);
if (itPtr->ddPtr->sizeChangedProc != NULL) {
itPtr->ddPtr->sizeChangedProc(iPtr);
}
}
static void Tix_WindowItemLostStyle(iPtr)
Tix_DItem * iPtr;
{
TixWindowItem *itPtr = (TixWindowItem *)iPtr;
itPtr->stylePtr = (TixWindowStyle*)TixGetDefaultDItemStyle(
itPtr->ddPtr, &tix_WindowItemType, iPtr, NULL);
Tix_WindowItemStyleChanged(iPtr);
}
/*
*--------------------------------------------------------------
*
* SubWindowStructureProc --
*
* This procedure is invoked whenever StructureNotify events
* occur for a window that's managed as part of a display
* item. This procudure's only purpose is to clean up when
* windows are deleted.
*
* Results:
* None.
*
* Side effects:
* The window is disassociated from the window item when it is
* deleted.
*
*--------------------------------------------------------------
*/
static void
SubWindowStructureProc(clientData, eventPtr)
ClientData clientData; /* Pointer to record describing window item. */
XEvent *eventPtr; /* Describes what just happened. */
{
TixWindowItem * itPtr = (TixWindowItem *)clientData;
int oldWidth, oldHeight;
if (eventPtr->type == DestroyNotify) {
itPtr->tkwin = NULL;
}
oldWidth = itPtr->size[0];
oldHeight = itPtr->size[1];
Tix_WindowItemCalculateSize((Tix_DItem*)itPtr);
if (oldWidth != itPtr->size[0] || oldHeight != itPtr->size[1]) {
if (itPtr->ddPtr->sizeChangedProc != NULL) {
itPtr->ddPtr->sizeChangedProc((Tix_DItem*)itPtr);
}
}
}
/*
*--------------------------------------------------------------
*
* SubWindowRequestProc --
*
* This procedure is invoked whenever a window that's associated
* with a display item changes its requested dimensions.
*
* Results:
* None.
*
* Side effects:
* The size and location on the screen of the window may change,
* depending on the options specified for the window item.
*
*--------------------------------------------------------------
*/
static void
SubWindowRequestProc(clientData, tkwin)
ClientData clientData; /* Pointer to record for window item.*/
Tk_Window tkwin; /* Window that changed its desired
* size. */
{
TixWindowItem *itPtr = (TixWindowItem *) clientData;
Tix_WindowItemCalculateSize((Tix_DItem*)itPtr);
if (itPtr->ddPtr->sizeChangedProc != NULL) {
itPtr->ddPtr->sizeChangedProc((Tix_DItem*)itPtr);
}
}
/*
*--------------------------------------------------------------
*
* SubWindowLostSlaveProc --
*
* This procedure is invoked by Tk whenever some other geometry
* claims control over a slave that used to be managed by us.
*
* Results:
* None.
*
* Side effects:
* Forgets all information about the slave.
*
*--------------------------------------------------------------
*/
/* ARGSUSED */
static void
SubWindowLostSlaveProc(clientData, tkwin)
ClientData clientData; /* TixWindowItem structure for slave
* window that was stolen away. */
Tk_Window tkwin; /* Tk's handle for the slave window. */
{
TixWindowItem *itPtr = (TixWindowItem *) clientData;
if (itPtr->tkwin == NULL) {
return;
} else {
itPtr->tkwin = NULL;
}
Tk_DeleteEventHandler(tkwin, StructureNotifyMask,
SubWindowStructureProc, (ClientData) itPtr);
Tk_ManageGeometry(tkwin, (Tk_GeomMgr *)NULL,
(ClientData) NULL);
if (itPtr->ddPtr->tkwin != Tk_Parent(tkwin)) {
Tk_UnmaintainGeometry(tkwin, itPtr->ddPtr->tkwin);
}
Tk_UnmapWindow(tkwin);
/*
* Inform the owner that the size has changed
*/
Tix_WindowItemCalculateSize((Tix_DItem*)itPtr);
if (itPtr->ddPtr->sizeChangedProc != NULL) {
itPtr->ddPtr->sizeChangedProc((Tix_DItem*)itPtr);
}
}
/*----------------------------------------------------------------------
* Tix_WindowItemUnmap --
*
*
*----------------------------------------------------------------------
*/
static void
Tix_WindowItemUnmap(itPtr)
TixWindowItem *itPtr;
{
Tk_Window tkwin = itPtr->tkwin;
if (tkwin == NULL) {
return;
}
if (itPtr->ddPtr->tkwin != Tk_Parent(tkwin)) {
Tk_UnmaintainGeometry(tkwin, itPtr->ddPtr->tkwin);
}
Tk_UnmapWindow(tkwin);
}
/*----------------------------------------------------------------------
*
*
* Display styles
*
*
*----------------------------------------------------------------------
*/
static Tix_DItemStyle *
Tix_WindowStyleCreate(interp, tkwin, diTypePtr, name)
Tcl_Interp * interp;
Tk_Window tkwin;
char * name;
Tix_DItemInfo * diTypePtr;
{
TixWindowStyle * stylePtr =
(TixWindowStyle *)ckalloc(sizeof(TixWindowStyle));
return (Tix_DItemStyle *)stylePtr;
}
static int
Tix_WindowStyleConfigure(style, argc, argv, flags)
Tix_DItemStyle *style;
int argc;
CONST84 char ** argv;
int flags;
{
TixWindowStyle * stylePtr = (TixWindowStyle *)style;
int oldPadX;
int oldPadY;
oldPadX = stylePtr->pad[0];
oldPadY = stylePtr->pad[1];
if (!(flags &TIX_DONT_CALL_CONFIG)) {
if (Tk_ConfigureWidget(stylePtr->interp, stylePtr->tkwin,
windowStyleConfigSpecs,
argc, argv, (char *)stylePtr, flags) != TCL_OK) {
return TCL_ERROR;
}
}
TixDItemStyleConfigureGCs(style);
if (oldPadX != stylePtr->pad[0] || oldPadY != stylePtr->pad[1]) {
TixDItemStyleChanged(stylePtr->diTypePtr, (Tix_DItemStyle *)stylePtr);
}
return TCL_OK;
}
static void Tix_WindowStyleFree(style)
Tix_DItemStyle *style;
{
TixWindowStyle * stylePtr = (TixWindowStyle *)style;
Tk_FreeOptions(windowStyleConfigSpecs, (char *)stylePtr,
Tk_Display(stylePtr->tkwin), 0);
ckfree((char *)stylePtr);
}
static int bg_flags [4] = {
TIX_DITEM_NORMAL_BG,
TIX_DITEM_ACTIVE_BG,
TIX_DITEM_SELECTED_BG,
TIX_DITEM_DISABLED_BG
};
static int fg_flags [4] = {
TIX_DITEM_NORMAL_FG,
TIX_DITEM_ACTIVE_FG,
TIX_DITEM_SELECTED_FG,
TIX_DITEM_DISABLED_FG
};
static void
Tix_WindowStyleSetTemplate(style, tmplPtr)
Tix_DItemStyle* style;
Tix_StyleTemplate * tmplPtr;
{
TixWindowStyle * stylePtr = (TixWindowStyle *)style;
int i;
if (tmplPtr->flags & TIX_DITEM_PADX) {
stylePtr->pad[0] = tmplPtr->pad[0];
}
if (tmplPtr->flags & TIX_DITEM_PADY) {
stylePtr->pad[1] = tmplPtr->pad[1];
}
for (i=0; i<4; i++) {
if (tmplPtr->flags & bg_flags[i]) {
if (stylePtr->colors[i].bg != NULL) {
Tk_FreeColor(stylePtr->colors[i].bg);
}
stylePtr->colors[i].bg = Tk_GetColor(
stylePtr->interp, stylePtr->tkwin,
Tk_NameOfColor(tmplPtr->colors[i].bg));
}
}
for (i=0; i<4; i++) {
if (tmplPtr->flags & fg_flags[i]) {
if (stylePtr->colors[i].fg != NULL) {
Tk_FreeColor(stylePtr->colors[i].fg);
}
stylePtr->colors[i].fg = Tk_GetColor(
stylePtr->interp, stylePtr->tkwin,
Tk_NameOfColor(tmplPtr->colors[i].fg));
}
}
Tix_WindowStyleConfigure(style, 0, 0, TIX_DONT_CALL_CONFIG);
}
/*----------------------------------------------------------------------
*
*
* Mapped Window List Handling
*
*
* Maintaining a list of mapped window items. Every host widgets should
* call these functions so that unwanted window items will not appear
* on the screen.
*
*
*----------------------------------------------------------------------
*/
void Tix_SetWindowItemSerial(lPtr, iPtr, serial)
Tix_LinkList * lPtr;
Tix_DItem * iPtr;
int serial;
{
TixWindowItem * itPtr = (TixWindowItem *)iPtr;
TixWindowItem * curr;
Tix_ListIterator li;
Tix_LinkListIteratorInit(&li);
itPtr->serial = serial;
for (Tix_LinkListStart(&mapWinListInfo, lPtr, &li);
!Tix_LinkListDone(&li);
Tix_LinkListNext (&mapWinListInfo, lPtr, &li)) {
curr = (TixWindowItem*)li.curr;
if (curr == itPtr) {
/* Don't want any duplication */
return;
}
}
Tix_LinkListAppend(&mapWinListInfo, lPtr, (char*)itPtr, 0);
}
/*
*----------------------------------------------------------------------
* UnmapWindows --
*
* We need to unmap all those windows that were displayed last time
* but should be now invisible.
* Otherwise we will have some unwanted child windows floating
* around.
*----------------------------------------------------------------------
*/
void Tix_UnmapInvisibleWindowItems(lPtr, serial)
Tix_LinkList * lPtr;
int serial;
{
TixWindowItem * curr;
Tix_ListIterator li;
Tix_LinkListIteratorInit(&li);
for (Tix_LinkListStart(&mapWinListInfo, lPtr, &li);
!Tix_LinkListDone(&li);
Tix_LinkListNext (&mapWinListInfo, lPtr, &li)) {
curr = (TixWindowItem*)li.curr;
if (curr->serial != serial) {
Tix_WindowItemUnmap(curr);
Tix_LinkListDelete(&mapWinListInfo, lPtr, &li);
}
}
}
void
Tix_WindowItemListRemove(lPtr, iPtr)
Tix_LinkList * lPtr;
Tix_DItem * iPtr;
{
TixWindowItem * curr;
Tix_ListIterator li;
Tix_LinkListIteratorInit(&li);
for (Tix_LinkListStart(&mapWinListInfo, lPtr, &li);
!Tix_LinkListDone(&li);
Tix_LinkListNext (&mapWinListInfo, lPtr, &li)) {
curr = (TixWindowItem*)li.curr;
if (curr == (TixWindowItem*)iPtr) {
Tix_WindowItemUnmap(curr);
Tix_LinkListDelete(&mapWinListInfo, lPtr, &li);
return;
}
}
}

80
generic/tixError.c Normal file
View File

@@ -0,0 +1,80 @@
/* $Id: tixError.c,v 1.2 2004/03/28 02:44:56 hobbs Exp $ */
/*
* tixError.c --
*
* Implements error handlers for Tix.
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#include <tixPort.h>
#include <tixInt.h>
int Tix_ArgcError(interp, argc, argv, prefixCount, message)
Tcl_Interp * interp;
int argc;
CONST84 char ** argv;
int prefixCount;
CONST84 char * message;
{
int i;
Tcl_AppendResult(interp, "wrong # of arguments, should be \"",(char*)NULL);
for (i=0; i<prefixCount && i<argc; i++) {
Tcl_AppendResult(interp, argv[i], " ", (char*)NULL);
}
Tcl_AppendResult(interp, message, "\".", (char*)NULL);
return TCL_ERROR;
}
int Tix_ValueMissingError(interp, spec)
Tcl_Interp * interp;
CONST84 char * spec;
{
Tcl_AppendResult(interp, "value for \"", spec,
"\" missing", (char*)NULL);
return TCL_ERROR;
}
/*----------------------------------------------------------------------
* Tix_UnknownPublicMethodError --
*
*
* ToDo: sort the list of commands.
*----------------------------------------------------------------------
*/
int Tix_UnknownPublicMethodError(interp, cPtr, widRec, method)
Tcl_Interp * interp;
TixClassRecord * cPtr;
CONST84 char * widRec;
CONST84 char * method;
{
int i;
CONST84 char * lead = "";
Tcl_AppendResult(interp, "unknown option \"", method,
"\": must be ",
(char*)NULL);
for (i=0; i<cPtr->nMethods-1; i++) {
Tcl_AppendResult(interp, lead, cPtr->methods[i], (char*)NULL);
lead = ", ";
}
if (cPtr->nMethods>1) {
Tcl_AppendResult(interp, " or ", (char*)NULL);
}
if (cPtr->nMethods>0) {
Tcl_AppendResult(interp, cPtr->methods[i], (char*)NULL);
}
return TCL_ERROR;
}

2114
generic/tixForm.c Normal file

File diff suppressed because it is too large Load Diff

143
generic/tixForm.h Normal file
View File

@@ -0,0 +1,143 @@
/* $Id: tixForm.h,v 1.2 2004/03/28 02:44:56 hobbs Exp $ */
/*
* tixForm.h --
*
* Declares the internal functions and data types for the Tix Form
* geometry manager.
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#ifndef _TIX_FORM_H
#define _TIX_FORM_H
#define SIDE0 0
#define SIDE1 1
#define NEXT_SIDE(x) (!x)
#define SIDEX 0
#define SIDEY 1
#define AXIS_X 0
#define AXIS_Y 1
#define OPPO_SIDE0 1
#define OPPO_SIDE1 2
#define OPPO_ALL 3
#define PINNED_SIDE0 4
#define PINNED_SIDE1 8
#define PINNED_ALL 12
#define ATT_NONE 0
#define ATT_GRID 1
#define ATT_OPPOSITE 2
#define ATT_PARALLEL 3
/*
* The following structures carry information about the client windows
*/
typedef union {
int grid;
struct _FormInfo * widget;
} Attachment;
typedef struct {
int pcnt; /* percentage anchor point */
int disp; /* displacement from the percentage anchor point*/
} Side;
typedef struct _FormInfo {
Tk_Window tkwin;
struct _MasterInfo* master; /* The master of this window */
struct _FormInfo * next;
int depend; /* used to detect circular dependency*/
/* These are specified by the user and set by the "tixForm" command
*/
Attachment att[2][2]; /* anchor of attachment */
int off[2][2]; /* offset of attachment */
char isDefault[2][2];/* Is this side a default attachment*/
char attType[2][2]; /* type of attachment
GRID or PIXEL*/
int pad[2][2]; /* value of padding */
/* These values are calculated by the PinnClient() functions
* and are used to calculated the required size of the master
* inside CalculateMasterGeometry(), as well as the positions
* of the clients inside ArrangeGeometry()
*/
Side side[2][2];
int sideFlags[2];
/* These values are used to place the clients into the clients
*/
int posn[2][2];
/* These things are for Spring'ing */
int spring[2][2];
struct _FormInfo * strWidget[2][2];
int springFail[2];
int fill[2];
} FormInfo;
/*
* The following structures carry information about the master windows
*/
typedef struct {
unsigned int isDeleted : 1;
unsigned int repackPending : 1;
} MasterFlags;
typedef struct _MasterInfo {
Tk_Window tkwin;
struct _FormInfo * client;
struct _FormInfo * client_tail;
int numClients;
int reqSize[2];
int numRequests; /* This is used to detect
* whether two geometry managers
* are used to manage the same
* master window
*/
int grids[2];
MasterFlags flags;
} MasterInfo;
/* tixFormMisc.c */
EXTERN int TixFm_Configure _ANSI_ARGS_((FormInfo *clientPtr,
Tk_Window topLevel,
Tcl_Interp* interp, int argc, CONST84 char **argv));
/* tixForm.c */
EXTERN FormInfo * TixFm_GetFormInfo _ANSI_ARGS_((Tk_Window tkwin,
int create));
EXTERN void TixFm_StructureProc _ANSI_ARGS_((ClientData clientData,
XEvent * eventPtr));
EXTERN void TixFm_AddToMaster _ANSI_ARGS_((MasterInfo *masterPtr,
FormInfo *clientPtr));
EXTERN void TixFm_DeleteMaster _ANSI_ARGS_((
MasterInfo *masterPtr));
EXTERN void TixFm_FreeMasterInfo _ANSI_ARGS_((
ClientData clientData));
EXTERN FormInfo * TixFm_FindClientPtrByName _ANSI_ARGS_((
Tcl_Interp * interp, CONST84 char * name,
Tk_Window topLevel));
EXTERN void TixFm_ForgetOneClient _ANSI_ARGS_((
FormInfo *clientPtr));
EXTERN void TixFm_Unlink _ANSI_ARGS_((FormInfo *clientPtr));
EXTERN void TixFm_UnlinkFromMaster _ANSI_ARGS_((
FormInfo *clientPtr));
#endif /* _TIX_FORM_H */

600
generic/tixFormMisc.c Normal file
View File

@@ -0,0 +1,600 @@
/* $Id: tixFormMisc.c,v 1.2 2004/03/28 02:44:56 hobbs Exp $ */
/*
* tixFormMisc.c --
*
* Implements the tixForm geometry manager, which has similar
* capability as the Motif Form geometry manager. Please
* refer to the documentation for the use of tixForm.
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#include <tixPort.h>
#include <tix.h>
#include <tixForm.h>
/*
* SubCommands of the tixForm command.
*/
TIX_DECLARE_SUBCMD(TixFm_Info);
static void AttachInfo _ANSI_ARGS_((Tcl_Interp * interp,
FormInfo * clientPtr, int axis, int which));
static int ConfigureAttachment _ANSI_ARGS_((FormInfo *clientPtr,
Tk_Window topLevel, Tcl_Interp* interp,
int axis, int which, CONST84 char *value));
static int ConfigureFill _ANSI_ARGS_((
FormInfo *clientPtr, Tk_Window tkwin,
Tcl_Interp* interp, CONST84 char *value));
static int ConfigurePadding _ANSI_ARGS_((
FormInfo *clientPtr, Tk_Window tkwin,
Tcl_Interp* interp, int axis, int which,
CONST84 char *value));
static int ConfigureSpring _ANSI_ARGS_((FormInfo *clientPtr,
Tk_Window topLevel, Tcl_Interp* interp,
int axis, int which, CONST84 char *value));
/*----------------------------------------------------------------------
* TixFm_Info --
*
* Return the information about the attachment of a client window
*----------------------------------------------------------------------
*/
int TixFm_Info(clientData, interp, argc, argv)
ClientData clientData; /* Main window associated with
* interpreter. */
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
Tk_Window topLevel = (Tk_Window) clientData;
FormInfo * clientPtr;
char buff[256];
int i,j;
static CONST84 char *sideNames[2][2] = {
{"-left", "-right"},
{"-top", "-bottom"}
};
static CONST84 char *padNames[2][2] = {
{"-padleft", "-padright"},
{"-padtop", "-padbottom"}
};
clientPtr = TixFm_FindClientPtrByName(interp, argv[0], topLevel);
if (clientPtr == NULL) {
return TCL_ERROR;
}
if (argc == 2) {
/* user wants some specific info
*/
for (i=0; i<2; i++) {
for (j=0; j<2; j++) {
/* Do you want to know attachment? */
if (strcmp(argv[1], sideNames[i][j]) == 0) {
AttachInfo(interp, clientPtr, i, j);
return TCL_OK;
}
/* Do you want to know padding? */
if (strcmp(argv[1], padNames[i][j]) == 0) {
sprintf(buff, "%d", clientPtr->pad[i][j]);
Tcl_AppendResult(interp, buff, NULL);
return TCL_OK;
}
}
}
Tcl_AppendResult(interp, "Unknown option \"", argv[1], "\"", NULL);
return TCL_ERROR;
}
/* Otherwise, give full info */
for (i=0; i<2; i++) {
for (j=0; j<2; j++) {
/* The information about attachment */
Tcl_AppendResult(interp, sideNames[i][j], " ", NULL);
AttachInfo(interp, clientPtr, i, j);
/* The information about padding */
Tcl_AppendResult(interp, padNames[i][j], " ", NULL);
sprintf(buff, "%d", clientPtr->pad[i][j]);
Tcl_AppendResult(interp, buff, " ", NULL);
}
}
return TCL_OK;
}
static void AttachInfo(interp, clientPtr, axis, which)
Tcl_Interp * interp;
FormInfo * clientPtr;
int axis;
int which;
{
char buff[256];
switch(clientPtr->attType[axis][which]) {
case ATT_NONE:
Tcl_AppendElement(interp, "none");
break;
case ATT_GRID:
sprintf(buff, "{%%%d %d}", clientPtr->att[axis][which].grid,
clientPtr->off[axis][which]);
Tcl_AppendResult(interp, buff, " ", NULL);
break;
case ATT_OPPOSITE:
sprintf(buff, "%d", clientPtr->off[axis][which]);
Tcl_AppendResult(interp, "{",
Tk_PathName(clientPtr->att[axis][which].widget->tkwin),
" ", buff, "} ", NULL);
break;
case ATT_PARALLEL:
sprintf(buff, "%d", clientPtr->off[axis][which]);
Tcl_AppendResult(interp, "{&",
Tk_PathName(clientPtr->att[axis][which].widget->tkwin),
" ", buff, "} ", NULL);
break;
}
}
/*----------------------------------------------------------------------
* Form Parameter Configuration
*
*----------------------------------------------------------------------
*/
static int ConfigureAttachment(clientPtr, topLevel, interp, axis, which, value)
FormInfo *clientPtr;
Tk_Window topLevel;
Tcl_Interp* interp;
int axis, which;
CONST84 char *value;
{
Tk_Window tkwin;
FormInfo * attWidget;
int code = TCL_OK;
int offset;
int grid;
int argc;
CONST84 char ** argv;
if (Tcl_SplitList(interp, value, &argc, &argv) != TCL_OK) {
return TCL_ERROR;
}
if (argc < 1 || argc > 2) {
Tcl_AppendResult(interp, "Malformed attachment value \"", value,
"\"", NULL);
code = TCL_ERROR;
goto done;
}
switch (argv[0][0]) {
case '#': /* Attached to grid */
case '%': /* Attached to percent (aka grid) */
if (Tcl_GetInt(interp, argv[0]+1, &grid) == TCL_ERROR) {
code = TCL_ERROR;
goto done;
}
clientPtr->attType[axis][which] = ATT_GRID;
clientPtr->att[axis][which].grid = grid;
break;
case '&': /* Attached to parallel widget */
tkwin = Tk_NameToWindow(interp, argv[0]+1, topLevel);
if (tkwin != NULL) {
if (Tk_IsTopLevel(tkwin)) {
Tcl_AppendResult(interp, "can't attach to \"", value,
"\": it's a top-level window", (char *) NULL);
code = TCL_ERROR;
goto done;
}
attWidget = TixFm_GetFormInfo(tkwin, 1);
TixFm_AddToMaster(clientPtr->master, attWidget);
clientPtr->attType[axis][which] = ATT_PARALLEL;
clientPtr->att[axis][which].widget = attWidget;
} else {
code = TCL_ERROR;
goto done;
}
break;
case '.': /* Attach to opposite widget */
tkwin = Tk_NameToWindow(interp, argv[0], topLevel);
if (tkwin != NULL) {
if (Tk_IsTopLevel(tkwin)) {
Tcl_AppendResult(interp, "can't attach to \"", value,
"\": it's a top-level window", (char *) NULL);
code = TCL_ERROR;
goto done;
}
attWidget = TixFm_GetFormInfo(tkwin, 1);
TixFm_AddToMaster(clientPtr->master, attWidget);
clientPtr->attType[axis][which] = ATT_OPPOSITE;
clientPtr->att[axis][which].widget = attWidget;
} else {
code = TCL_ERROR;
goto done;
}
break;
case 'n': /* none */
if (argc == 1 && strcmp(argv[0], "none") == 0) {
clientPtr->attType[axis][which] = ATT_NONE;
goto done;
} else {
Tcl_AppendResult(interp, "Malformed attachment value \"", value,
"\"", NULL);
code = TCL_ERROR;
goto done;
}
break;
default: /* Check if is attached to pixel */
/* If there is only one value, this can be the offset with implicit
* anchor point 0% or max_grid%
*/
if (argc != 1) {
Tcl_AppendResult(interp, "Malformed attachment value \"", value,
"\"", NULL);
code = TCL_ERROR;
goto done;
}
#if 1
if (Tk_GetPixels(interp, topLevel, argv[0], &offset) != TCL_OK) {
#else
if (Tcl_GetInt(interp, argv[0], &offset) == TCL_ERROR) {
#endif
code = TCL_ERROR;
goto done;
}
clientPtr->attType[axis][which] = ATT_GRID;
clientPtr->off [axis][which] = offset;
if (offset < 0 || (offset == 0 && strcmp(argv[0], "-0") ==0)) {
clientPtr->att[axis][which].grid = clientPtr->master->grids[axis];
} else {
clientPtr->att[axis][which].grid = 0;
}
goto done; /* We have already gotten both anchor and offset */
}
if (argc == 2) {
#if 1
if (Tk_GetPixels(interp, topLevel, argv[1], &offset) != TCL_OK) {
#else
if (Tcl_GetInt(interp, argv[1], &offset) == TCL_ERROR) {
#endif
code = TCL_ERROR;
goto done;
}
clientPtr->off[axis][which] = offset;
} else {
clientPtr->off[axis][which] = 0;
}
done:
if (argv) {
ckfree((char*) argv);
}
if (code == TCL_ERROR) {
clientPtr->attType[axis][which] = ATT_NONE;
clientPtr->off[axis][which] = 0;
}
return code;
}
static int ConfigurePadding(clientPtr, tkwin, interp, axis, which, value)
FormInfo *clientPtr;
Tk_Window tkwin;
Tcl_Interp* interp;
int axis, which;
CONST84 char *value;
{
int p_value;
if (Tk_GetPixels(interp, tkwin, value, &p_value) != TCL_OK) {
return TCL_ERROR;
}
else {
clientPtr->pad[axis][which] = p_value;
return TCL_OK;
}
}
static int ConfigureFill(clientPtr, tkwin, interp, value)
FormInfo *clientPtr;
Tk_Window tkwin;
Tcl_Interp* interp;
CONST84 char *value;
{
size_t len = strlen(value);
if (strncmp(value, "x", len) == 0) {
clientPtr->fill[AXIS_X] = 1;
clientPtr->fill[AXIS_Y] = 0;
}
else if (strncmp(value, "y", len) == 0) {
clientPtr->fill[AXIS_X] = 0;
clientPtr->fill[AXIS_Y] = 1;
}
else if (strncmp(value, "both", len) == 0) {
clientPtr->fill[AXIS_X] = 1;
clientPtr->fill[AXIS_Y] = 1;
}
else if (strncmp(value, "none", len) == 0) {
clientPtr->fill[AXIS_X] = 0;
clientPtr->fill[AXIS_Y] = 0;
}
else {
Tcl_AppendResult(interp, "bad fill style \"", value,
"\": must be none, x, y, or both", NULL);
return TCL_ERROR;
}
return TCL_OK;
}
static int ConfigureSpring(clientPtr, topLevel, interp, axis, which, value)
FormInfo *clientPtr;
Tk_Window topLevel;
Tcl_Interp* interp;
int axis, which;
CONST84 char *value;
{
int strength;
int i = axis, j = which;
if (Tcl_GetInt(interp, value, &strength) != TCL_OK) {
return TCL_ERROR;
}
clientPtr->spring[i][j] = strength;
if (clientPtr->attType[i][j] == ATT_OPPOSITE) {
FormInfo * oppo;
oppo = clientPtr->att[i][j].widget;
oppo->spring[i][!j] = strength;
if (strength != 0 && clientPtr->strWidget[i][j] == NULL) {
clientPtr->strWidget[i][j] = oppo;
if (oppo->strWidget[i][!j] != clientPtr) {
if (oppo->strWidget[i][!j] != NULL) {
oppo->strWidget[i][!j]->strWidget[i][j] = NULL;
oppo->strWidget[i][!j]->spring[i][j] = 0;
}
}
oppo->strWidget[i][!j] = clientPtr;
}
}
return TCL_OK;
}
int TixFm_Configure(clientPtr, topLevel, interp, argc, argv)
FormInfo *clientPtr;
Tk_Window topLevel;
Tcl_Interp* interp;
int argc;
CONST84 char **argv;
{
int i, flag, value;
for (i=0; i< argc; i+=2) {
flag = i;
value = i+1;
if (strcmp(argv[flag], "-in") == 0) {
/* Reset the parent of the widget
*/
Tcl_AppendResult(interp,
"\"-in \" must be the first option given to tixForm", NULL);
return TCL_ERROR;
} else if (strcmp(argv[flag], "-l") == 0) {
if (ConfigureAttachment(clientPtr, topLevel, interp,
0, 0, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-left") == 0) {
if (ConfigureAttachment(clientPtr, topLevel, interp,
0, 0, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-r") == 0) {
if (ConfigureAttachment(clientPtr, topLevel, interp,
0, 1, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-right") == 0) {
if (ConfigureAttachment(clientPtr, topLevel, interp,
0, 1, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-top") == 0) {
if (ConfigureAttachment(clientPtr, topLevel, interp,
1, 0, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-t") == 0) {
if (ConfigureAttachment(clientPtr, topLevel, interp,
1, 0, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-bottom") == 0) {
if (ConfigureAttachment(clientPtr, topLevel, interp,
1, 1, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-b") == 0) {
if (ConfigureAttachment(clientPtr, topLevel, interp,
1, 1, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-padx") == 0) {
if (ConfigurePadding(clientPtr, topLevel, interp,
0, 0, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
if (ConfigurePadding(clientPtr, topLevel, interp,
0, 1, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-pady") == 0) {
if (ConfigurePadding(clientPtr,topLevel,interp,
1, 0, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
if (ConfigurePadding(clientPtr, topLevel, interp,
1, 1, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-padleft") == 0) {
if (ConfigurePadding(clientPtr, topLevel, interp,
0, 0, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-lp") == 0) {
if (ConfigurePadding(clientPtr, topLevel, interp,
0, 0, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-padright")== 0){
if (ConfigurePadding(clientPtr, topLevel, interp,
0, 1, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-rp")== 0){
if (ConfigurePadding(clientPtr, topLevel, interp,
0, 1, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-padtop")== 0) {
if (ConfigurePadding(clientPtr, topLevel, interp,
1, 0, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-tp")== 0) {
if (ConfigurePadding(clientPtr, topLevel, interp,
1, 0, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag],"-padbottom")== 0){
if (ConfigurePadding(clientPtr, topLevel, interp,
1, 1, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag],"-bp")== 0){
if (ConfigurePadding(clientPtr, topLevel, interp,
1, 1, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-leftspring") == 0) {
if (ConfigureSpring(clientPtr, topLevel, interp,
0, 0, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-ls") == 0) {
if (ConfigureSpring(clientPtr, topLevel, interp,
0, 0, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-rightspring") == 0) {
if (ConfigureSpring(clientPtr, topLevel, interp,
0, 1, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-rs") == 0) {
if (ConfigureSpring(clientPtr, topLevel, interp,
0, 1, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-topspring") == 0) {
if (ConfigureSpring(clientPtr, topLevel, interp,
1, 0, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-ts") == 0) {
if (ConfigureSpring(clientPtr, topLevel, interp,
1, 0, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-bottomspring") == 0) {
if (ConfigureSpring(clientPtr, topLevel, interp,
1, 1, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-bs") == 0) {
if (ConfigureSpring(clientPtr, topLevel, interp,
1, 1, argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else if (strcmp(argv[flag], "-fill") == 0) {
if (ConfigureFill(clientPtr, topLevel, interp,
argv[value]) == TCL_ERROR) {
return TCL_ERROR;
}
} else {
Tcl_AppendResult(interp, "Wrong option \"",
argv[i], "\".", (char *) NULL);
return TCL_ERROR;
}
}
/*
* Clear the previously set default attachment if the opposide
* edge is attached.
*/
#if 0
/* (1) The X axis */
if ((clientPtr->attType[0][0] == ATT_DEFAULT_PIXEL)
&&(clientPtr->attType[0][1] != ATT_NONE)) {
clientPtr->attType[0][0] = ATT_NONE;
}
/* (2) The Y axis */
if ((clientPtr->attType[1][0] == ATT_DEFAULT_PIXEL)
&&(clientPtr->attType[1][1] != ATT_NONE)) {
clientPtr->attType[1][0] = ATT_NONE;
}
#endif
return TCL_OK;
}

360
generic/tixGeometry.c Normal file
View File

@@ -0,0 +1,360 @@
/* $Id: tixGeometry.c,v 1.4 2005/03/25 20:15:53 hobbs Exp $ */
/*
* tixGeometry.c --
*
* TCL bindings of TK Geometry Management functions.
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#include <tixPort.h>
#include <tixInt.h>
static Tcl_HashTable clientTable; /* hash table for geometry managers */
static void StructureProc _ANSI_ARGS_((ClientData clientData,
XEvent *eventPtr));
static void GeoReqProc _ANSI_ARGS_((ClientData clientData,
Tk_Window tkwin));
static void GeoLostSlaveProc _ANSI_ARGS_((ClientData clientData,
Tk_Window tkwin));
typedef struct ClientStruct {
Tcl_Interp * interp;
Tk_Window tkwin;
char * command;
unsigned isDeleted : 1;
} ClientStruct;
static Tk_GeomMgr geoType = {
"tixGeometry", /* name */
GeoReqProc, /* requestProc */
GeoLostSlaveProc, /* lostSlaveProc */
};
/*----------------------------------------------------------------------
*
* Geometry Management Hooks
*
*
*----------------------------------------------------------------------
*/
/*----------------------------------------------------------------------
*
* The following functions handles the geometry requests of the clients
*
*----------------------------------------------------------------------
*/
static void FreeClientStruct(clientData)
ClientData clientData;
{
ClientStruct * cnPtr = (ClientStruct *) clientData;
ckfree((char*)cnPtr->command);
ckfree((char*)cnPtr);
}
/* This function is called when the clients initiates a geometry
* request i.e., a button changes its text and now needs a larger
* width
*
*/
static void
GeoReqProc(clientData, tkwin)
ClientData clientData; /* Information about
* window that got new preferred
* geometry. */
Tk_Window tkwin; /* Other Tk-related information
* about the window. */
{
ClientStruct * cnPtr = (ClientStruct *) clientData;
int result;
if (cnPtr->isDeleted) {
return;
}
result = Tix_GlobalVarEval(cnPtr->interp, cnPtr->command, " -request ",
Tk_PathName(cnPtr->tkwin), (char*)NULL);
if (result != TCL_OK) {
Tcl_AddErrorInfo(cnPtr->interp,
"\n (geometry request command executed by tixManageGeometry)");
Tk_BackgroundError(cnPtr->interp);
}
}
/*
* This function is called when the clients is grabbed by another
* geometry manager. %% Should inform with a -lost call
*/
static void
GeoLostSlaveProc(clientData, tkwin)
ClientData clientData; /* Information about
* window that got new preferred
* geometry. */
Tk_Window tkwin; /* Other Tk-related information
* about the window. */
{
ClientStruct * cnPtr = (ClientStruct *) clientData;
Tcl_HashEntry * hashPtr;
int result;
if (cnPtr->isDeleted) {
return;
}
result = Tix_GlobalVarEval(cnPtr->interp, cnPtr->command, " -lostslave ",
Tk_PathName(cnPtr->tkwin), (char*)NULL);
if (result != TCL_OK) {
Tcl_AddErrorInfo(cnPtr->interp,
"\n (geometry request command executed by tixManageGeometry)");
Tk_BackgroundError(cnPtr->interp);
}
hashPtr = Tcl_FindHashEntry(&clientTable, (char *)tkwin);
if (hashPtr) {
Tcl_DeleteHashEntry(hashPtr);
}
cnPtr->isDeleted = 1;
Tk_EventuallyFree((ClientData) cnPtr, (Tix_FreeProc*)FreeClientStruct);
}
static void StructureProc(clientData, eventPtr)
ClientData clientData;
XEvent *eventPtr;
{
ClientStruct * cnPtr = (ClientStruct *) clientData;
Tcl_HashEntry * hashPtr;
if (eventPtr->type == DestroyNotify) {
if (cnPtr->isDeleted) {
return;
}
hashPtr = Tcl_FindHashEntry(&clientTable, (char *)cnPtr->tkwin);
if (hashPtr) {
Tcl_DeleteHashEntry(hashPtr);
}
cnPtr->isDeleted = 1;
Tk_EventuallyFree((ClientData) cnPtr, (Tix_FreeProc*)FreeClientStruct);
}
}
/*
*
* argv[1] = clientPathName
* argv[2] = managerCommand <-- can have arguments
*
* %% add possibility to delete a manager
*
*/
TIX_DEFINE_CMD(Tix_ManageGeometryCmd)
{
Tk_Window topLevel = (Tk_Window)clientData;
Tk_Window tkwin;
ClientStruct * cnPtr;
Tcl_HashEntry * hashPtr;
int isNew;
static int inited = 0;
if (argc!=3) {
return Tix_ArgcError(interp, argc, argv, 1, "pathname command");
}
if ((tkwin = Tk_NameToWindow(interp, argv[1], topLevel)) == NULL) {
return TCL_ERROR;
}
if (!inited) {
Tcl_InitHashTable(&clientTable, TCL_ONE_WORD_KEYS);
inited = 1;
}
hashPtr = Tcl_CreateHashEntry(&clientTable, (char *)tkwin, &isNew);
if (!isNew) {
cnPtr = (ClientStruct *) Tcl_GetHashValue(hashPtr);
ckfree(cnPtr->command);
cnPtr->command = tixStrDup(argv[2]);
} else {
cnPtr = (ClientStruct *) ckalloc(sizeof(ClientStruct));
cnPtr->tkwin = tkwin;
cnPtr->interp = interp;
cnPtr->command = tixStrDup(argv[2]);
cnPtr->isDeleted = 0;
Tcl_SetHashValue(hashPtr, cnPtr);
Tk_ManageGeometry(tkwin, &geoType, (ClientData)cnPtr);
Tk_CreateEventHandler(tkwin, StructureNotifyMask,
StructureProc, (ClientData)cnPtr);
}
return TCL_OK;
}
/*----------------------------------------------------------------------
*
* The following are TCL bindings for the TK geometry functions.
*
*----------------------------------------------------------------------
*/
/*
*
* argv[1] = clientPathName
* argv[2] = req width
* argv[3] = req height
*
*/
TIX_DEFINE_CMD(Tix_GeometryRequestCmd)
{
Tk_Window topLevel = (Tk_Window)clientData;
Tk_Window tkwin;
int reqWidth;
int reqHeight;
if (argc != 4) {
return Tix_ArgcError(interp, argc, argv, 1,
"pathname reqwidth reqheight");
}
if ((tkwin = Tk_NameToWindow(interp, argv[1], topLevel)) == NULL) {
return TCL_ERROR;
}
if (Tk_GetPixels(interp, tkwin, argv[2], &reqWidth) != TCL_OK) {
return TCL_ERROR;
}
if (Tk_GetPixels(interp, tkwin, argv[3], &reqHeight) != TCL_OK) {
return TCL_ERROR;
}
Tk_GeometryRequest(tkwin, reqWidth, reqHeight);
return TCL_OK;
}
/*
*
* argv[1] = clientPathName
* argv[2] = width
* argv[3] = height
* argv[4] = width
* argv[5] = height
*
*/
TIX_DEFINE_CMD(Tix_MoveResizeWindowCmd)
{
Tk_Window topLevel = (Tk_Window)clientData;
Tk_Window tkwin;
int x, y;
int width;
int height;
if (argc != 6) {
return Tix_ArgcError(interp, argc, argv, 1,
"pathname x y width height");
}
if ((tkwin = Tk_NameToWindow(interp, argv[1], topLevel)) == NULL) {
return TCL_ERROR;
}
if (Tk_GetPixels(interp, tkwin, argv[2], &x) != TCL_OK) {
return TCL_ERROR;
}
if (Tk_GetPixels(interp, tkwin, argv[3], &y) != TCL_OK) {
return TCL_ERROR;
}
if (Tk_GetPixels(interp, tkwin, argv[4], &width) != TCL_OK) {
return TCL_ERROR;
}
if (Tk_GetPixels(interp, tkwin, argv[5], &height) != TCL_OK) {
return TCL_ERROR;
}
Tk_MoveResizeWindow(tkwin, x, y, width, height);
return TCL_OK;
}
/*
*
* argv[1] = clientPathName
*
*/
TIX_DEFINE_CMD(Tix_MapWindowCmd)
{
Tk_Window topLevel = (Tk_Window)clientData;
Tk_Window tkwin;
if (argc != 2) {
return Tix_ArgcError(interp, argc, argv, 1, "pathname");
}
if ((tkwin = Tk_NameToWindow(interp, argv[1], topLevel)) == NULL) {
return TCL_ERROR;
}
Tk_MapWindow(tkwin);
return TCL_OK;
}
/*
* Tix_FlushXCmd -- calls XFlush()
* argv[1] = pathName
*
*/
TIX_DEFINE_CMD(Tix_FlushXCmd)
{
Tk_Window topLevel = (Tk_Window)clientData;
Tk_Window tkwin;
if (argc != 2) {
return Tix_ArgcError(interp, argc, argv, 1, "pathname");
}
if ((tkwin = Tk_NameToWindow(interp, argv[1], topLevel)) == NULL) {
return TCL_ERROR;
}
#if !defined(__WIN32__) && !defined(MAC_TCL) && !defined(MAC_OSX_TK) /* UNIX */
XFlush(Tk_Display(tkwin));
#endif
return TCL_OK;
}
/*
*
* argv[1] = clientPathName
*
*/
TIX_DEFINE_CMD(Tix_UnmapWindowCmd)
{
Tk_Window topLevel = (Tk_Window)clientData;
Tk_Window tkwin;
if (argc != 2) {
return Tix_ArgcError(interp, argc, argv, 1, "pathname");
}
if ((tkwin = Tk_NameToWindow(interp, argv[1], topLevel)) == NULL) {
return TCL_ERROR;
}
Tk_UnmapWindow(tkwin);
return TCL_OK;
}

912
generic/tixGrData.c Normal file
View File

@@ -0,0 +1,912 @@
/* $Id: tixGrData.c,v 1.2 2004/03/28 02:44:56 hobbs Exp $ */
/*
* tixGrData.c --
*
* This module manipulates the data structure for a Grid widget.
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#include <tixPort.h>
#include <tixInt.h>
#include <tixGrid.h>
/* need "(unsigned int)" to prevent sign-extension on 64-bit machines, and
* "(unsigned long)" to avoid an egcs warning
*/
#define FIX(X) ((char*)(unsigned long)(unsigned int)(X))
static int FindRowCol _ANSI_ARGS_((TixGridDataSet * dataSet,
int x, int y, TixGridRowCol * rowcol[2],
Tcl_HashEntry * hashPtrs[2]));
static TixGridRowCol * InitRowCol _ANSI_ARGS_((int index));
static int RowColMaxSize _ANSI_ARGS_((WidgetPtr wPtr,
int which, TixGridRowCol *rowCol,
TixGridSize * defSize));
static TixGridRowCol *
InitRowCol(index)
int index;
{
TixGridRowCol * rowCol = (TixGridRowCol *)ckalloc(sizeof(TixGridRowCol));
rowCol->dispIndex = index;
rowCol->size.sizeType = TIX_GR_DEFAULT;
rowCol->size.sizeValue = 0;
rowCol->size.charValue = 0;
rowCol->size.pad0 = 2;
rowCol->size.pad1 = 2;
rowCol->size.pixels = 0;
Tcl_InitHashTable(&rowCol->table, TCL_ONE_WORD_KEYS);
return rowCol;
}
/*----------------------------------------------------------------------
* TixGridDataSetInit --
*
* Create an instance of the TixGridDataSet data structure.
*
*----------------------------------------------------------------------
*/
TixGridDataSet *
TixGridDataSetInit()
{
TixGridDataSet * dataSet =(TixGridDataSet*)ckalloc(sizeof(TixGridDataSet));
Tcl_InitHashTable(&dataSet->index[0], TCL_ONE_WORD_KEYS);
Tcl_InitHashTable(&dataSet->index[1], TCL_ONE_WORD_KEYS);
dataSet->maxIdx[0] = -1;
dataSet->maxIdx[1] = -1;
return dataSet;
}
/*----------------------------------------------------------------------
* TixGridDataSetFree --
*
* Frees an instance of the TixGridDataSet data structure.
*
*----------------------------------------------------------------------
*/
void
TixGridDataSetFree(dataSet)
TixGridDataSet* dataSet;
{
Tcl_HashSearch hashSearch;
Tcl_HashEntry *hashPtr;
TixGridRowCol *rcPtr;
int i;
for (i=0; i<2; i++) {
for (hashPtr = Tcl_FirstHashEntry(&dataSet->index[i], &hashSearch);
hashPtr;
hashPtr = Tcl_NextHashEntry(&hashSearch)) {
rcPtr = (TixGridRowCol *)Tcl_GetHashValue(hashPtr);
if (rcPtr->table.numEntries > 0) {
fprintf(stderr, "Grid hash entry leaked: %d : %d\n", i,
rcPtr->dispIndex);
}
Tcl_DeleteHashTable(&rcPtr->table);
ckfree((char*)rcPtr);
}
}
Tcl_DeleteHashTable(&dataSet->index[0]);
Tcl_DeleteHashTable(&dataSet->index[1]);
ckfree((char*)dataSet);
}
/*----------------------------------------------------------------------
* TixGridDataFindEntry --
*
* Results:
* Return the element if it exists. Otherwise returns NULL.
*
* Side effects:
* None.
*----------------------------------------------------------------------
*/
char *
TixGridDataFindEntry(dataSet, x, y)
TixGridDataSet * dataSet;
int x;
int y;
{
TixGridRowCol *col, *row;
Tcl_HashEntry *hashPtr;
/* (1) Find the row and column */
if (!(hashPtr = Tcl_FindHashEntry(&dataSet->index[0], FIX(x)))) {
return NULL;
}
col = (TixGridRowCol *)Tcl_GetHashValue(hashPtr);
if (!(hashPtr = Tcl_FindHashEntry(&dataSet->index[1], FIX(y)))) {
return NULL;
}
row = (TixGridRowCol *)Tcl_GetHashValue(hashPtr);
/* (2) Find the entry */
if (row->table.numEntries < col->table.numEntries) {
if (!(hashPtr = Tcl_FindHashEntry(&row->table, (char*)col))) {
return NULL;
}
}
else {
if (!(hashPtr = Tcl_FindHashEntry(&col->table, (char*)row))) {
return NULL;
}
}
return (char *)Tcl_GetHashValue(hashPtr);
}
/*----------------------------------------------------------------------
* FindRowCol --
*
* Internal function: finds row and column info an entry.
*
* Results:
* Returns true if BOTH row and column exist. If so, the row and
* column info is returned in the rowcol.
*
* Side effects:
* None.
*----------------------------------------------------------------------
*/
static int
FindRowCol(dataSet, x, y, rowcol, hashPtrs)
TixGridDataSet * dataSet; /* The Grid dataset. */
int x, y; /* Location of the cell. */
TixGridRowCol * rowcol[2]; /* Returns information about the row/col. */
Tcl_HashEntry * hashPtrs[2];/* Returns hash table info about the row/col.*/
{
hashPtrs[0] = Tcl_FindHashEntry(&dataSet->index[0], FIX(x));
if (hashPtrs[0] != NULL) {
rowcol[0] = (TixGridRowCol *)Tcl_GetHashValue(hashPtrs[0]);
} else {
return 0;
}
hashPtrs[1] = Tcl_FindHashEntry(&dataSet->index[1], FIX(y));
if (hashPtrs[1] != NULL) {
rowcol[1] = (TixGridRowCol *)Tcl_GetHashValue(hashPtrs[1]);
} else {
return 0;
}
return 1;
}
/*----------------------------------------------------------------------
* TixGridDataCreateEntry --
*
* Find or create the entry at the specified index.
*
* Results:
* A handle to the entry.
*
* Side effects:
* A new entry is created if it is not already in the dataset.
*----------------------------------------------------------------------
*/
CONST84 char *
TixGridDataCreateEntry(dataSet, x, y, defaultEntry)
TixGridDataSet * dataSet;
int x;
int y;
CONST84 char * defaultEntry;
{
TixGridRowCol *rowcol[2];
Tcl_HashEntry *hashPtr;
int isNew, i, dispIndex[2];
dispIndex[0] = x;
dispIndex[1] = y;
for (i=0; i<2; i++) {
hashPtr = Tcl_CreateHashEntry(&dataSet->index[i],
FIX(dispIndex[i]), &isNew);
if (!isNew) {
rowcol[i] = (TixGridRowCol *)Tcl_GetHashValue(hashPtr);
} else {
rowcol[i] = InitRowCol(dispIndex[i]);
Tcl_SetHashValue(hashPtr, (char*)rowcol[i]);
if (dataSet->maxIdx[i] < dispIndex[i]) {
dataSet->maxIdx[i] = dispIndex[i];
}
}
}
hashPtr = Tcl_CreateHashEntry(&rowcol[0]->table,
(char*)rowcol[1], &isNew);
if (!isNew) {
return (char *) Tcl_GetHashValue(hashPtr);
}
else {
TixGrEntry *chPtr = (TixGrEntry *)defaultEntry;
Tcl_SetHashValue(hashPtr, (char*)chPtr);
chPtr->entryPtr[0] = hashPtr;
hashPtr = Tcl_CreateHashEntry(&rowcol[1]->table,
(char*)rowcol[0], &isNew);
Tcl_SetHashValue(hashPtr, (char*)defaultEntry);
chPtr->entryPtr[1] = hashPtr;
return defaultEntry;
}
}
/*----------------------------------------------------------------------
* TixGridDataDeleteEntry --
*
* Deletes the entry at the specified index.
*
* Results:
* True iff the entry existed and was deleted.
*
* Side effects:
* If there is an entry at the index, it is deleted.
*----------------------------------------------------------------------
*/
int
TixGridDataDeleteEntry(dataSet, x, y)
TixGridDataSet * dataSet; /* The Grid dataset. */
int x; /* Column number of the entry. */
int y; /* Row number of the entry. */
{
TixGridRowCol *rowcol[2];
Tcl_HashEntry *hashPtrs[2]; /* Hash entries of the row/col. */
Tcl_HashEntry *cx, *cy; /* Hash entries of the cell in the row/col. */
if (!FindRowCol(dataSet, x, y, rowcol, hashPtrs)) {
/*
* The row and/or the column do not exist.
*/
return 0;
}
cx = Tcl_FindHashEntry(&rowcol[0]->table, (char*)rowcol[1]);
cy = Tcl_FindHashEntry(&rowcol[1]->table, (char*)rowcol[0]);
if (cx == NULL && cy == NULL) {
return 0;
}
else if (cx != NULL && cy != NULL) {
Tcl_DeleteHashEntry(cx);
Tcl_DeleteHashEntry(cy);
}
else {
panic("Inconsistent grid dataset: (%d,%d) : %x %x", x, y, cx, cy);
}
return 1;
/*
* ToDo: trim down the hash table.
*/
}
/* return value: has the size of the grid changed as a result of sorting */
int
TixGridDataUpdateSort(dataSet, axis, start, end, items)
TixGridDataSet * dataSet;
int axis;
int start;
int end;
Tix_GrSortItem *items;
{
TixGridRowCol **ptr;
Tcl_HashEntry *hashPtr;
int numItems = end - start + 1;
int i, k, max;
if (numItems <= 0) {
return 0;
}
ptr = (TixGridRowCol **)ckalloc(numItems * sizeof(TixGridRowCol *));
for (k=0,i=start; i<=end; i++,k++) {
if (!(hashPtr = Tcl_FindHashEntry(&dataSet->index[axis], FIX(i)))) {
/*
* This row/col doesn't exist
*/
ptr[k] = NULL;
} else {
ptr[k] = (TixGridRowCol *)Tcl_GetHashValue(hashPtr);
Tcl_DeleteHashEntry(hashPtr);
}
}
max = start;
for (k=0,i=start; i<=end; i++,k++) {
int pos, isNew;
pos = items[k].index - start;
if (ptr[pos] != NULL) {
hashPtr = Tcl_CreateHashEntry(&dataSet->index[axis], FIX(i),
&isNew);
Tcl_SetHashValue(hashPtr, (char*)ptr[pos]);
ptr[pos]->dispIndex = i;
max = i;
}
}
ckfree((char*)ptr);
if (end+1 >= dataSet->maxIdx[axis]) {
if (dataSet->maxIdx[axis] != max+1) {
dataSet->maxIdx[axis] = max+1;
return 1; /* size changed */
}
}
return 0; /* size not changed */
}
static int
RowColMaxSize(wPtr, which, rowCol, defSize)
WidgetPtr wPtr;
int which; /* 0=cols, 1=rows */
TixGridRowCol *rowCol;
TixGridSize * defSize;
{
Tcl_HashSearch hashSearch;
Tcl_HashEntry *hashPtr;
TixGrEntry * chPtr;
int maxSize = 1;
if (rowCol->table.numEntries == 0) {
return defSize->pixels;
}
for (hashPtr = Tcl_FirstHashEntry(&rowCol->table, &hashSearch);
hashPtr;
hashPtr = Tcl_NextHashEntry(&hashSearch)) {
chPtr = (TixGrEntry *)Tcl_GetHashValue(hashPtr);
if (maxSize < chPtr->iPtr->base.size[which]) {
maxSize = chPtr->iPtr->base.size[which];
}
}
return maxSize;
}
/*
*----------------------------------------------------------------------
* TixGridDataGetRowColSize --
*
* Returns width of a column or height of a row.
*
* Results:
* The width or height.
*
* Side effects:
* None.
*----------------------------------------------------------------------
*/
int
TixGridDataGetRowColSize(wPtr, dataSet, which, index, defSize, pad0, pad1)
WidgetPtr wPtr; /* Info about Grid widget */
TixGridDataSet * dataSet; /* Dataset of the Grid */
int which; /* 0=cols, 1=rows */
int index; /* Column or row number */
TixGridSize * defSize; /* The default size for the grid cells */
int *pad0; /* Holds return value of horizontal padding. */
int *pad1; /* Holds return value of vertical padding. */
{
TixGridRowCol *rowCol;
Tcl_HashEntry *hashPtr;
int size;
if (!(hashPtr = Tcl_FindHashEntry(&dataSet->index[which], FIX(index)))) {
size = defSize->pixels;
*pad0 = defSize->pad0;
*pad1 = defSize->pad1;
}
else {
rowCol = (TixGridRowCol *)Tcl_GetHashValue(hashPtr);
switch (rowCol->size.sizeType) {
case TIX_GR_AUTO:
size = RowColMaxSize(wPtr, which, rowCol, defSize);
*pad0 = rowCol->size.pad0;
*pad1 = rowCol->size.pad1;
break;
case TIX_GR_DEFINED_PIXEL:
size = rowCol->size.sizeValue;
*pad0 = rowCol->size.pad0;
*pad1 = rowCol->size.pad1;
break;
case TIX_GR_DEFINED_CHAR:
size = (int)(rowCol->size.charValue * wPtr->fontSize[which]);
*pad0 = rowCol->size.pad0;
*pad1 = rowCol->size.pad1;
break;
case TIX_GR_DEFAULT:
default: /* some error ?? */
if (defSize->sizeType == TIX_GR_AUTO) {
size = RowColMaxSize(wPtr, which, rowCol, defSize);
} else {
size = defSize->pixels;
}
*pad0 = defSize->pad0;
*pad1 = defSize->pad1;
}
}
return size;
}
int
TixGridDataGetIndex(interp, wPtr, xStr, yStr, xPtr, yPtr)
Tcl_Interp * interp;
WidgetPtr wPtr;
CONST84 char * xStr;
CONST84 char * yStr;
int * xPtr;
int * yPtr;
{
CONST84 char * str[2];
int * ptr[2];
int i;
str[0] = xStr;
str[1] = yStr;
ptr[0] = xPtr;
ptr[1] = yPtr;
for (i=0; i<2; i++) {
if (str[i] == NULL) { /* ignore this index */
continue;
}
if (strcmp(str[i], "max") == 0) {
*ptr[i] = wPtr->dataSet->maxIdx[i];
if (*ptr[i] < wPtr->hdrSize[i]) {
*ptr[i] = wPtr->hdrSize[i];
}
}
else if (strcmp(str[i], "end") == 0) {
*ptr[i] = wPtr->dataSet->maxIdx[i] + 1;
if (*ptr[i] < wPtr->hdrSize[i]) {
*ptr[i] = wPtr->hdrSize[i];
}
} else {
if (Tcl_GetInt(interp, str[i], ptr[i]) != TCL_OK) {
return TCL_ERROR;
}
}
if (*ptr[i] < 0) {
*ptr[i] = 0;
}
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
* TixGridDataConfigRowColSize --
*
* Configure width of column or height of rows.
*
* Results:
* Standard Tcl result.
*
* Side effects:
* The column/rows size will be changed in an idle event.
*----------------------------------------------------------------------
*/
int
TixGridDataConfigRowColSize(interp, wPtr, dataSet, which, index, argc, argv,
argcErrorMsg, changed_ret)
Tcl_Interp * interp;
WidgetPtr wPtr;
TixGridDataSet * dataSet;
int which; /* 0=cols, 1=rows */
int index;
int argc;
CONST84 char ** argv;
CONST84 char * argcErrorMsg;
int *changed_ret; /* Returns whether size has been changed. */
{
TixGridRowCol *rowCol;
Tcl_HashEntry *hashPtr;
int isNew, code;
hashPtr = Tcl_CreateHashEntry(&dataSet->index[which], FIX(index), &isNew);
if (!isNew) {
rowCol = (TixGridRowCol *)Tcl_GetHashValue(hashPtr);
} else {
rowCol = InitRowCol(index);
Tcl_SetHashValue(hashPtr, (char*)rowCol);
if (dataSet->maxIdx[which] < index) {
dataSet->maxIdx[which] = index;
}
}
code = Tix_GrConfigSize(interp, wPtr, argc, argv, &rowCol->size,
argcErrorMsg, changed_ret);
if (changed_ret) {
*changed_ret |= isNew;
}
return code;
}
/*
*----------------------------------------------------------------------
* TixGridDataGetGridSize --
*
* Returns the number of rows and columns of the grid.
*
* Results:
* None.
*
* Side effects:
* None.
*----------------------------------------------------------------------
*/
/*
* ToDo: maintain numCol and numRow info while adding entries.
*/
void
TixGridDataGetGridSize(dataSet, numCol_ret, numRow_ret)
TixGridDataSet * dataSet;
int *numCol_ret;
int *numRow_ret;
{
int maxSize[2], i;
Tcl_HashEntry *hashPtr;
Tcl_HashSearch hashSearch;
TixGridRowCol * rowCol;
maxSize[0] = 1;
maxSize[1] = 1;
if (dataSet->index[0].numEntries == 0 || dataSet->index[1].numEntries==0) {
goto done;
}
for (i=0; i<2; i++) {
for (hashPtr = Tcl_FirstHashEntry(&dataSet->index[i], &hashSearch);
hashPtr;
hashPtr = Tcl_NextHashEntry(&hashSearch)) {
rowCol = (TixGridRowCol *)Tcl_GetHashValue(hashPtr);
if (maxSize[i] < rowCol->dispIndex+1) {
maxSize[i] = rowCol->dispIndex+1;
}
}
}
done:
if (numCol_ret) {
*numCol_ret = maxSize[0];
}
if (numRow_ret) {
*numRow_ret = maxSize[1];
}
}
/*
* the following four functions return true if done -- no more rows or cells
* are left to traverse
*/
int
TixGrDataFirstRow(dataSet, rowSearchPtr)
TixGridDataSet* dataSet;
Tix_GrDataRowSearch * rowSearchPtr;
{
rowSearchPtr->hashPtr = Tcl_FirstHashEntry(&dataSet->index[0],
&rowSearchPtr->hashSearch);
if (rowSearchPtr->hashPtr != NULL) {
rowSearchPtr->row = (TixGridRowCol *)Tcl_GetHashValue(
rowSearchPtr->hashPtr);
return 0;
} else {
rowSearchPtr->row = NULL;
return 1;
}
}
int
TixGrDataNextRow(rowSearchPtr)
Tix_GrDataRowSearch * rowSearchPtr;
{
rowSearchPtr->hashPtr = Tcl_NextHashEntry(&rowSearchPtr->hashSearch);
if (rowSearchPtr->hashPtr != NULL) {
rowSearchPtr->row = (TixGridRowCol *)Tcl_GetHashValue(
rowSearchPtr->hashPtr);
return 0;
} else {
rowSearchPtr->row = NULL;
return 1;
}
}
int
TixGrDataFirstCell(rowSearchPtr, cellSearchPtr)
Tix_GrDataRowSearch * rowSearchPtr;
Tix_GrDataCellSearch * cellSearchPtr;
{
cellSearchPtr->hashPtr = Tcl_FirstHashEntry(&rowSearchPtr->row->table,
&cellSearchPtr->hashSearch);
if (cellSearchPtr->hashPtr != NULL) {
cellSearchPtr->data = (char *)Tcl_GetHashValue(
cellSearchPtr->hashPtr);
return 0;
} else {
cellSearchPtr->data = NULL;
return 1;
}
}
int
TixGrDataNextCell(cellSearchPtr)
Tix_GrDataCellSearch * cellSearchPtr;
{
cellSearchPtr->hashPtr = Tcl_NextHashEntry(&cellSearchPtr->hashSearch);
if (cellSearchPtr->hashPtr != NULL) {
cellSearchPtr->data = (char *)Tcl_GetHashValue(
cellSearchPtr->hashPtr);
return 0;
} else {
cellSearchPtr->data = NULL;
return 1;
}
}
/*----------------------------------------------------------------------
* TixGridDataDeleteSearchedEntry --
*
* Deletes an entry returned by one of the search functions.
*
* Results:
* None.
*
* Side effects:
* If there is an entry at the index, it is deleted.
*----------------------------------------------------------------------
*/
void
TixGridDataDeleteSearchedEntry(cellSearchPtr)
Tix_GrDataCellSearch * cellSearchPtr;
{
TixGrEntry * chPtr = (TixGrEntry *)cellSearchPtr->data;
Tcl_DeleteHashEntry(chPtr->entryPtr[0]);
Tcl_DeleteHashEntry(chPtr->entryPtr[1]);
}
/*
*----------------------------------------------------------------------
* TixGridDataDeleteRange --
*
* Deletes the rows (columns) at the given range.
*
* Results:
* None.
*
* Side effects:
* The given rows (columns) are deleted.
*----------------------------------------------------------------------
*/
void
TixGridDataDeleteRange(wPtr, dataSet, which, from, to)
WidgetPtr wPtr; /* Info about the grid widget. */
TixGridDataSet * dataSet; /* Dataset of the Grid */
int which; /* 0=cols, 1=rows */
int from; /* Starting column/row. */
int to; /* Ending column/row (inclusive). */
{
int tmp, i, other, deleted = 0;
if (from < 0 ) {
from = 0;
}
if (to < 0 ) {
to = 0;
}
if (from > to) {
tmp = to;
to = from;
from = tmp;
}
if (which == 0) {
other = 1;
} else {
other = 0;
}
for (i=from; i<=to; i++) {
Tcl_HashEntry *hashPtr, *hp, *toDel;
TixGridRowCol *rcPtr, *rcp;
Tcl_HashSearch hashSearch;
hashPtr = Tcl_FindHashEntry(&dataSet->index[which], FIX(i));
if (hashPtr != NULL) {
rcPtr = (TixGridRowCol *)Tcl_GetHashValue(hashPtr);
for (hp = Tcl_FirstHashEntry(&dataSet->index[other], &hashSearch);
hp;
hp = Tcl_NextHashEntry(&hashSearch)) {
rcp = (TixGridRowCol *)Tcl_GetHashValue(hp);
toDel = Tcl_FindHashEntry(&rcp->table, (char*)rcPtr);
if (toDel != NULL) {
TixGrEntry * chPtr;
chPtr = (TixGrEntry *)Tcl_GetHashValue(toDel);
if (chPtr) {
deleted = 1;
Tix_GrFreeElem(chPtr);
}
Tcl_DeleteHashEntry(toDel);
}
}
Tcl_DeleteHashEntry(hashPtr);
Tcl_DeleteHashTable(&rcPtr->table);
ckfree((char*)rcPtr);
}
}
if (deleted) {
Tix_GrDoWhenIdle(wPtr, TIX_GR_RESIZE);
}
}
/*
*----------------------------------------------------------------------
* TixGridDataMoveRange --
*
* Moves a range of row (columns) by a given offset. E.g. move 2-4 by 2
* changes the rows 2,3,4 to 4,5,6.
*
* Results:
* None.
*
* Side effects:
* Rows (columns) at locations where the given rows will be moved
* to are deleted.
*----------------------------------------------------------------------
*/
void
TixGridDataMoveRange(wPtr, dataSet, which, from, to, by)
WidgetPtr wPtr; /* Info about the grid widget. */
TixGridDataSet * dataSet; /* Dataset of the Grid */
int which; /* 0=cols, 1=rows */
int from; /* Starting column/row. */
int to; /* Ending column/row (inclusive). */
int by; /* The distance of the move. */
{
int tmp, i, s, e, incr;
int df, dt; /* Rows inside this range will be deleted
* before the given rows are moved. */
if (by == 0) {
return;
}
if (from < 0 ) {
from = 0;
}
if (to < 0 ) {
to = 0;
}
if (from > to) {
tmp = to;
to = from;
from = tmp;
}
if ((from + by) < 0) {
/*
* Delete the leading rows that will be moved beyond the top of grid.
*/
int n; /* Number of rows to delete. */
n = - (from + by);
if (n > (to - from + 1)) {
n = to - from + 1;
}
TixGridDataDeleteRange(wPtr, dataSet, which, from, (from+n-1));
from = from + n;
if (from > to) {
/*
* All the rows have been deleted.
*/
return;
}
}
/*
* Delete rows at locations where the given rows will be moved to.
*/
df = from + by;
dt = to + by;
if (by > 0) {
if (df <= to) {
df = to + 1;
}
} else {
if (dt >= from) {
dt = from - 1;
}
}
TixGridDataDeleteRange(wPtr, dataSet, which, df, dt);
/*
* Rename the rows.
*/
if (by > 0) {
s = to;
e = from-1;
incr = -1;
} else {
s = from;
e = to+1;
incr = 1;
}
for (i=s; i!=e; i+=incr) {
Tcl_HashEntry *hashPtr;
TixGridRowCol *rcPtr;
int isNew;
hashPtr = Tcl_FindHashEntry(&dataSet->index[which], FIX(i));
if (hashPtr != NULL) {
rcPtr = (TixGridRowCol *)Tcl_GetHashValue(hashPtr);
rcPtr->dispIndex = i+by;
Tcl_DeleteHashEntry(hashPtr);
hashPtr = Tcl_CreateHashEntry(&dataSet->index[which], FIX(i+by),
&isNew);
Tcl_SetHashValue(hashPtr, (char*)rcPtr);
}
}
}

88
generic/tixGrData.h Normal file
View File

@@ -0,0 +1,88 @@
/* $Id: tixGrData.h,v 1.1.1.1 2000/05/17 11:08:42 idiscovery Exp $ */
/*
* tixGData.h --
*
* Defines portable data structure for tixGrid.
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#ifndef _TIX_GRID_DATA_H_
#define _TIX_GRID_DATA_H_
/*
* Data structure that stored the cells in a Grid widget. It is optimized
* for column/row insertion and deletion.
*
* - A grid is divideded into a set of rows and columns. Each row and column
* is divided into a set of cells.
*
* - The following discusses the structure of a row. The structure of a
* column is the reverse of a row.
*
* Row y is stored in the hash table TixGridDataSet.index[1] with
* the index y. Hence, to search for row y, we use the FindHashEntry
* operation:
*
* row_y = TixGridDataSet.index[1].FindHashEntry(y);
*
* To locate a cell (x,y), we can first find the row y, and then
* locate the cell at column x of this row. Note that the cell is
* *not* indexed by its column position (y), but rather by the hash
* table of the column y. The following example illustrates how cell
* (x,y) can be searched:
*
* row_y = TixGridDataSet.index[1].FindHashEntry(y);
* col_x = TixGridDataSet.index[0].FindHashEntry(x);
*
* cell_xy = row_x.list.FindHashEntry(&col_x);
*
* The advantage of this arrangement is it is very efficient to
* insert a row into into the grid -- we just have to fix the
* indices of the rows table. For example, if, after the insertion,
* row_y is now moved to the row y1, we change its index from y to
* y1. In general, an insertion operation takes log(n) time in a
* grid that contains n items.
*
*/
typedef struct TixGridDataSet {
Tcl_HashTable index[2]; /* the row and column indices */
/* index[0] holds the columns
* (horizontal index)
*/
int maxIdx[2]; /* the max row/col, or {-1,-1}
* if there are no rows/col
*/
} TixGridDataSet;
#define TIX_GR_AUTO 0
#define TIX_GR_DEFAULT 1
#define TIX_GR_DEFINED_PIXEL 2
#define TIX_GR_DEFINED_CHAR 3
typedef struct TixGridSize {
int sizeType;
int sizeValue; /* width or height */
int pixels;
int pad0, pad1;
double charValue;
} TixGridSize;
typedef struct TixGridRowCol {
/* private: */
Tcl_HashTable table;
/* public: */
int dispIndex; /* the row or column in which
* this TixGridRowCol is displayed */
TixGridSize size;
} TixGridRowCol;
#endif

793
generic/tixGrFmt.c Normal file
View File

@@ -0,0 +1,793 @@
/* $Id: tixGrFmt.c,v 1.3 2004/03/28 02:44:56 hobbs Exp $ */
/*
* tixGrFmt.c --
*
* This module handles the formatting of the elements inside a Grid
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#include <tixPort.h>
#include <tixInt.h>
#include <tixDef.h>
#include <tixGrid.h>
typedef struct FormatStruct {
int x1, y1, x2, y2;
} FormatStruct;
typedef struct BorderFmtStruct {
int x1, y1, x2, y2;
Tk_3DBorder border;
Tk_3DBorder selectBorder; /* the border color color */
int borderWidth; /* Width of 3-D borders. */
int relief; /* Indicates whether window as a whole is
* raised, sunken, or flat. */
int xon, xoff;
int yon, yoff;
int filled;
} BorderFmtStruct;
typedef struct GridFmtStruct {
int x1, y1, x2, y2;
Tk_3DBorder border; /* the border color color */
Tk_3DBorder selectBorder; /* the border color color */
Tk_3DBorder bgBorder; /* the background color */
int borderWidth; /* Width of 3-D borders. */
int relief; /* Indicates whether window as a whole is
* raised, sunken, or flat. */
int xon, xoff;
int yon, yoff;
Tk_Anchor anchor;
int filled;
} GridFmtStruct;
static TIX_DECLARE_SUBCMD(Tix_GrFormatBorder);
static TIX_DECLARE_SUBCMD(Tix_GrFormatGrid);
EXTERN TIX_DECLARE_SUBCMD(Tix_GrFormat);
typedef int CFG_TYPE;
static int Tix_GrSaveColor _ANSI_ARGS_((WidgetPtr wPtr,
CFG_TYPE type, void * ptr));
static void GetBlockPosn _ANSI_ARGS_((WidgetPtr wPtr, int x1,
int y1, int x2, int y2, int * bx1, int * by1,
int * bx2, int * by2));
static void GetRenderPosn _ANSI_ARGS_((WidgetPtr wPtr,
int bx1, int by1, int bx2, int by2, int * rx1,
int * ry1, int * rx2, int * ry2));
static void Tix_GrFillCells _ANSI_ARGS_((WidgetPtr wPtr,
Tk_3DBorder border, Tk_3DBorder selectBorder,
int bx1, int by1, int bx2, int by2,
int borderWidth, int relief, int filled,
int bw[2][2]));
static int GetInfo _ANSI_ARGS_((WidgetPtr wPtr,
Tcl_Interp *interp, int argc, CONST84 char **argv,
FormatStruct * infoPtr,
Tk_ConfigSpec * configSpecs));
#define DEF_GRID_ANCHOR "se"
#define DEF_GRID_BORDER_XOFF "0"
#define DEF_GRID_BORDER_XON "1"
#define DEF_GRID_BORDER_YOFF "0"
#define DEF_GRID_BORDER_YON "1"
#define DEF_GRID_GRIDLINE_XOFF "0"
#define DEF_GRID_GRIDLINE_XON "1"
#define DEF_GRID_GRIDLINE_YOFF "0"
#define DEF_GRID_GRIDLINE_YON "1"
#define DEF_GRID_FILLED "0"
#define DEF_GRID_BORDER_COLOR NORMAL_BG
#define DEF_GRID_BORDER_MONO WHITE
#define DEF_GRID_GRIDLINE_COLOR BLACK
#define DEF_GRID_GRIDLINE_MONO BLACK
static Tk_ConfigSpec borderConfigSpecs[] = {
{TK_CONFIG_BORDER, "-background", "background", "Background",
DEF_GRID_BG_COLOR, Tk_Offset(BorderFmtStruct, border),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_BORDER, "-background", "background", "Background",
DEF_GRID_BG_MONO, Tk_Offset(BorderFmtStruct, border),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,
(char *) NULL, 0, 0},
{TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
(char *) NULL, 0, 0},
{TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
DEF_GRID_BORDER_WIDTH, Tk_Offset(BorderFmtStruct, borderWidth), 0},
{TK_CONFIG_BOOLEAN, "-filled", "filled", "Filled",
DEF_GRID_FILLED, Tk_Offset(BorderFmtStruct, filled), 0},
{TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
DEF_GRID_RELIEF, Tk_Offset(BorderFmtStruct, relief), 0},
{TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
DEF_GRID_SELECT_BG_COLOR, Tk_Offset(BorderFmtStruct, selectBorder),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
DEF_GRID_SELECT_BG_MONO, Tk_Offset(BorderFmtStruct, selectBorder),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_INT, "-xoff", "xoff", "Xoff",
DEF_GRID_BORDER_XOFF, Tk_Offset(BorderFmtStruct, xoff), 0},
{TK_CONFIG_INT, "-xon", "xon", "Xon",
DEF_GRID_BORDER_XON, Tk_Offset(BorderFmtStruct, xon), 0},
{TK_CONFIG_INT, "-yoff", "yoff", "Yoff",
DEF_GRID_BORDER_YOFF, Tk_Offset(BorderFmtStruct, yoff), 0},
{TK_CONFIG_INT, "-yon", "yon", "Yon",
DEF_GRID_BORDER_YON, Tk_Offset(BorderFmtStruct, yon), 0},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, 0}
};
static Tk_ConfigSpec gridConfigSpecs[] = {
{TK_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor",
DEF_GRID_ANCHOR, Tk_Offset(GridFmtStruct, anchor), 0},
{TK_CONFIG_BORDER, "-background", "background", "Background",
DEF_GRID_BG_COLOR, Tk_Offset(GridFmtStruct, bgBorder),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_BORDER, "-background", "background", "Background",
DEF_GRID_BG_COLOR, Tk_Offset(GridFmtStruct, bgBorder),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_BORDER, "-bordercolor", "borderColor", "BorderColor",
DEF_GRID_GRIDLINE_COLOR, Tk_Offset(GridFmtStruct, border),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_BORDER, "-bordercolor", "borderColor", "BorderColor",
DEF_GRID_GRIDLINE_MONO, Tk_Offset(GridFmtStruct, border),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,
(char *) NULL, 0, 0},
{TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
(char *) NULL, 0, 0},
{TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
DEF_GRID_BORDER_WIDTH, Tk_Offset(GridFmtStruct, borderWidth), 0},
{TK_CONFIG_BOOLEAN, "-filled", "filled", "Filled",
DEF_GRID_FILLED, Tk_Offset(GridFmtStruct, filled), 0},
{TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
DEF_GRID_RELIEF, Tk_Offset(GridFmtStruct, relief), 0},
{TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
DEF_GRID_SELECT_BG_COLOR, Tk_Offset(GridFmtStruct, selectBorder),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
DEF_GRID_SELECT_BG_MONO, Tk_Offset(GridFmtStruct, selectBorder),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_INT, "-xoff", "xoff", "Xoff",
DEF_GRID_GRIDLINE_XOFF, Tk_Offset(GridFmtStruct, xoff), 0},
{TK_CONFIG_INT, "-xon", "xon", "Xon",
DEF_GRID_GRIDLINE_XON, Tk_Offset(GridFmtStruct, xon), 0},
{TK_CONFIG_INT, "-yoff", "yoff", "Yoff",
DEF_GRID_GRIDLINE_YOFF, Tk_Offset(GridFmtStruct, yoff), 0},
{TK_CONFIG_INT, "-yon", "yon", "Yon",
DEF_GRID_GRIDLINE_YON, Tk_Offset(GridFmtStruct, yon), 0},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, 0}
};
int
Tix_GrFormat(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
static Tix_SubCmdInfo subCmdInfo[] = {
{TIX_DEFAULT_LEN, "border", 4, TIX_VAR_ARGS, Tix_GrFormatBorder,
"x1 y1 x2 y2 ?option value ...?"},
{TIX_DEFAULT_LEN, "grid", 4, TIX_VAR_ARGS, Tix_GrFormatGrid,
"x1 y1 x2 y2 ?option value ...?"},
};
static Tix_CmdInfo cmdInfo = {
Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "?option? ?arg ...?",
};
WidgetPtr wPtr = (WidgetPtr) clientData;
if (wPtr->renderInfo == NULL) {
Tcl_AppendResult(interp, "the \"format\" command can only be called ",
"by the -formatcmd handler of the tixGrid widget", NULL);
return TCL_ERROR;
}
return Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData,
interp, argc+1, argv-1);
}
static int
GetInfo(wPtr, interp, argc, argv, infoPtr, configSpecs)
WidgetPtr wPtr;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
FormatStruct * infoPtr;
Tk_ConfigSpec * configSpecs;
{
int temp;
if (argc < 4) {
return Tix_ArgcError(interp, argc+2, argv-2, 2, "x1 y1 x2 y2 ...");
}
if (Tcl_GetInt(interp, argv[0], &infoPtr->x1) != TCL_OK) {
return TCL_ERROR;
}
if (Tcl_GetInt(interp, argv[1], &infoPtr->y1) != TCL_OK) {
return TCL_ERROR;
}
if (Tcl_GetInt(interp, argv[2], &infoPtr->x2) != TCL_OK) {
return TCL_ERROR;
}
if (Tcl_GetInt(interp, argv[3], &infoPtr->y2) != TCL_OK) {
return TCL_ERROR;
}
if (Tk_ConfigureWidget(interp, wPtr->dispData.tkwin, configSpecs,
argc-4, argv+4, (char *)infoPtr, 0) != TCL_OK) {
return TCL_ERROR;
}
if (infoPtr->x1 > infoPtr->x2) {
temp = infoPtr->x1;
infoPtr->x1 = infoPtr->x2;
infoPtr->x2 = temp;
}
if (infoPtr->y1 > infoPtr->y2) {
temp = infoPtr->y1;
infoPtr->y1 = infoPtr->y2;
infoPtr->y2 = temp;
}
/* trivial rejects */
if (infoPtr->x1 > wPtr->renderInfo->fmt.x2) {
return TCL_BREAK;
}
if (infoPtr->x2 < wPtr->renderInfo->fmt.x1) {
return TCL_BREAK;
}
if (infoPtr->y1 > wPtr->renderInfo->fmt.y2) {
return TCL_BREAK;
}
if (infoPtr->y2 < wPtr->renderInfo->fmt.y1) {
return TCL_BREAK;
}
/* the area is indeed visible, do some clipping */
if (infoPtr->x1 < wPtr->renderInfo->fmt.x1) {
infoPtr->x1 = wPtr->renderInfo->fmt.x1;
}
if (infoPtr->x2 > wPtr->renderInfo->fmt.x2) {
infoPtr->x2 = wPtr->renderInfo->fmt.x2;
}
if (infoPtr->y1 < wPtr->renderInfo->fmt.y1) {
infoPtr->y1 = wPtr->renderInfo->fmt.y1;
}
if (infoPtr->y2 > wPtr->renderInfo->fmt.y2) {
infoPtr->y2 = wPtr->renderInfo->fmt.y2;
}
return TCL_OK;
}
static void
GetBlockPosn(wPtr, x1, y1, x2, y2, bx1, by1, bx2, by2)
WidgetPtr wPtr;
int x1; /* cell index */
int x2;
int y1;
int y2;
int * bx1; /* block index */
int * by1;
int * bx2;
int * by2;
{
*bx1 = x1;
*bx2 = x2;
*by1 = y1;
*by2 = y2;
switch (wPtr->renderInfo->fmt.whichArea) {
case TIX_S_MARGIN:
break;
case TIX_X_MARGIN:
*bx1 -= wPtr->scrollInfo[0].offset;
*bx2 -= wPtr->scrollInfo[0].offset;
break;
case TIX_Y_MARGIN:
*by1 -= wPtr->scrollInfo[1].offset;
*by2 -= wPtr->scrollInfo[1].offset;
break;
case TIX_MAIN:
*bx1 -= wPtr->scrollInfo[0].offset;
*bx2 -= wPtr->scrollInfo[0].offset;
*by1 -= wPtr->scrollInfo[1].offset;
*by2 -= wPtr->scrollInfo[1].offset;
break;
}
}
static void
GetRenderPosn(wPtr, bx1, by1, bx2, by2, rx1, ry1, rx2, ry2)
WidgetPtr wPtr;
int bx1; /* block index */
int by1;
int bx2;
int by2;
int * rx1; /* render buffer position */
int * ry1;
int * rx2;
int * ry2;
{
int x, y, i;
for (x=0,i=0; i<=bx2; i++) {
if (i == bx1) {
*rx1 = x;
}
if (i == bx2) {
*rx2 = x + wPtr->mainRB->dispSize[0][i].total - 1;
break;
}
x += wPtr->mainRB->dispSize[0][i].total;
}
for (y=0,i=0; i<=by2; i++) {
if (i == by1) {
*ry1 = y;
}
if (i == by2) {
*ry2 = y + wPtr->mainRB->dispSize[1][i].total - 1;
break;
}
y += wPtr->mainRB->dispSize[1][i].total;
}
*rx1 += wPtr->renderInfo->origin[0];
*rx2 += wPtr->renderInfo->origin[0];
*ry1 += wPtr->renderInfo->origin[1];
*ry2 += wPtr->renderInfo->origin[1];
}
static void
Tix_GrFillCells(wPtr, border, selectBorder, bx1, by1, bx2, by2,
borderWidth, relief, filled, bw)
WidgetPtr wPtr;
Tk_3DBorder border;
Tk_3DBorder selectBorder;
int bx1;
int by1;
int bx2;
int by2;
int borderWidth;
int relief;
int filled;
int bw[2][2];
{
int rx1, ry1, rx2, ry2;
int i, j;
Tk_3DBorder targetBorder;
for (i=bx1; i<=bx2; i++) {
for (j=by1; j<=by2; j++) {
if (filled) {
GetRenderPosn(wPtr, i, j, i, j, &rx1,&ry1, &rx2,&ry2);
if (wPtr->mainRB->elms[i][j].selected) {
targetBorder = selectBorder;
} else {
targetBorder = border;
}
Tk_Fill3DRectangle(wPtr->dispData.tkwin,
wPtr->renderInfo->drawable,
targetBorder, rx1, ry1, rx2-rx1+1, ry2-ry1+1,
0, TK_RELIEF_FLAT);
wPtr->mainRB->elms[i][j].filled = 1;
} else {
if (!wPtr->mainRB->elms[i][j].filled) {
if (i == bx1) {
if (wPtr->mainRB->elms[i][j].borderW[0][0] < bw[0][0]){
wPtr->mainRB->elms[i][j].borderW[0][0] = bw[0][0];
}
}
if (i == bx2) {
if (wPtr->mainRB->elms[i][j].borderW[0][1] < bw[0][1]){
wPtr->mainRB->elms[i][j].borderW[0][1] = bw[0][1];
}
}
if (j == by1) {
if (wPtr->mainRB->elms[i][j].borderW[1][0] < bw[1][0]){
wPtr->mainRB->elms[i][j].borderW[1][0] = bw[1][0];
}
}
if (j == by2) {
if (wPtr->mainRB->elms[i][j].borderW[1][1] < bw[1][1]){
wPtr->mainRB->elms[i][j].borderW[1][1] = bw[1][1];
}
}
}
}
}
}
if (borderWidth > 0) {
GetRenderPosn(wPtr, bx1, by1, bx2, by2, &rx1,&ry1, &rx2,&ry2);
if (bx1 == bx2 && by1 == by2) {
/* special case: if a single cell is selected, we invert the
* border */
if (wPtr->mainRB->elms[bx1][by1].selected) {
if (relief == TK_RELIEF_RAISED) {
relief = TK_RELIEF_SUNKEN;
}
else if (relief == TK_RELIEF_SUNKEN) {
relief = TK_RELIEF_RAISED;
}
}
}
Tk_Draw3DRectangle(wPtr->dispData.tkwin,
wPtr->renderInfo->drawable,
border, rx1, ry1, rx2-rx1+1, ry2-ry1+1,
borderWidth, relief);
}
}
static int
Tix_GrFormatBorder(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
BorderFmtStruct info;
int code = TCL_OK;
int bx1, bx2, by1, by2;
int i, j;
info.x1 = 0;
info.y1 = 0;
info.x2 = 0;
info.y2 = 0;
info.border = NULL;
info.borderWidth = 0;
info.selectBorder = NULL;
info.relief = TK_RELIEF_FLAT;
info.xon = 0;
info.xoff = 0;
info.yon = 0;
info.yoff = 0;
info.filled = 0;
if ((code = GetInfo(wPtr, interp, argc, argv, (FormatStruct*)&info,
borderConfigSpecs))!= TCL_OK) {
goto done;
}
/*
* If the xon is not specified, then by default the xon is encloses the
* whole region. Same for yon.
*/
if (info.xon == 0) {
info.xon = info.x2 - info.x1 + 1;
info.xoff = 0;
}
if (info.yon == 0) {
info.yon = info.y2 - info.y1 + 1;
info.yoff = 0;
}
GetBlockPosn(wPtr, info.x1, info.y1, info.x2, info.y2,
&bx1, &by1, &bx2, &by2);
#if 0
/* now it works */
#ifdef __WIN32__
if (bx1 == 0 && bx2 == 0 && by1 == 0 && by2 == 0) {
/* some how this doesn't work in BC++ 4.5 */
goto done;
}
#endif
#endif
for (i=bx1; i<=bx2; i+=(info.xon+info.xoff)) {
for (j=by1; j<=by2; j+=(info.yon+info.yoff)) {
int _bx1, _by1, _bx2, _by2;
int borderWidths[2][2];
_bx1 = i;
_bx2 = i+info.xon-1;
_by1 = j;
_by2 = j+info.yon-1;
if (_bx2 > bx2) {
_bx2 = bx2;
}
if (_by2 > by2) {
_by2 = by2;
}
borderWidths[0][0] = info.borderWidth;
borderWidths[0][1] = info.borderWidth;
borderWidths[1][0] = info.borderWidth;
borderWidths[1][1] = info.borderWidth;
Tix_GrFillCells(wPtr, info.border, info.selectBorder,
_bx1, _by1, _bx2, _by2,
info.borderWidth, info.relief, info.filled, borderWidths);
}
}
done:
if (code == TCL_BREAK) {
code = TCL_OK;
}
if (code == TCL_OK) {
if (Tix_GrSaveColor(wPtr, TK_CONFIG_BORDER, (void*)info.border) == 0) {
info.border = (Tk_3DBorder)NULL;
}
if (Tix_GrSaveColor(wPtr, TK_CONFIG_BORDER, (void*)info.selectBorder)
== 0) {
info.selectBorder = (Tk_3DBorder)NULL;
}
Tk_FreeOptions(borderConfigSpecs, (char *)&info,
wPtr->dispData.display, 0);
}
return code;
}
static int
Tix_GrFormatGrid(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
GridFmtStruct info;
int code = TCL_OK;
int rx1, rx2, ry1, ry2;
int bx1, bx2, by1, by2;
int i, j;
GC gc;
int borderWidths[2][2];
info.x1 = 0;
info.y1 = 0;
info.x2 = 0;
info.y2 = 0;
info.border = NULL;
info.selectBorder = NULL;
info.bgBorder = NULL;
info.borderWidth = 0;
info.relief = TK_RELIEF_FLAT;
info.xon = 1;
info.xoff = 0;
info.yon = 1;
info.yoff = 0;
info.filled = 0;
if ((code = GetInfo(wPtr, interp, argc, argv, (FormatStruct*)&info,
gridConfigSpecs))!= TCL_OK) {
goto done;
}
gc = Tk_3DBorderGC(wPtr->dispData.tkwin, info.border,
TK_3D_FLAT_GC);
GetBlockPosn(wPtr, info.x1, info.y1, info.x2, info.y2,
&bx1, &by1, &bx2, &by2);
borderWidths[0][0] = 0;
borderWidths[0][1] = 0;
borderWidths[1][0] = 0;
borderWidths[1][1] = 0;
switch(info.anchor) {
case TK_ANCHOR_N:
case TK_ANCHOR_NE:
case TK_ANCHOR_NW:
borderWidths[1][0] = info.borderWidth;
break;
default:
; /* do nothing. This line gets rid of compiler warnings */
}
switch(info.anchor) {
case TK_ANCHOR_SE:
case TK_ANCHOR_S:
case TK_ANCHOR_SW:
borderWidths[1][1] = info.borderWidth;
break;
default:
; /* do nothing. This line gets rid of compiler warnings */
}
switch(info.anchor) {
case TK_ANCHOR_SW:
case TK_ANCHOR_W:
case TK_ANCHOR_NW:
borderWidths[0][0] = info.borderWidth;
break;
default:
; /* do nothing. This line gets rid of compiler warnings */
}
switch(info.anchor) {
case TK_ANCHOR_NE:
case TK_ANCHOR_E:
case TK_ANCHOR_SE:
borderWidths[0][1] = info.borderWidth;
break;
default:
; /* do nothing. This line gets rid of compiler warnings */
}
for (i=bx1; i<=bx2; i+=(info.xon+info.xoff)) {
for (j=by1; j<=by2; j+=(info.yon+info.yoff)) {
int _bx1, _by1, _bx2, _by2;
_bx1 = i;
_bx2 = i+info.xon-1;
_by1 = j;
_by2 = j+info.yon-1;
if (_bx2 > bx2) {
_bx2 = bx2;
}
if (_by2 > by2) {
_by2 = by2;
}
Tix_GrFillCells(wPtr, info.bgBorder, info.selectBorder,
_bx1, _by1, _bx2, _by2, 0, TK_RELIEF_FLAT, info.filled,
borderWidths);
if (info.borderWidth > 0) {
GetRenderPosn(wPtr, _bx1, _by1, _bx2, _by2,
&rx1,&ry1, &rx2,&ry2);
switch(info.anchor) {
case TK_ANCHOR_N:
case TK_ANCHOR_NE:
case TK_ANCHOR_NW:
XDrawLine(wPtr->dispData.display,
wPtr->renderInfo->drawable, gc,
rx1, ry1, rx2, ry1);
break;
default:
; /* do nothing. This line gets rid of compiler warnings */
}
switch(info.anchor) {
case TK_ANCHOR_SE:
case TK_ANCHOR_S:
case TK_ANCHOR_SW:
XDrawLine(wPtr->dispData.display,
wPtr->renderInfo->drawable, gc,
rx1, ry2, rx2, ry2);
break;
default:
; /* do nothing. This line gets rid of compiler warnings */
}
switch(info.anchor) {
case TK_ANCHOR_SW:
case TK_ANCHOR_W:
case TK_ANCHOR_NW:
XDrawLine(wPtr->dispData.display,
wPtr->renderInfo->drawable, gc,
rx1, ry1, rx1, ry2);
break;
default:
; /* do nothing. This line gets rid of compiler warnings */
}
switch(info.anchor) {
case TK_ANCHOR_NE:
case TK_ANCHOR_E:
case TK_ANCHOR_SE:
XDrawLine(wPtr->dispData.display,
wPtr->renderInfo->drawable, gc,
rx2, ry1, rx2, ry2);
break;
default:
; /* do nothing. This line gets rid of compiler warnings */
}
}
}
}
done:
if (code == TCL_BREAK) {
code = TCL_OK;
}
if (code == TCL_OK) {
if (Tix_GrSaveColor(wPtr, TK_CONFIG_BORDER, (void*)info.border) == 0) {
info.border = (Tk_3DBorder)NULL;
}
if (Tix_GrSaveColor(wPtr, TK_CONFIG_BORDER, (void*)info.bgBorder)==0) {
info.bgBorder = (Tk_3DBorder)NULL;
}
if (Tix_GrSaveColor(wPtr, TK_CONFIG_BORDER, (void*)info.selectBorder)
== 0) {
info.selectBorder = (Tk_3DBorder)NULL;
}
Tk_FreeOptions(gridConfigSpecs, (char *)&info, wPtr->dispData.display,
0);
}
return code;
}
/* returns 1 if the caller can free the border/color */
static int Tix_GrSaveColor(wPtr, type, ptr)
WidgetPtr wPtr;
CFG_TYPE type;
void * ptr;
{
long pixel;
Tix_ListIterator li;
int found;
ColorInfo * cPtr;
if (type == TK_CONFIG_COLOR) {
pixel = ((XColor *)ptr)->pixel;
} else {
pixel = Tk_3DBorderColor((Tk_3DBorder)ptr)->pixel;
}
Tix_SimpleListIteratorInit(&li);
for (found = 0, Tix_SimpleListStart(&wPtr->colorInfo, &li);
!Tix_SimpleListDone(&li);
Tix_SimpleListNext (&wPtr->colorInfo, &li)) {
cPtr = (ColorInfo *)li.curr;
if (cPtr->pixel == pixel) {
cPtr->counter = wPtr->colorInfoCounter;
return 1;
}
}
cPtr = (ColorInfo *)ckalloc(sizeof(ColorInfo));
if (type == TK_CONFIG_COLOR) {
cPtr->color = (XColor *)ptr;
} else {
cPtr->border = (Tk_3DBorder)ptr;
}
cPtr->type = (int)type;
cPtr->pixel = pixel;
cPtr->counter = wPtr->colorInfoCounter;
Tix_SimpleListAppend(&wPtr->colorInfo, (char*)cPtr, 0);
return 0;
}
void
Tix_GrFreeUnusedColors(wPtr, freeAll)
WidgetPtr wPtr;
int freeAll;
{
Tix_ListIterator li;
ColorInfo * cPtr;
Tix_SimpleListIteratorInit(&li);
for (Tix_SimpleListStart(&wPtr->colorInfo, &li);
!Tix_SimpleListDone(&li);
Tix_SimpleListNext (&wPtr->colorInfo, &li)) {
cPtr = (ColorInfo *)li.curr;
if (freeAll || cPtr->counter < wPtr->colorInfoCounter) {
Tix_SimpleListDelete(&wPtr->colorInfo, &li);
if (cPtr->type == (int)(TK_CONFIG_COLOR)) {
Tk_FreeColor(cPtr->color);
} else {
Tk_Free3DBorder(cPtr->border);
}
ckfree((char*)cPtr);
}
}
}

121
generic/tixGrRC.c Normal file
View File

@@ -0,0 +1,121 @@
/* $Id: tixGrRC.c,v 1.3 2004/03/28 02:44:56 hobbs Exp $ */
/*
* tixGrRC.c --
*
* This module handles "size" sub-commands.
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#include <tixPort.h>
#include <tixInt.h>
#include <tixDef.h>
#include <tixGrid.h>
static TIX_DECLARE_SUBCMD(Tix_GrRCSize);
EXTERN TIX_DECLARE_SUBCMD(Tix_GrSetSize);
int
Tix_GrSetSize(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
static Tix_SubCmdInfo subCmdInfo[] = {
{TIX_DEFAULT_LEN, "row", 1, TIX_VAR_ARGS, Tix_GrRCSize,
"index ?option value ...?"},
{TIX_DEFAULT_LEN, "column", 1, TIX_VAR_ARGS, Tix_GrRCSize,
"index ?option value ...?"},
};
static Tix_CmdInfo cmdInfo = {
Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "option index ?arg ...?",
};
return Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData,
interp, argc+1, argv-1);
}
static int
Tix_GrRCSize(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
int which, index, code;
char errorMsg[300];
int changed;
/* TODO: can the index be <0?? */
if (argv[-1][0] == 'c') {
which = 0;
} else {
which = 1;
}
if (Tcl_GetInt(interp, argv[0], &index) != TCL_OK) {
size_t len = strlen(argv[0]);
Tcl_ResetResult(interp);
if (strncmp(argv[0], "default", len) != 0) {
Tcl_AppendResult(interp, "unknown option \"", argv[0],
"\"; must be an integer or \"default\"", NULL);
return TCL_ERROR;
} else {
/*
* Set the default sizes
*/
/* Buffer size checked: test=grrc-1.2 */
sprintf(errorMsg, "%s %s ?option value ...?", argv[-2], argv[-1]);
code = Tix_GrConfigSize(interp, wPtr, argc-1, argv+1,
&wPtr->defSize[which], errorMsg, &changed);
/* Handling special cases */
if (code == TCL_OK) {
switch (wPtr->defSize[which].sizeType) {
case TIX_GR_DEFAULT:
wPtr->defSize[which].sizeType = TIX_GR_DEFINED_CHAR;
if (which == 0) {
wPtr->defSize[which].charValue = 10.0;
} else {
wPtr->defSize[which].charValue = 1.1;
}
}
switch (wPtr->defSize[which].sizeType) {
case TIX_GR_DEFINED_PIXEL:
wPtr->defSize[which].pixels=wPtr->defSize[which].sizeValue;
break;
case TIX_GR_DEFINED_CHAR:
wPtr->defSize[which].pixels =
(int)(wPtr->defSize[which].charValue *
wPtr->fontSize[which]);
break;
}
}
}
} else {
/* Buffer size checked: test=grrc-1.3 */
sprintf(errorMsg, "%s %s ?option value ...?", argv[-2], argv[-1]);
code = TixGridDataConfigRowColSize(interp, wPtr, wPtr->dataSet,
which, index, argc-1, argv+1, errorMsg, &changed);
}
if (changed) {
Tix_GrDoWhenIdle(wPtr, TIX_GR_RESIZE);
}
return code;
}

288
generic/tixGrSel.c Normal file
View File

@@ -0,0 +1,288 @@
/* $Id: tixGrSel.c,v 1.2 2004/03/28 02:44:56 hobbs Exp $ */
/*
* tixGrSel.c --
*
* This module handles the selection
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#include <tixPort.h>
#include <tixInt.h>
#include <tixDef.h>
#include <tixGrid.h>
EXTERN TIX_DECLARE_SUBCMD(Tix_GrSelection);
static TIX_DECLARE_SUBCMD(Tix_GrSelIncludes);
static TIX_DECLARE_SUBCMD(Tix_GrSelModify);
static int Tix_GrSelIncludes _ANSI_ARGS_((ClientData clientData,
Tcl_Interp *interp, int argc, CONST84 char **argv));
static void Tix_GrAdjustSelection _ANSI_ARGS_((
WidgetPtr wPtr, SelectBlock * sbPtr));
static void Tix_GrMergeSelection _ANSI_ARGS_((
WidgetPtr wPtr, SelectBlock * sbPtr));
int
Tix_GrSelection(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
static Tix_SubCmdInfo subCmdInfo[] = {
{TIX_DEFAULT_LEN, "adjust", 2, 4, Tix_GrSelModify,
"x1 y1 ?x2 y2?"},
{TIX_DEFAULT_LEN, "clear", 2, 4, Tix_GrSelModify,
"x1 y1 ?x2 y2?"},
{TIX_DEFAULT_LEN, "includes", 2, 4, Tix_GrSelIncludes,
"x1 y1 ?x2 y2?"},
{TIX_DEFAULT_LEN, "set", 2, 4, Tix_GrSelModify,
"x1 y1 ?x2 y2?"},
{TIX_DEFAULT_LEN, "toggle", 2, 4, Tix_GrSelModify,
"x1 y1 ?x2 y2?"},
};
static Tix_CmdInfo cmdInfo = {
Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "?option? ?arg ...?",
};
return Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData,
interp, argc+1, argv-1);
}
static int
Tix_GrSelIncludes(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
#if 0
WidgetPtr wPtr = (WidgetPtr) clientData;
#endif
return TCL_OK;
}
static void
Tix_GrMergeSelection(wPtr, sbPtr)
WidgetPtr wPtr;
SelectBlock * sbPtr;
{
Tix_ListIterator li;
switch (sbPtr->type) {
case TIX_GR_SET:
case TIX_GR_CLEAR:
if (sbPtr->range[0][0] == 0 &&
sbPtr->range[1][0] == 0 &&
sbPtr->range[0][1] == TIX_GR_MAX &&
sbPtr->range[1][1] == TIX_GR_MAX) {
/* clear everything else from the list
*/
Tix_SimpleListIteratorInit(&li);
for (Tix_SimpleListStart(&wPtr->selList, &li);
!Tix_SimpleListDone(&li);
Tix_SimpleListNext (&wPtr->selList, &li)) {
SelectBlock *ptr = (SelectBlock *)li.curr;
Tix_SimpleListDelete(&wPtr->selList, &li);
ckfree((char*)ptr);
}
}
if (sbPtr->type == TIX_GR_SET) {
Tix_SimpleListAppend(&wPtr->selList, (char*)sbPtr, 0);
}
goto done;
}
#if 0
switch (sbPtr->type) {
case TIX_GR_TOGGLE: {
}
break;
case TIX_GR_SET: {
Tix_SimpleListAppend(&wPtr->selList, (char*)sbPtr, 0);
}
break;
case TIX_GR_CLEAR: {
Tix_SimpleListIteratorInit(&li);
for (Tix_SimpleListStart(&wPtr->selList, &li);
!Tix_SimpleListDone(&li);
Tix_SimpleListNext (&wPtr->selList, &li)) {
}
}
}
#else
Tix_SimpleListAppend(&wPtr->selList, (char*)sbPtr, 0);
#endif
done:
Tix_GrAddChangedRect(wPtr, sbPtr->range, 0);
}
static void
Tix_GrAdjustSelection(wPtr, sbPtr)
WidgetPtr wPtr;
SelectBlock * sbPtr;
{
int changed[2][2];
SelectBlock * current;
current = (SelectBlock*)wPtr->selList.tail;
/*
* The changed region is the union of the area of the current selection
* and the adjusted selection.
*/
changed[TIX_X][0] = sbPtr->range[TIX_X][0];
changed[TIX_X][1] = sbPtr->range[TIX_X][1];
changed[TIX_Y][0] = sbPtr->range[TIX_Y][0];
changed[TIX_Y][1] = sbPtr->range[TIX_Y][1];
if (changed[TIX_X][0] > current->range[TIX_X][0]) {
changed[TIX_X][0] = current->range[TIX_X][0];
}
if (changed[TIX_X][1] < current->range[TIX_X][1]) {
changed[TIX_X][1] = current->range[TIX_X][1];
}
if (changed[TIX_Y][0] > current->range[TIX_Y][0]) {
changed[TIX_Y][0] = current->range[TIX_Y][0];
}
if (changed[TIX_Y][1] < current->range[TIX_Y][1]) {
changed[TIX_Y][1] = current->range[TIX_Y][1];
}
/* Adjust the current selection according to sbPtr */
current->range[TIX_X][0] = sbPtr->range[TIX_X][0];
current->range[TIX_X][1] = sbPtr->range[TIX_X][1];
current->range[TIX_Y][0] = sbPtr->range[TIX_Y][0];
current->range[TIX_Y][1] = sbPtr->range[TIX_Y][1];
/* Set the changed area */
Tix_GrAddChangedRect(wPtr, changed, 0);
/* sbPtr is no longer needed */
ckfree((char*)sbPtr);
}
static int
Tix_GrSelModify(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
int type, adjust = 0;
SelectBlock * sbPtr = NULL;
int tmp;
if (argc != 2 && argc != 4) {
return Tix_ArgcError(interp, argc+2, argv-2, 2, "x1 y1 ?x2 y2?");
}
/*
* (1) find out the type of operation.
*/
if (argv[-1][0] == 'a') {
if (wPtr->selList.numItems <= 0) {
/*
* There is nothing in the selection list to adjust!
*/
Tcl_AppendResult(interp, "selection list is empty", NULL);
return TCL_ERROR;
}
adjust = 1;
type = 0;
}
else if (argv[-1][0] == 'c') {
type = TIX_GR_CLEAR;
}
else if (argv[-1][0] == 's') {
type = TIX_GR_SET;
}
else {
type = TIX_GR_TOGGLE;
}
sbPtr = (SelectBlock*)ckalloc(sizeof(SelectBlock));
sbPtr->type = type;
if (Tcl_GetInt(interp, argv[0], &sbPtr->range[0][0]) != TCL_OK) {
goto error;
}
if (Tcl_GetInt(interp, argv[1], &sbPtr->range[1][0]) != TCL_OK) {
goto error;
}
if (argc == 4) {
if (Tcl_GetInt(interp, argv[2], &sbPtr->range[0][1]) != TCL_OK) {
if (strcmp(argv[2], "max") == 0) {
Tcl_ResetResult(interp);
sbPtr->range[0][1] = TIX_GR_MAX;
} else {
goto error;
}
}
if (Tcl_GetInt(interp, argv[3], &sbPtr->range[1][1]) != TCL_OK) {
if (strcmp(argv[3], "max") == 0) {
Tcl_ResetResult(interp);
sbPtr->range[1][1] = TIX_GR_MAX;
} else {
goto error;
}
}
} else {
sbPtr->range[0][1] = sbPtr->range[0][0];
sbPtr->range[1][1] = sbPtr->range[1][0];
}
if (wPtr->selectUnit != tixRowUid) {
if (sbPtr->range[0][0] > sbPtr->range[0][1]) {
tmp = sbPtr->range[0][1];
sbPtr->range[0][1] = sbPtr->range[0][0];
sbPtr->range[0][0] = tmp;
}
} else {
sbPtr->range[0][0] = 0;
sbPtr->range[0][1] = TIX_GR_MAX;
}
if (wPtr->selectUnit != tixColumnUid) {
if (sbPtr->range[1][0] > sbPtr->range[1][1]) {
tmp = sbPtr->range[1][1];
sbPtr->range[1][1] = sbPtr->range[1][0];
sbPtr->range[1][0] = tmp;
}
} else {
sbPtr->range[1][0] = 0;
sbPtr->range[1][1] = TIX_GR_MAX;
}
if (adjust) {
Tix_GrAdjustSelection(wPtr, sbPtr);
sbPtr = NULL;
} else {
Tix_GrMergeSelection(wPtr, sbPtr);
}
wPtr->toComputeSel = 1;
return TCL_OK;
error:
if (sbPtr) {
ckfree((char*)sbPtr);
}
return TCL_ERROR;
}

466
generic/tixGrSort.c Normal file
View File

@@ -0,0 +1,466 @@
/* $Id: tixGrSort.c,v 1.3 2008/02/28 04:05:29 hobbs Exp $ */
/*
* tixGrSel.c --
*
* This module handles the sorting of the Grid widget.
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#include <tixPort.h>
#include <tixInt.h>
#include <tixGrid.h>
/*
* The variables below are used to implement the "lsort" command.
* Unfortunately, this use of static variables prevents "lsort"
* from being thread-safe, but there's no alternative given the
* current implementation of qsort. In a threaded environment
* these variables should be made thread-local if possible, or else
* "lsort" needs internal mutual exclusion.
*/
static Tcl_Interp *sortInterp = NULL; /* Interpreter for "lsort" command.
* NULL means no lsort is active. */
static enum {ASCII, INTEGER, REAL, COMMAND} sortMode;
/* Mode for sorting:compare as strings,
* compare as numbers, or call
* user-defined command for
* comparison. */
static Tcl_DString sortCmd; /* Holds command if mode is COMMAND.
* pre-initialized to hold base of
* command. */
static int sortIncreasing; /* 0 means sort in decreasing order,
* 1 means increasing order. */
static int sortCode; /* Anything other than TCL_OK means a
* problem occurred while sorting; this
* executing a comparison command, so
* the sort was aborted. */
/*
* Forward declarations for procedures defined in this file:
*/
EXTERN TIX_DECLARE_SUBCMD(Tix_GrSort);
static int SortCompareProc _ANSI_ARGS_((CONST VOID *first,
CONST VOID *second));
char * Tix_GrGetCellText _ANSI_ARGS_((WidgetPtr wPtr,
int x, int y));
Tix_GrSortItem * Tix_GrGetSortItems _ANSI_ARGS_((WidgetPtr wPtr,
int axis, int start, int end, int sortKeyIndex));
void Tix_GrFreeSortItems _ANSI_ARGS_((WidgetPtr wPtr,
Tix_GrSortItem * items, int numItems));
/*
*----------------------------------------------------------------------
*
* Tcl_LsortCmd --
*
* This procedure is invoked to process the "lsort" Tcl command.
* See the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
*
* Side effects:
* See the user documentation.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
char *
Tix_GrGetCellText(wPtr, x, y)
WidgetPtr wPtr;
int x;
int y;
{
TixGrEntry* chPtr;
if ((chPtr = (TixGrEntry*) TixGridDataFindEntry(wPtr->dataSet, x, y))) {
switch (Tix_DItemType(chPtr->iPtr)) {
case TIX_DITEM_TEXT:
return chPtr->iPtr->text.text;
case TIX_DITEM_IMAGETEXT:
return chPtr->iPtr->imagetext.text;
default:
return NULL;
}
} else {
return NULL;
}
}
Tix_GrSortItem *
Tix_GrGetSortItems(wPtr, axis, start, end, sortKeyIndex)
WidgetPtr wPtr;
int axis;
int start;
int end;
int sortKeyIndex;
{
int i, k, numItems;
Tix_GrSortItem *items;
if (end <= start) {
/* sanity check: no need to sort */
return (Tix_GrSortItem *) NULL;
}
numItems = end-start+1;
items = (Tix_GrSortItem *)ckalloc(sizeof(Tix_GrSortItem) * numItems);
for (k=0,i=start; i<=end; i++, k++) {
items[k].index = i;
if (axis == 0) {
items[k].data = Tix_GrGetCellText(wPtr, i, sortKeyIndex);
} else {
items[k].data = Tix_GrGetCellText(wPtr, sortKeyIndex, i);
}
}
return items;
}
void
Tix_GrFreeSortItems(wPtr, items, numItems)
WidgetPtr wPtr;
Tix_GrSortItem * items;
int numItems;
{
ckfree((char*)items);
}
int
Tix_GrSort(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
int i, axis, otherAxis, start, end;
size_t len;
Tix_GrSortItem *items = NULL;
int numItems;
CONST84 char *command = NULL; /* Initialization needed only to
* prevent compiler warning. */
int sortKeyIndex;
int gridSize[2];
/*-------------------------------------------------------------------
* Argument parsing
*-------------------------------------------------------------------
*/
if (sortInterp != NULL) {
Tcl_SetResult(interp,
"can't invoke the tixGrid sort command recursively",
TCL_STATIC);
return TCL_ERROR;
}
/* Figure out the sorting dimension
*/
len = strlen(argv[0]);
if (strncmp(argv[0], "rows", len)==0) {
axis = 1;
otherAxis = 0;
} else if (strncmp(argv[0], "column", len)==0) {
axis = 0;
otherAxis = 1;
} else {
Tcl_AppendResult(interp, "wrong dimension \"", argv[0],
"\", should be row or column", (char *) NULL);
return TCL_ERROR;
}
/* get the start and end index
*/
if (axis == 0) {
if (TixGridDataGetIndex(interp, wPtr, argv[1], NULL, &start, NULL)
!=TCL_OK) {
return TCL_ERROR;
}
if (TixGridDataGetIndex(interp, wPtr, argv[2], NULL, &end, NULL)
!=TCL_OK) {
return TCL_ERROR;
}
} else {
if (TixGridDataGetIndex(interp, wPtr, NULL, argv[1], NULL, &start)
!=TCL_OK) {
return TCL_ERROR;
}
if (TixGridDataGetIndex(interp, wPtr, NULL, argv[2], NULL, &end)
!=TCL_OK) {
return TCL_ERROR;
}
}
/* Check the range
*/
TixGridDataGetGridSize(wPtr->dataSet, &gridSize[0], &gridSize[1]);
if (start > end) {
int tmp = start;
start = end;
end = tmp;
}
if (start >= gridSize[axis]) {
/* no need to sort */
return TCL_OK;
}
if (end == start) {
/* no need to sort */
return TCL_OK;
}
/* get the options
*/
if ((argc-3) %2 != 0) {
Tcl_AppendResult(interp, "value for \"", argv[argc-1],
"\" missing", NULL);
return TCL_ERROR;
}
sortInterp = interp;
sortMode = ASCII;
sortIncreasing = 1;
sortCode = TCL_OK;
sortKeyIndex = wPtr->hdrSize[otherAxis]; /* by default, use the first
* scrollable item as the key
*/
for (i=3; i<argc; i+=2) {
len = strlen(argv[i]);
if (strncmp(argv[i], "-type", len) == 0) {
if (strcmp(argv[i+1], "ascii") == 0) {
sortMode = ASCII;
} else if (strcmp(argv[i+1], "integer") == 0) {
sortMode = INTEGER;
} else if (strcmp(argv[i+1], "real") == 0) {
sortMode = REAL;
} else {
Tcl_AppendResult(interp, "wrong type \"", argv[i+1],
"\": must be ascii, integer or real", (char *) NULL);
sortCode = TCL_ERROR;
goto done;
}
}
else if (strncmp(argv[i], "-order", len) == 0) {
if (strcmp(argv[i+1], "increasing") == 0) {
sortIncreasing = 1;
} else if (strcmp(argv[i+1], "decreasing") == 0) {
sortIncreasing = 0;
} else {
Tcl_AppendResult(interp, "wrong order \"", argv[i+1],
"\": must be increasing or decreasing", (char *) NULL);
sortCode = TCL_ERROR;
goto done;
}
}
else if (strncmp(argv[i], "-key", len) == 0) {
if (axis == 0) {
/* sort columns: the key is a column index (1) */
if (TixGridDataGetIndex(interp, wPtr, NULL, argv[i+1], NULL,
&sortKeyIndex) !=TCL_OK) {
sortCode = TCL_ERROR;
goto done;
}
} else {
/* sort rows: the key is a row index (0)*/
if (TixGridDataGetIndex(interp, wPtr, argv[i+1], NULL,
&sortKeyIndex, NULL) !=TCL_OK) {
sortCode = TCL_ERROR;
goto done;
}
}
}
else if (strncmp(argv[i], "-command", len) == 0) {
sortMode = COMMAND;
command = argv[i+1];
}
else {
Tcl_AppendResult(interp, "wrong option \"", argv[i],
"\": must be -command, -key, -order or -type", (char *) NULL);
sortCode = TCL_ERROR;
goto done;
}
}
if (sortMode == COMMAND) {
Tcl_DStringInit(&sortCmd);
Tcl_DStringAppend(&sortCmd, command, -1);
}
/*------------------------------------------------------------------
* SORTING
*------------------------------------------------------------------
*/
/* prepare the array to be sorted */
numItems = end - start + 1;
items = Tix_GrGetSortItems(wPtr, axis, start, end, sortKeyIndex);
if (items != NULL) {
int sizeChanged;
qsort((VOID *)items, (size_t)numItems, sizeof(Tix_GrSortItem),
SortCompareProc);
for (i=0; i<numItems; i++) {
printf("%d\n", items[i].index);
}
sizeChanged = TixGridDataUpdateSort(wPtr->dataSet, axis, start, end,
items);
if (sizeChanged) {
Tix_GrDoWhenIdle(wPtr, TIX_GR_RESIZE);
} else {
wPtr->toResetRB = 1;
Tix_GrDoWhenIdle(wPtr, TIX_GR_REDRAW);
}
Tix_GrFreeSortItems(wPtr, items, numItems);
}
/* Done */
if (sortCode == TCL_OK) {
Tcl_ResetResult(interp);
}
if (sortMode == COMMAND) {
Tcl_DStringFree(&sortCmd);
}
done:
sortInterp = NULL;
return sortCode;
}
/*
*----------------------------------------------------------------------
*
* SortCompareProc --
*
* This procedure is invoked by qsort to determine the proper
* ordering between two elements.
*
* Results:
* < 0 means first is "smaller" than "second", > 0 means "first"
* is larger than "second", and 0 means they should be treated
* as equal.
*
* Side effects:
* None, unless a user-defined comparison command does something
* weird.
*
*----------------------------------------------------------------------
*/
static int
SortCompareProc(first, second)
CONST VOID *first, *second; /* Elements to be compared. */
{
int order;
char *firstString = ((Tix_GrSortItem*)first )->data;
char *secondString = ((Tix_GrSortItem*)second)->data;
order = 0;
if (sortCode != TCL_OK) {
/*
* Once an error has occurred, skip any future comparisons
* so as to preserve the error message in sortInterp->result.
*/
return order;
}
if (firstString == NULL && secondString == NULL) {
/* equal */
return order;
}
if (secondString == NULL) {
/* first larger than second */
order = 1;
goto done;
}
if (firstString == NULL) {
order = -1;
goto done;
}
if (sortMode == ASCII) {
order = strcmp(firstString, secondString);
} else if (sortMode == INTEGER) {
int a, b;
if ((Tcl_GetInt(sortInterp, firstString, &a) != TCL_OK)
|| (Tcl_GetInt(sortInterp, secondString, &b) != TCL_OK)) {
Tcl_AddErrorInfo(sortInterp,
"\n (converting list element from string to integer)");
sortCode = TCL_ERROR;
return order;
}
if (a > b) {
order = 1;
} else if (b > a) {
order = -1;
}
} else if (sortMode == REAL) {
double a, b;
if ((Tcl_GetDouble(sortInterp, firstString, &a) != TCL_OK)
|| (Tcl_GetDouble(sortInterp, secondString, &b) != TCL_OK)) {
Tcl_AddErrorInfo(sortInterp,
"\n (converting list element from string to real)");
sortCode = TCL_ERROR;
return order;
}
if (a > b) {
order = 1;
} else if (b > a) {
order = -1;
}
} else {
int oldLength;
char *end;
/*
* Generate and evaluate a command to determine which string comes
* first.
*/
oldLength = Tcl_DStringLength(&sortCmd);
Tcl_DStringAppendElement(&sortCmd, firstString);
Tcl_DStringAppendElement(&sortCmd, secondString);
sortCode = Tcl_Eval(sortInterp, Tcl_DStringValue(&sortCmd));
Tcl_DStringTrunc(&sortCmd, oldLength);
if (sortCode != TCL_OK) {
Tcl_AddErrorInfo(sortInterp,
"\n (user-defined comparison command)");
return order;
}
/*
* Parse the result of the command.
*/
order = strtol(sortInterp->result, &end, 0);
if ((end == sortInterp->result) || (*end != 0)) {
Tcl_ResetResult(sortInterp);
Tcl_AppendResult(sortInterp,
"comparison command returned non-numeric result",
(char *) NULL);
sortCode = TCL_ERROR;
return order;
}
}
done:
if (!sortIncreasing) {
order = -order;
}
return order;
}

205
generic/tixGrUtl.c Normal file
View File

@@ -0,0 +1,205 @@
/* $Id: tixGrUtl.c,v 1.2 2004/03/28 02:44:56 hobbs Exp $ */
/*
* tixGrUtl.c --
*
* Utility functions for Grid
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#include <tixPort.h>
#include <tixInt.h>
#include <tixDef.h>
#include <tixGrid.h>
#ifndef UCHAR
#define UCHAR(c) ((unsigned char) (c))
#endif
/* string must be a real number plus "char". E.g, "3.0char" */
int
Tix_GetChars(interp, string, doublePtr)
Tcl_Interp *interp; /* Use this for error reporting. */
CONST84 char *string; /* String describing a justification style. */
double *doublePtr; /* Place to store converted result. */
{
char *end;
double d;
d = strtod(string, &end);
if (end == string) {
goto error;
}
while ((*end != '\0') && isspace(*end)) {
end++;
}
if (strncmp(end, "char", 4) != 0) {
goto error;
}
for (end+=4; (*end != '\0') && isspace(UCHAR(*end)); end++) {
;
}
if (*end != '\0') {
goto error;
}
if (d < 0) {
goto error;
}
*doublePtr = d;
return TCL_OK;
error:
Tcl_AppendResult(interp, "bad screen distance \"", string,
"\"", (char *) NULL);
return TCL_ERROR;
}
int Tix_GrConfigSize(interp, wPtr, argc, argv, sizePtr, argcErrorMsg,
changed_ret)
Tcl_Interp *interp;
WidgetPtr wPtr;
int argc;
CONST84 char **argv;
TixGridSize *sizePtr;
CONST84 char * argcErrorMsg;
int *changed_ret;
{
int pixels;
double chars;
int i;
TixGridSize newSize;
int changed = 0;
if (argc == 0) {
char buff[40];
Tcl_AppendResult(interp, "-size ", NULL);
switch (sizePtr->sizeType) {
case TIX_GR_AUTO:
Tcl_AppendResult(interp, "auto", NULL);
break;
case TIX_GR_DEFAULT:
Tcl_AppendResult(interp, "default", NULL);
break;
case TIX_GR_DEFINED_PIXEL:
sprintf(buff, "%d", sizePtr->sizeValue);
Tcl_AppendResult(interp, buff, NULL);
break;
case TIX_GR_DEFINED_CHAR:
sprintf(buff, "%fchar", sizePtr->charValue);
Tcl_AppendResult(interp, buff, NULL);
break;
default:
Tcl_AppendResult(interp, "default", NULL);
break;
}
Tcl_AppendResult(interp, " -pad0 ", NULL);
sprintf(buff, "%d", sizePtr->pad0);
Tcl_AppendResult(interp, buff, NULL);
Tcl_AppendResult(interp, " -pad1 ", NULL);
sprintf(buff, "%d", sizePtr->pad1);
Tcl_AppendResult(interp, buff, NULL);
return TCL_OK;
}
if ((argc %2) != 0) {
Tcl_AppendResult(interp, "value missing for option \"",
argv[argc-1], "\"", NULL);
return TCL_ERROR;
}
newSize = *sizePtr;
for (i=0; i<argc; i+=2) {
if (strncmp("-size", argv[i], strlen(argv[i])) == 0) {
if (strcmp(argv[i+1], "auto")==0) {
newSize.sizeType = TIX_GR_AUTO;
newSize.sizeValue = 0;
}
else if (strcmp(argv[i+1], "default")==0) {
newSize.sizeType = TIX_GR_DEFAULT;
newSize.sizeValue = 0;
}
else if (Tk_GetPixels(interp, wPtr->dispData.tkwin, argv[i+1],
&pixels) == TCL_OK) {
newSize.sizeType = TIX_GR_DEFINED_PIXEL;
newSize.sizeValue = pixels;
}
else {
Tcl_ResetResult(interp);
if (Tix_GetChars(interp, argv[i+1], &chars) == TCL_OK) {
newSize.sizeType = TIX_GR_DEFINED_CHAR;
newSize.charValue = chars;
}
else {
return TCL_ERROR;
}
}
}
else if (strcmp("-pad0", argv[i]) == 0) {
if (Tk_GetPixels(interp, wPtr->dispData.tkwin, argv[i+1],
&pixels) == TCL_OK) {
newSize.pad0 = pixels;
}
else {
return TCL_ERROR;
}
}
else if (strcmp("-pad1", argv[i]) == 0) {
if (Tk_GetPixels(interp, wPtr->dispData.tkwin, argv[i+1],
&pixels) == TCL_OK) {
newSize.pad1 = pixels;
}
else {
return TCL_ERROR;
}
}
else {
Tcl_AppendResult(interp, "Unknown option \"", argv[i],
"\"; must be -pad0, -pad1 or -size", NULL);
return TCL_ERROR;
}
}
if (changed_ret) {
if (sizePtr->sizeType != newSize.sizeType) {
changed = 1;
}
if (sizePtr->sizeValue != newSize.sizeValue) {
changed = 1;
}
if (sizePtr->charValue != newSize.charValue) {
changed = 1;
}
if (sizePtr->pad1 != newSize.pad0) {
changed = 1;
}
if (sizePtr->pad1 != newSize.pad1) {
changed = 1;
}
*changed_ret = changed;
}
*sizePtr = newSize;
return TCL_OK;
}

3312
generic/tixGrid.c Normal file

File diff suppressed because it is too large Load Diff

417
generic/tixGrid.h Normal file
View File

@@ -0,0 +1,417 @@
/*
* tixGrid.h --
*
* Defines main data structures for tixGrid
*
* Copyright (c) 1993-1999 Ioi Kim Lam.
* Copyright (c) 2000 Tix Project Group.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tixGrid.h,v 1.3 2004/03/28 02:44:56 hobbs Exp $
*/
#ifndef _TIX_GRID_H_
#define _TIX_GRID_H_
#ifndef _TIX_GRID_DATA_H_
#include "tixGrData.h"
#endif
#define TIX_X 0
#define TIX_Y 1
#define TIX_S_MARGIN 0
#define TIX_X_MARGIN 1
#define TIX_Y_MARGIN 2
#define TIX_MAIN 3
#define TIX_SITE_NONE -1
typedef struct TixGrEntry {
Tix_DItem * iPtr;
Tcl_HashEntry * entryPtr[2]; /* The index of this entry in the
* row/col tables */
} TixGrEntry;
/*----------------------------------------------------------------------
* Render Block
*
* Before the Grid is rendered, information is filled into a pseudo 2D
* array of RenderBlockElem's:
*
* (1) entries are placed in the appropriate (x,y) locations
* (2) background and borders are formatted according
* (3) highlights are formatted.
*
* The widget is redrawn using the render-block. This saves reformatting
* the next time the widget is exposed.
*----------------------------------------------------------------------
*/
typedef struct RenderBlockElem {
TixGrEntry * chPtr; /* not allocated, don't need to free */
int borderW[2][2];
int index[2];
unsigned int selected : 1;
unsigned int filled : 1;
} RenderBlockElem;
/* ElmDispSize --
*
* This structure stores the size information of the visible
* rows (RenderBlock.dispSize[0][...]) and columns
* (RenderBlock.dispSize[1][...])
*/
typedef struct ElmDispSize {
int preBorder;
int size;
int postBorder;
int total; /* simple the sum of the above */
} ElmDispSize;
typedef struct RenderBlock {
int size[2]; /* num of rows and cols in the render block */
RenderBlockElem **elms; /* An Malloc'ed pseudo 2D array (you can do
* things like elms[0][0]), Used for the
* main body of the Grid.
*/
ElmDispSize *dispSize[2]; /* (dispSizes[0][x], dispSizes[1][y])
* will be the dimension of the element (x,y)
* displayed on the screen (may be bigger
* or smaller than its desired size). */
int visArea[2]; /* visible area (width times height) of
* the visible cells on the screen */
} RenderBlock;
/*----------------------------------------------------------------------
* RenderInfo
*
* This stores information for rendering from the RB into an X drawable.
*
*----------------------------------------------------------------------
*/
typedef struct RenderInfo {
Drawable drawable;
int origin[2];
int offset[2];
int size[2]; /* width and height of the area to draw
* (number of pixels starting from the offset)
* if offset = (2,2) and size = (5,5) we have
* to draw the rectangle ((2,2), (6,6));
*/
struct { /* the current valid grid area for the */
int x1, x2, y1, y2; /* "format" command */
int whichArea;
} fmt;
} RenderInfo;
typedef struct ExposedArea {
int x1, y1, x2, y2;
} ExposedArea, Rect;
/*----------------------------------------------------------------------
* ColorInfo
*
* These colors are used by the format commands. They must be saved
* or otherwise the colormap may be changed ..
*----------------------------------------------------------------------
*/
typedef struct ColorInfo {
struct ColorInfo * next;
int counter;
int type; /* TK_CONFIG_BORDER or TK_CONFIG_COLOR */
long pixel;
Tk_3DBorder border;
XColor * color;
} ColorInfo;
/*----------------------------------------------------------------------
* SelectBlock
*
* These structures are arranged in a list and are used to determine
* where a cell is selected.
*----------------------------------------------------------------------
*/
#define TIX_GR_CLEAR 1
#define TIX_GR_SET 2
#define TIX_GR_TOGGLE 3
#define TIX_GR_MAX 0x7fffffff
#define TIX_GR_RESIZE 1
#define TIX_GR_REDRAW 2
typedef struct SelectBlock {
struct SelectBlock * next;
int range[2][2]; /* the top left and bottom right corners */
int type; /* TIX_GR_CLEAR, TIX_GR_SET,
* TIX_GR_TOGGLE
*
* If several SelectBlock covers the same
* cell, the last block in the wPtr->selList
* determines whether this cell is selected
* or not */
} SelectBlock;
/*----------------------------------------------------------------------
* GrSortItem
*
* Used to sort the items in the grid
*----------------------------------------------------------------------
*/
typedef struct Tix_GrSortItem {
char * data; /* is usually a string, but
* can be a pointer to an
* arbitrary data in C API */
int index; /* row or column */
} Tix_GrSortItem;
/*----------------------------------------------------------------------
* Data structure for iterating the cells inside the grid.
*
*----------------------------------------------------------------------
*/
typedef struct Tix_GrDataRowSearch {
struct TixGridRowCol * row;
Tcl_HashSearch hashSearch;
Tcl_HashEntry *hashPtr;
} Tix_GrDataRowSearch;
typedef struct Tix_GrDataCellSearch {
char * data;
Tcl_HashSearch hashSearch;
Tcl_HashEntry *hashPtr;
} Tix_GrDataCellSearch;
/*----------------------------------------------------------------------
*
* Main data structure of the grid widget.
*
*----------------------------------------------------------------------
*/
typedef struct Tix_GridScrollInfo {
char * command;
int max; /* total size (width or height) of the widget*/
int offset; /* The top/left side of the scrolled widget */
int unit; /* How much should we scroll when the user */
double window; /* visible size, percentage of the total */
}Tix_GridScrollInfo;
typedef struct GridStruct {
Tix_DispData dispData;
Tcl_Command widgetCmd; /* Token for button's widget command. */
/*
* Information used when displaying widget:
*/
int reqSize[2]; /* For app programmer to request size */
/*
* Information used when displaying widget:
*/
/* Border and general drawing */
int borderWidth; /* Width of 3-D borders. */
int selBorderWidth; /* Width of 3-D borders for selected items */
int relief; /* Indicates whether window as a whole is
* raised, sunken, or flat. */
Tk_3DBorder border; /* Used for drawing the 3d border. */
Tk_3DBorder selectBorder; /* Used for selected background. */
XColor *normalFg; /* Normal foreground for text. */
XColor *normalBg; /* Normal background for text. */
XColor *selectFg; /* Color for drawing selected text. */
Tk_Uid state; /* State can only be normal or disabled. */
/* GC and stuff */
GC backgroundGC; /* GC for drawing background. */
GC selectGC; /* GC for drawing selected background. */
GC anchorGC; /* GC for drawing dotted anchor highlight. */
TixFont font; /* Default font used by the DItems. */
/* Text drawing */
Cursor cursor; /* Current cursor for window, or None. */
/* For highlights */
int highlightWidth; /* Width in pixels of highlight to draw
* around widget when it has the focus.
* <= 0 means don't draw a highlight. */
int bdPad; /* = highlightWidth + borderWidth */
XColor *highlightColorPtr; /* Color for drawing traversal highlight. */
GC highlightGC; /* For drawing traversal highlight. */
/*
* default pad and gap values
*/
int padX, padY;
Tk_Uid selectMode; /* Selection style: single, browse, multiple,
* or extended. This value isn't used in C
* code, but the Tcl bindings use it. */
Tk_Uid selectUnit; /* Selection unit: cell, row or column.
* This value isn't used in C
* code, but the Tcl bindings use it. */
/*
* The following three sites are used according to the -selectunit.
* if selectunit is: "cell", [0] and [1] are used; "row", only [0]
* is used; "column", only [1] is used
*/
int anchor[2]; /* The current anchor unit */
int dropSite[2]; /* The current drop site */
int dragSite[2]; /* The current drop site */
/*
* Callback commands.
*/
char *command; /* The command when user double-clicks */
char *browseCmd; /* The command to call when the selection
* changes. */
char *editNotifyCmd; /* The command to call to determine whether
* a cell is editable. */
char *editDoneCmd; /* The command to call when an entry has
* been edited by the user.*/
char *formatCmd; /* The command to call when the Grid widget
* needs to be reformatted (e.g, Exposure
* events or when contents have been
* changed). */
char *sizeCmd; /* The command to call when the size of
* the listbox changes. E.g., when the user
* add/deletes elements. Useful for auto-
* scrollbar geometry managers */
/*
* Info for lay-out
*/
char *takeFocus; /* Value of -takefocus option; not used in
* the C code, but used by keyboard traversal
* scripts. Malloc'ed, but may be NULL. */
int serial; /* this number is incremented before each time
* the widget is redisplayed */
TixGridDataSet * dataSet;
RenderBlock * mainRB; /* Malloc'ed */
int hdrSize[2]; /* number of rows (height of x header, index
* [0]) and columns (width of y header, index
* [1]) */
int floatRange[2]; /* Are the num of columns and rows floated?
* (if floated, you can scroll past the max
* element).*/
int gridSize[2]; /* the size of the grid where there is data */
Tix_DItemInfo * diTypePtr; /* Default item type */
ExposedArea expArea;
RenderInfo * renderInfo; /* only points to stuff in stack */
Tix_GridScrollInfo scrollInfo[2];
int fontSize[2]; /* size of the "0" char of the -font option
*/
TixGridSize defSize[2];
Tix_LinkList colorInfo;
Tix_LinkList selList;
Tix_LinkList mappedWindows;
int colorInfoCounter;
unsigned int hasFocus : 1;
unsigned int idleEvent : 1;
unsigned int toResize : 1; /* idle event */
unsigned int toRedraw : 1; /* idle event */
unsigned int toResetRB : 1; /* Do we need to reset the render block */
unsigned int toComputeSel : 1;
unsigned int toRedrawHighlight : 1;
} Grid;
typedef Grid WidgetRecord;
typedef Grid * WidgetPtr;
/*
* common functions
*/
EXTERN void Tix_GrAddChangedRect _ANSI_ARGS_((
WidgetPtr wPtr, int changedRect[2][2],
int isSite));
EXTERN int Tix_GrConfigSize _ANSI_ARGS_((Tcl_Interp *interp,
WidgetPtr wPtr, int argc, CONST84 char **argv,
TixGridSize *sizePtr, CONST84 char * argcErrorMsg,
int *changed_ret));
EXTERN void Tix_GrDoWhenIdle _ANSI_ARGS_((WidgetPtr wPtr,
int type));
EXTERN void Tix_GrCancelDoWhenIdle _ANSI_ARGS_((WidgetPtr wPtr));
EXTERN void Tix_GrFreeElem _ANSI_ARGS_((TixGrEntry * chPtr));
EXTERN void Tix_GrFreeUnusedColors _ANSI_ARGS_((WidgetPtr wPtr,
int freeAll));
EXTERN void Tix_GrScrollPage _ANSI_ARGS_((WidgetPtr wPtr,
int count, int axis));
/*
* The dataset functions
*/
EXTERN int TixGridDataConfigRowColSize _ANSI_ARGS_((
Tcl_Interp * interp, WidgetPtr wPtr,
TixGridDataSet * dataSet, int which, int index,
int argc, CONST84 char ** argv, CONST84 char * argcErrorMsg,
int *changed_ret));
EXTERN CONST84 char * TixGridDataCreateEntry _ANSI_ARGS_((
TixGridDataSet * dataSet, int x, int y,
CONST84 char * defaultEntry));
EXTERN int TixGridDataDeleteEntry _ANSI_ARGS_((
TixGridDataSet * dataSet, int x, int y));
EXTERN void TixGridDataDeleteRange _ANSI_ARGS_((WidgetPtr wPtr,
TixGridDataSet * dataSet, int which,
int from, int to));
EXTERN void TixGridDataDeleteSearchedEntry _ANSI_ARGS_((
Tix_GrDataCellSearch * cellSearchPtr));
EXTERN char * TixGridDataFindEntry _ANSI_ARGS_((
TixGridDataSet * dataSet, int x, int y));
EXTERN int TixGrDataFirstCell _ANSI_ARGS_((
Tix_GrDataRowSearch * rowSearchPtr,
Tix_GrDataCellSearch * cellSearchPtr));
EXTERN int TixGrDataFirstRow _ANSI_ARGS_((
TixGridDataSet* dataSet,
Tix_GrDataRowSearch * rowSearchPtr));
EXTERN int TixGridDataGetRowColSize _ANSI_ARGS_((
WidgetPtr wPtr, TixGridDataSet * dataSet,
int which, int index, TixGridSize * defSize,
int *pad0, int * pad1));
EXTERN void TixGridDataGetGridSize _ANSI_ARGS_((
TixGridDataSet * dataSet, int *width_ret,
int *height_ret));
EXTERN int TixGridDataGetIndex _ANSI_ARGS_((
Tcl_Interp * interp, WidgetPtr wPtr,
CONST84 char * xStr, CONST84 char * yStr,
int * xPtr, int * yPtr));
EXTERN void TixGridDataInsert _ANSI_ARGS_((
TixGridDataSet * dataSet,
int x, int y, ClientData data));
EXTERN void TixGridDataMoveRange _ANSI_ARGS_((WidgetPtr wPtr,
TixGridDataSet * dataSet, int which,
int from, int to, int by));
EXTERN int TixGrDataNextCell _ANSI_ARGS_((
Tix_GrDataCellSearch * cellSearchPtr));
EXTERN int TixGrDataNextRow _ANSI_ARGS_((
Tix_GrDataRowSearch * rowSearchPtr));
EXTERN TixGridDataSet* TixGridDataSetInit _ANSI_ARGS_((void));
EXTERN void TixGridDataSetFree _ANSI_ARGS_((
TixGridDataSet* dataSet));
EXTERN int TixGridDataUpdateSort _ANSI_ARGS_((
TixGridDataSet * dataSet, int axis,
int start, int end, Tix_GrSortItem *items));
#endif /*_TIX_GRID_H_*/

407
generic/tixHLCol.c Normal file
View File

@@ -0,0 +1,407 @@
/* $Id: tixHLCol.c,v 1.2 2004/03/28 02:44:56 hobbs Exp $ */
/*
* tixHLCol.c ---
*
*
* Implements columns inside tixHList widgets
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#include <tixPort.h>
#include <tixInt.h>
#include <tixHList.h>
static TIX_DECLARE_SUBCMD(Tix_HLItemCreate);
static TIX_DECLARE_SUBCMD(Tix_HLItemConfig);
static TIX_DECLARE_SUBCMD(Tix_HLItemCGet);
static TIX_DECLARE_SUBCMD(Tix_HLItemDelete);
static TIX_DECLARE_SUBCMD(Tix_HLItemExists);
static TIX_DECLARE_SUBCMD(Tix_HLColWidth);
static HListElement * Tix_HLGetColumn(Tcl_Interp *interp, WidgetPtr wPtr,
CONST84 char ** argv, int * column_ret, int mustExist);
HListColumn *
Tix_HLAllocColumn(wPtr, chPtr)
WidgetPtr wPtr;
HListElement * chPtr;
{
HListColumn * column;
int i;
column =
(HListColumn*)ckalloc(sizeof(HListColumn)*wPtr->numColumns);
for (i=0; i<wPtr->numColumns; i++) {
column[i].type = HLTYPE_COLUMN;
column[i].self = (char*)&column[i];
column[i].chPtr = chPtr;
column[i].iPtr = NULL;
column[i].iPtr = NULL;
column[i].width = UNINITIALIZED;
}
return column;
}
static HListElement *
Tix_HLGetColumn(interp, wPtr, argv, column_ret, mustExist)
Tcl_Interp *interp;
WidgetPtr wPtr;
CONST84 char ** argv;
int * column_ret;
int mustExist;
{
HListElement * chPtr;
int column;
if ((chPtr = Tix_HLFindElement(interp, wPtr, argv[0])) == NULL) {
return NULL;
}
if (Tcl_GetInt(interp, argv[1], &column) != TCL_OK) {
return NULL;
}
if (column >= wPtr->numColumns || column < 0) {
Tcl_AppendResult(interp, "Column \"", argv[1],
"\" does not exist", (char*)NULL);
return NULL;
}
if (mustExist && chPtr->col[column].iPtr == NULL) {
Tcl_AppendResult(interp, "entry \"", argv[0],
"\" does not have an item at column ", argv[1], NULL);
return NULL;
}
* column_ret = column;
return chPtr;
}
/*----------------------------------------------------------------------
* "item" sub command
*----------------------------------------------------------------------
*/
int
Tix_HLItem(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
static Tix_SubCmdInfo subCmdInfo[] = {
{TIX_DEFAULT_LEN, "cget", 3, 3, Tix_HLItemCGet,
"entryPath column option"},
{TIX_DEFAULT_LEN, "configure", 2, TIX_VAR_ARGS, Tix_HLItemConfig,
"entryPath column ?option? ?value ...?"},
{TIX_DEFAULT_LEN, "create", 2, TIX_VAR_ARGS, Tix_HLItemCreate,
"entryPath column ?option value ...?"},
{TIX_DEFAULT_LEN, "delete", 2, 2, Tix_HLItemDelete,
"entryPath column"},
{TIX_DEFAULT_LEN, "exists", 2, 2, Tix_HLItemExists,
"entryPath column"},
};
static Tix_CmdInfo cmdInfo = {
Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "?option? ?arg ...?",
};
return Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData,
interp, argc+1, argv-1);
}
/*----------------------------------------------------------------------
* "item cget" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLItemCGet(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListElement * chPtr;
int column;
if ((chPtr=Tix_HLGetColumn(interp, wPtr, argv, &column, 1)) == NULL) {
return TCL_ERROR;
}
return Tk_ConfigureValue(interp, wPtr->dispData.tkwin,
chPtr->col[column].iPtr->base.diTypePtr->itemConfigSpecs,
(char *)chPtr->col[column].iPtr, argv[2], 0);
}
/*----------------------------------------------------------------------
* "item configure" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLItemConfig(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListElement * chPtr;
int column;
if ((chPtr=Tix_HLGetColumn(interp, wPtr, argv, &column, 1)) == NULL) {
return TCL_ERROR;
}
if (argc == 2) {
return Tk_ConfigureInfo(interp, wPtr->dispData.tkwin,
chPtr->col[column].iPtr->base.diTypePtr->itemConfigSpecs,
(char *)chPtr->col[column].iPtr, NULL, 0);
} else if (argc == 3) {
return Tk_ConfigureInfo(interp, wPtr->dispData.tkwin,
chPtr->col[column].iPtr->base.diTypePtr->itemConfigSpecs,
(char *)chPtr->col[column].iPtr, argv[2], 0);
} else {
Tix_HLMarkElementDirty(wPtr, chPtr);
Tix_HLResizeWhenIdle(wPtr);
return Tix_DItemConfigure(chPtr->col[column].iPtr,
argc-2, argv+2, TK_CONFIG_ARGV_ONLY);
}
}
/*----------------------------------------------------------------------
* "item create" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLItemCreate(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListElement * chPtr;
int column, i;
size_t len;
Tix_DItem * iPtr;
CONST84 char * ditemType = NULL;
if ((chPtr=Tix_HLGetColumn(interp, wPtr, argv, &column, 0)) == NULL) {
return TCL_ERROR;
}
if (argc %2) {
Tcl_AppendResult(interp, "value for \"", argv[argc-1],
"\" missing", NULL);
return TCL_ERROR;
}
for (i=2; i<argc; i+=2) {
len = strlen(argv[i]);
if (strncmp(argv[i], "-itemtype", len) == 0) {
ditemType = argv[i+1];
}
}
if (ditemType == NULL) {
ditemType = wPtr->diTypePtr->name;
}
iPtr = Tix_DItemCreate(&wPtr->dispData, ditemType);
if (iPtr == NULL) {
return TCL_ERROR;
}
iPtr->base.clientData = (ClientData)&chPtr->col[column];
if (Tix_DItemConfigure(iPtr, argc-2, argv+2, 0) != TCL_OK) {
return TCL_ERROR;
}
if (chPtr->col[column].iPtr != NULL) {
if (Tix_DItemType(chPtr->col[column].iPtr) == TIX_DITEM_WINDOW) {
Tix_WindowItemListRemove(&wPtr->mappedWindows,
chPtr->col[column].iPtr);
}
Tix_DItemFree(chPtr->col[column].iPtr);
}
chPtr->col[column].iPtr = iPtr;
Tix_HLMarkElementDirty(wPtr, chPtr);
Tix_HLResizeWhenIdle(wPtr);
return TCL_OK;
}
/*----------------------------------------------------------------------
* "item delete" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLItemDelete(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListElement * chPtr;
int column;
if ((chPtr=Tix_HLGetColumn(interp, wPtr, argv, &column, 1)) == NULL) {
return TCL_ERROR;
}
if (column == 0) {
Tcl_AppendResult(interp,"Cannot delete item at column 0",(char*)NULL);
return TCL_ERROR;
}
if (Tix_DItemType(chPtr->col[column].iPtr) == TIX_DITEM_WINDOW) {
Tix_WindowItemListRemove(&wPtr->mappedWindows,
chPtr->col[column].iPtr);
}
/* Free the item and leave a blank */
Tix_DItemFree(chPtr->col[column].iPtr);
chPtr->col[column].iPtr = NULL;
Tix_HLMarkElementDirty(wPtr, chPtr);
Tix_HLResizeWhenIdle(wPtr);
return TCL_OK;
}
/*----------------------------------------------------------------------
* "item exists" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLItemExists(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListElement * chPtr;
int column;
if ((chPtr=Tix_HLGetColumn(interp, wPtr, argv, &column, 0)) == NULL) {
return TCL_ERROR;
}
if (chPtr->col[column].iPtr == NULL) {
Tcl_AppendResult(interp, "0", NULL);
} else {
Tcl_AppendResult(interp, "1", NULL);
}
return TCL_OK;
}
/*----------------------------------------------------------------------
* "column" sub command
*----------------------------------------------------------------------
*/
int
Tix_HLColumn(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
static Tix_SubCmdInfo subCmdInfo[] = {
{TIX_DEFAULT_LEN, "width", 1, 3, Tix_HLColWidth,
"column ?-char? ?size?"},
};
static Tix_CmdInfo cmdInfo = {
Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "?option? ?arg ...?",
};
return Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData,
interp, argc+1, argv-1);
}
/*----------------------------------------------------------------------
* "column width" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLColWidth(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
int column;
char buff[128];
int newWidth;
if (Tcl_GetInt(interp, argv[0], &column) != TCL_OK) {
return TCL_ERROR;
}
if (column >= wPtr->numColumns || column < 0) {
Tcl_AppendResult(interp, "Column \"", argv[0],
"\" does not exist", (char*)NULL);
return TCL_ERROR;
}
if (argc == 1) { /* Query */
if (wPtr->root->dirty || wPtr->allDirty) {
/* We must update the geometry NOW otherwise we will get a wrong
* width
*/
Tix_HLCancelResizeWhenIdle(wPtr);
Tix_HLComputeGeometry((ClientData)wPtr);
}
sprintf(buff, "%d", wPtr->actualSize[column].width);
Tcl_AppendResult(interp, buff, NULL);
return TCL_OK;
}
else if (argc == 2) {
if (argv[1][0] == '\0') {
newWidth = UNINITIALIZED;
goto setwidth;
}
if (Tk_GetPixels(interp, wPtr->dispData.tkwin, argv[1],
&newWidth) != TCL_OK) {
return TCL_ERROR;
}
if (newWidth < 0) {
newWidth = 0;
}
}
else if (argc == 3 && strcmp(argv[1], "-char")==0) {
if (argv[2][0] == '\0') {
newWidth = UNINITIALIZED;
goto setwidth;
}
if (Tcl_GetInt(interp, argv[2], &newWidth) != TCL_OK) {
return TCL_ERROR;
}
if (newWidth < 0) {
newWidth = 0;
}
newWidth *= wPtr->scrollUnit[0];
}
else {
return Tix_ArgcError(interp, argc+3, argv-3, 3,
"column ?-char? ?size?");
}
setwidth:
if (wPtr->reqSize[column].width == newWidth) {
return TCL_OK;
} else {
wPtr->reqSize[column].width = newWidth;
}
if (wPtr->actualSize[column].width == newWidth) {
return TCL_OK;
} else {
wPtr->allDirty = 1;
Tix_HLResizeWhenIdle(wPtr);
return TCL_OK;
}
}

580
generic/tixHLHdr.c Normal file
View File

@@ -0,0 +1,580 @@
/* $Id: tixHLHdr.c,v 1.3 2004/03/28 02:44:56 hobbs Exp $ */
/*
* tixHLHdr.c ---
*
*
* Implements headers for tixHList widgets
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#include <tixPort.h>
#include <tixInt.h>
#include <tixHList.h>
#include <tixDef.h>
static TIX_DECLARE_SUBCMD(Tix_HLHdrCreate);
static TIX_DECLARE_SUBCMD(Tix_HLHdrConfig);
static TIX_DECLARE_SUBCMD(Tix_HLHdrCGet);
static TIX_DECLARE_SUBCMD(Tix_HLHdrDelete);
static TIX_DECLARE_SUBCMD(Tix_HLHdrExist);
static TIX_DECLARE_SUBCMD(Tix_HLHdrSize);
static void FreeWindowItem _ANSI_ARGS_((Tcl_Interp *interp,
WidgetPtr wPtr, HListHeader *hPtr));
static void FreeHeader _ANSI_ARGS_((Tcl_Interp *interp,
WidgetPtr wPtr, HListHeader *hPtr));
static HListHeader* AllocHeader _ANSI_ARGS_((Tcl_Interp *interp,
WidgetPtr wPtr));
static HListHeader* Tix_HLGetHeader _ANSI_ARGS_((Tcl_Interp * interp,
WidgetPtr wPtr, CONST84 char * string,
int requireIPtr));
static Tk_ConfigSpec headerConfigSpecs[] = {
{TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,
(char *) NULL, 0, 0},
{TK_CONFIG_PIXELS, "-borderwidth", "headerBorderWidth", "BorderWidth",
DEF_HLISTHEADER_BORDER_WIDTH, Tk_Offset(HListHeader, borderWidth), 0},
{TK_CONFIG_BORDER, "-headerbackground", "headerBackground", "Background",
DEF_HLISTHEADER_BG_COLOR, Tk_Offset(HListHeader, background),
TK_CONFIG_COLOR_ONLY},
{TK_CONFIG_BORDER, "-headerbackground", "headerBackground", "Background",
DEF_HLISTHEADER_BG_MONO, Tk_Offset(HListHeader, background),
TK_CONFIG_MONO_ONLY},
{TK_CONFIG_RELIEF, "-relief", "headerRelief", "Relief",
DEF_HLISTHEADER_RELIEF, Tk_Offset(HListHeader, relief), 0},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, 0}
};
/*----------------------------------------------------------------------
*
* Local functions
*
*----------------------------------------------------------------------
*/
static HListHeader*
AllocHeader(interp, wPtr)
Tcl_Interp *interp;
WidgetPtr wPtr;
{
HListHeader * hPtr = (HListHeader*)ckalloc(sizeof(HListHeader));
hPtr->type = HLTYPE_HEADER;
hPtr->self = (char*)hPtr;
hPtr->wPtr = wPtr;
hPtr->iPtr = NULL;
hPtr->width = 0;
hPtr->background = NULL;
hPtr->relief = TK_RELIEF_RAISED;
hPtr->borderWidth = 2;
if (Tk_ConfigureWidget(interp, wPtr->dispData.tkwin, headerConfigSpecs,
0, 0, (char *)hPtr, 0) != TCL_OK) {
/* some unrecoverable errors */
return NULL;
}
return hPtr;
}
static void
FreeWindowItem(interp, wPtr, hPtr)
Tcl_Interp *interp;
WidgetPtr wPtr;
HListHeader *hPtr;
{
Tix_WindowItemListRemove(&wPtr->mappedWindows,
hPtr->iPtr);
}
static void
FreeHeader(interp, wPtr, hPtr)
Tcl_Interp *interp;
WidgetPtr wPtr;
HListHeader *hPtr;
{
if (hPtr->iPtr) {
if (Tix_DItemType(hPtr->iPtr) == TIX_DITEM_WINDOW) {
FreeWindowItem(interp, wPtr, hPtr);
}
Tix_DItemFree(hPtr->iPtr);
}
Tk_FreeOptions(headerConfigSpecs, (char *)hPtr, wPtr->dispData.display, 0);
ckfree((char*) hPtr);
}
static HListHeader*
Tix_HLGetHeader(interp, wPtr, string, requireIPtr)
Tcl_Interp * interp;
WidgetPtr wPtr;
CONST84 char * string;
int requireIPtr;
{
int column;
if (Tcl_GetInt(interp, string, &column) != TCL_OK) {
return NULL;
}
if (column >= wPtr->numColumns || column < 0) {
Tcl_AppendResult(interp, "Column \"", string,
"\" does not exist", (char*)NULL);
return NULL;
}
if (requireIPtr && wPtr->headers[column]->iPtr == NULL) {
Tcl_AppendResult(interp, "Column \"", string,
"\" does not have a header", (char*)NULL);
return NULL;
}
return wPtr->headers[column];
}
int
Tix_HLCreateHeaders(interp, wPtr)
Tcl_Interp *interp;
WidgetPtr wPtr;
{
int i;
wPtr->headers = (HListHeader**)
ckalloc(sizeof(HListHeader*) * wPtr->numColumns);
for (i=0; i<wPtr->numColumns; i++) {
wPtr->headers[i] = NULL;
}
for (i=0; i<wPtr->numColumns; i++) {
if ((wPtr->headers[i] = AllocHeader(interp, wPtr)) == NULL) {
return TCL_ERROR;
}
}
wPtr->headerDirty = 1;
return TCL_OK;
}
void Tix_HLFreeHeaders(interp, wPtr)
Tcl_Interp *interp;
WidgetPtr wPtr;
{
int i;
if (wPtr->headers == NULL) {
return;
}
for (i=0; i<wPtr->numColumns; i++) {
if (wPtr->headers[i] != NULL) {
FreeHeader(interp, wPtr, wPtr->headers[i]);
}
}
ckfree((char*)wPtr->headers);
}
void
Tix_HLDrawHeader(wPtr, pixmap, gc, hdrX, hdrY, hdrW, hdrH, xOffset)
WidgetPtr wPtr;
Pixmap pixmap;
GC gc;
int hdrX;
int hdrY;
int hdrW;
int hdrH;
int xOffset;
{
int i, x, y;
int drawnWidth; /* how much of the header have I drawn? */
int width; /* width of the current header item */
int winItemExtra; /* window items need a bit extra offset
* because they must be places relative to
* the main window, not the header subwindow
*/
x = hdrX - xOffset;
y = hdrY;
drawnWidth = 0;
winItemExtra = wPtr->borderWidth + wPtr->highlightWidth;
if (wPtr->needToRaise) {
/* the needToRaise flag is set every time a new window item is
* created inside the header of the HList.
*
* We need to make sure that the windows items in the list
* body are clipped by the header subwindow. However, the window
* items inside the header should be over the header subwindow.
*
* The two XRaiseWindow calls in this function make sure that
* the stacking relationship as described above always hold
*/
XRaiseWindow(Tk_Display(wPtr->headerWin),
Tk_WindowId(wPtr->headerWin));
}
for (i=0; i<wPtr->numColumns; i++) {
HListHeader * hPtr = wPtr->headers[i];
width = wPtr->actualSize[i].width;
if (i == wPtr->numColumns-1) {
/* If the widget is wider than required,
* We need to extend the last item to the end of the list,
* or otherwise we'll see a curtailed header
*/
if (drawnWidth + width <hdrW) {
width = hdrW - drawnWidth;
}
}
Tk_Fill3DRectangle(wPtr->dispData.tkwin, pixmap, hPtr->background,
x, y, width, wPtr->headerHeight, hPtr->borderWidth,
hPtr->relief);
/* Note when we draw the item, we use the
* wPtr->actualSize[i].width instead of the (possibly extended) width
* so that the header is well-aligned with the element columns.
*/
if (hPtr->iPtr) {
int itemX, itemY;
itemX = x+hPtr->borderWidth;
itemY = y+hPtr->borderWidth;
if (Tix_DItemType(hPtr->iPtr) == TIX_DITEM_WINDOW) {
itemX += winItemExtra;
itemY += winItemExtra;
}
Tix_DItemDisplay(pixmap, hPtr->iPtr,
itemX, itemY,
wPtr->actualSize[i].width - 2*hPtr->borderWidth,
wPtr->headerHeight - 2*hPtr->borderWidth,
0, 0,
TIX_DITEM_NORMAL_FG);
if (wPtr->needToRaise &&
Tix_DItemType(hPtr->iPtr) == TIX_DITEM_WINDOW) {
TixWindowItem * wiPtr;
wiPtr = (TixWindowItem *)hPtr->iPtr;
if (Tk_WindowId(wiPtr->tkwin) == None) {
Tk_MakeWindowExist(wiPtr->tkwin);
}
XRaiseWindow(Tk_Display(wiPtr->tkwin),
Tk_WindowId(wiPtr->tkwin));
}
}
x += width;
drawnWidth += width;
#if 0
/* %% funny, doesn't work */
if (drawnWidth >= hdrW) {
/* The rest is invisible. Don't bother to draw */
break;
}
#endif
}
wPtr->needToRaise = 0;
}
void Tix_HLComputeHeaderGeometry(wPtr)
WidgetPtr wPtr;
{
int i;
wPtr->headerHeight = 0;
for (i=0; i<wPtr->numColumns; i++) {
int height;
int width;
if (wPtr->headers[i]->iPtr) {
width = Tix_DItemWidth (wPtr->headers[i]->iPtr);
height = Tix_DItemHeight(wPtr->headers[i]->iPtr);
} else {
width = 0;
height = 0;
}
width += wPtr->headers[i]->borderWidth * 2;
height += wPtr->headers[i]->borderWidth * 2;
wPtr->headers[i]->width = width;
if (height > wPtr->headerHeight) {
wPtr->headerHeight = height;
}
}
wPtr->headerDirty = 0;
}
/*----------------------------------------------------------------------
* "header" sub command
*----------------------------------------------------------------------
*/
int
Tix_HLHeader(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
static Tix_SubCmdInfo subCmdInfo[] = {
{TIX_DEFAULT_LEN, "cget", 2, 2, Tix_HLHdrCGet,
"column option"},
{TIX_DEFAULT_LEN, "configure", 1, TIX_VAR_ARGS, Tix_HLHdrConfig,
"column ?option? ?value ...?"},
{TIX_DEFAULT_LEN, "create", 1, TIX_VAR_ARGS, Tix_HLHdrCreate,
"column ?option value ...?"},
{TIX_DEFAULT_LEN, "delete", 1, 1, Tix_HLHdrDelete,
"column"},
{TIX_DEFAULT_LEN, "exist", 1, 1, Tix_HLHdrExist,
"column"},
{TIX_DEFAULT_LEN, "size", 1, 1, Tix_HLHdrSize,
"column"},
};
static Tix_CmdInfo cmdInfo = {
Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "?option? ?arg ...?",
};
return Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData,
interp, argc+1, argv-1);
}
/*----------------------------------------------------------------------
* "header cget" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLHdrCGet(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListHeader * hPtr;
if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 1)) == NULL) {
return TCL_ERROR;
}
return Tix_ConfigureValue2(interp, wPtr->dispData.tkwin,
(char*)hPtr, headerConfigSpecs, hPtr->iPtr, argv[1], 0);
}
/*----------------------------------------------------------------------
* "header configure" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLHdrConfig(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListHeader * hPtr;
if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 1)) == NULL) {
return TCL_ERROR;
}
if (argc == 1) {
return Tix_ConfigureInfo2(interp, wPtr->dispData.tkwin,
(char*)hPtr, headerConfigSpecs, hPtr->iPtr,
(char *) NULL, 0);
} else if (argc == 2) {
return Tix_ConfigureInfo2(interp, wPtr->dispData.tkwin,
(char*)hPtr, headerConfigSpecs, hPtr->iPtr,
(char *) argv[1], 0);
} else {
int sizeChanged = 0;
if (Tix_WidgetConfigure2(interp, wPtr->dispData.tkwin,
(char*)hPtr, headerConfigSpecs, hPtr->iPtr,
argc-1, argv+1, TK_CONFIG_ARGV_ONLY, 0, &sizeChanged) != TCL_OK) {
return TCL_ERROR;
}
if (sizeChanged) {
wPtr->headerDirty = 1;
Tix_HLResizeWhenIdle(wPtr);
}
return TCL_OK;
}
}
/*----------------------------------------------------------------------
* "header create" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLHdrCreate(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListHeader * hPtr;
int i;
Tix_DItem * iPtr;
CONST84 char * ditemType = NULL;
if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 0)) == NULL) {
return TCL_ERROR;
}
if ((argc %2) == 0) {
Tcl_AppendResult(interp, "value for \"", argv[argc-1],
"\" missing", NULL);
return TCL_ERROR;
}
for (i=1; i<argc; i+=2) {
if (strncmp(argv[i], "-itemtype", strlen(argv[i])) == 0) {
ditemType = argv[i+1];
}
}
if (ditemType == NULL) {
ditemType = wPtr->diTypePtr->name;
}
iPtr = Tix_DItemCreate(&wPtr->dispData, ditemType);
if (iPtr == NULL) {
return TCL_ERROR;
}
if (Tix_DItemType(iPtr) == TIX_DITEM_WINDOW) {
wPtr->needToRaise = 1;
}
/*
* mark clientData to NULL. This will tell DItemSizeChanged()
* that ths item belongs to the header
*/
iPtr->base.clientData = (ClientData)hPtr;
if (hPtr->iPtr != NULL) {
if (Tix_DItemType(hPtr->iPtr) == TIX_DITEM_WINDOW) {
FreeWindowItem(interp, wPtr, hPtr);
}
Tix_DItemFree(hPtr->iPtr);
}
hPtr->iPtr = iPtr;
if (Tix_WidgetConfigure2(wPtr->dispData.interp, wPtr->dispData.tkwin,
(char*)hPtr, headerConfigSpecs, hPtr->iPtr, argc-1, argv+1, 0,
1, NULL) != TCL_OK) {
return TCL_ERROR;
}
wPtr->headerDirty = 1;
Tix_HLResizeWhenIdle(wPtr);
return TCL_OK;
}
/*----------------------------------------------------------------------
* "header delete" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLHdrDelete(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListHeader * hPtr;
if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 1)) == NULL) {
return TCL_ERROR;
}
if (Tix_DItemType(hPtr->iPtr) == TIX_DITEM_WINDOW) {
FreeWindowItem(interp, wPtr, hPtr);
}
/* Free the item and leave a blank! */
Tix_DItemFree(hPtr->iPtr);
hPtr->iPtr = NULL;
wPtr->headerDirty = 1;
Tix_HLResizeWhenIdle(wPtr);
return TCL_OK;
}
/*----------------------------------------------------------------------
* "header exist" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLHdrExist(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListHeader * hPtr;
if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 0)) == NULL) {
return TCL_ERROR;
}
if (hPtr->iPtr == NULL) {
Tcl_AppendResult(interp, "0", NULL);
} else {
Tcl_AppendResult(interp, "1", NULL);
}
return TCL_OK;
}
/*----------------------------------------------------------------------
* "header size" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLHdrSize(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListHeader * hPtr;
char buff[128];
if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 1)) == NULL) {
return TCL_ERROR;
}
if (hPtr->iPtr == NULL) {
Tcl_AppendResult(interp, "entry \"", argv[0],
"\" does not have a header", (char*)NULL);
return TCL_ERROR;
}
sprintf(buff, "%d %d",
Tix_DItemWidth(hPtr->iPtr),
Tix_DItemHeight(hPtr->iPtr));
Tcl_AppendResult(interp, buff, NULL);
return TCL_OK;
}

281
generic/tixHLInd.c Normal file
View File

@@ -0,0 +1,281 @@
/* $Id: tixHLInd.c,v 1.2 2004/03/28 02:44:56 hobbs Exp $ */
/*
* tixHLInd.c ---
*
* Implements indicators inside tixHList widgets
*
* Copyright (c) 1994-1995 Ioi Kim Lam. All rights reserved.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#include <tixPort.h>
#include <tixInt.h>
#include <tixHList.h>
static TIX_DECLARE_SUBCMD(Tix_HLIndCreate);
static TIX_DECLARE_SUBCMD(Tix_HLIndConfig);
static TIX_DECLARE_SUBCMD(Tix_HLIndCGet);
static TIX_DECLARE_SUBCMD(Tix_HLIndDelete);
static TIX_DECLARE_SUBCMD(Tix_HLIndExists);
static TIX_DECLARE_SUBCMD(Tix_HLIndSize);
/*----------------------------------------------------------------------
* "indicator" sub command
*----------------------------------------------------------------------
*/
int
Tix_HLIndicator(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
static Tix_SubCmdInfo subCmdInfo[] = {
{TIX_DEFAULT_LEN, "cget", 2, 2, Tix_HLIndCGet,
"entryPath option"},
{TIX_DEFAULT_LEN, "configure", 1, TIX_VAR_ARGS, Tix_HLIndConfig,
"entryPath ?option? ?value ...?"},
{TIX_DEFAULT_LEN, "create", 1, TIX_VAR_ARGS, Tix_HLIndCreate,
"entryPath ?option value ...?"},
{TIX_DEFAULT_LEN, "delete", 1, 1, Tix_HLIndDelete,
"entryPath"},
{TIX_DEFAULT_LEN, "exists", 1, 1, Tix_HLIndExists,
"entryPath"},
{TIX_DEFAULT_LEN, "size", 1, 1, Tix_HLIndSize,
"entryPath"},
};
static Tix_CmdInfo cmdInfo = {
Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "?option? ?arg ...?",
};
return Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData,
interp, argc+1, argv-1);
}
/*----------------------------------------------------------------------
* "indicator cget" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLIndCGet(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListElement * chPtr;
if ((chPtr = Tix_HLFindElement(interp, wPtr, argv[0])) == NULL) {
return TCL_ERROR;
}
if (chPtr->indicator == NULL) {
Tcl_AppendResult(interp, "entry \"", argv[0],
"\" does not have an indicator", (char*)NULL);
return TCL_ERROR;
}
return Tk_ConfigureValue(interp, wPtr->dispData.tkwin,
chPtr->indicator->base.diTypePtr->itemConfigSpecs,
(char *)chPtr->indicator, argv[1], 0);
}
/*----------------------------------------------------------------------
* "indicator configure" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLIndConfig(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListElement * chPtr;
if ((chPtr = Tix_HLFindElement(interp, wPtr, argv[0])) == NULL) {
return TCL_ERROR;
}
if (chPtr->indicator == NULL) {
Tcl_AppendResult(interp, "entry \"", argv[0],
"\" does not have an indicator", (char*)NULL);
return TCL_ERROR;
}
if (argc == 1) {
return Tk_ConfigureInfo(interp, wPtr->dispData.tkwin,
chPtr->indicator->base.diTypePtr->itemConfigSpecs,
(char *)chPtr->indicator, NULL, 0);
} else if (argc == 2) {
return Tk_ConfigureInfo(interp, wPtr->dispData.tkwin,
chPtr->indicator->base.diTypePtr->itemConfigSpecs,
(char *)chPtr->indicator, argv[1], 0);
} else {
Tix_HLMarkElementDirty(wPtr, chPtr);
Tix_HLResizeWhenIdle(wPtr);
return Tix_DItemConfigure(chPtr->indicator,
argc-1, argv+1, TK_CONFIG_ARGV_ONLY);
}
}
/*----------------------------------------------------------------------
* "indicator create" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLIndCreate(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListElement * chPtr;
int i;
size_t len;
Tix_DItem * iPtr;
CONST84 char * ditemType = NULL;
if ((chPtr = Tix_HLFindElement(interp, wPtr, argv[0])) == NULL) {
return TCL_ERROR;
}
if ((argc %2) == 0) {
Tcl_AppendResult(interp, "value for \"", argv[argc-1],
"\" missing", NULL);
return TCL_ERROR;
}
for (i=1; i<argc; i+=2) {
len = strlen(argv[i]);
if (strncmp(argv[i], "-itemtype", len) == 0) {
ditemType = argv[i+1];
}
}
if (ditemType == NULL) {
ditemType = wPtr->diTypePtr->name;
}
iPtr = Tix_DItemCreate(&wPtr->dispData, ditemType);
if (iPtr == NULL) {
return TCL_ERROR;
}
if (Tix_DItemType(iPtr) == TIX_DITEM_WINDOW) {
wPtr->needToRaise = 1;
}
iPtr->base.clientData = (ClientData)chPtr;
if (Tix_DItemConfigure(iPtr, argc-1, argv+1, 0) != TCL_OK) {
return TCL_ERROR;
}
if (chPtr->indicator != NULL) {
if (Tix_DItemType(chPtr->indicator) == TIX_DITEM_WINDOW) {
Tix_WindowItemListRemove(&wPtr->mappedWindows,
chPtr->indicator);
}
Tix_DItemFree(chPtr->indicator);
}
chPtr->indicator = iPtr;
Tix_HLMarkElementDirty(wPtr, chPtr);
Tix_HLResizeWhenIdle(wPtr);
return TCL_OK;
}
/*----------------------------------------------------------------------
* "indicator delete" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLIndDelete(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListElement * chPtr;
if ((chPtr = Tix_HLFindElement(interp, wPtr, argv[0])) == NULL) {
return TCL_ERROR;
}
if (chPtr->indicator == NULL) {
Tcl_AppendResult(interp, "entry \"", argv[0],
"\" does not have an indicator", (char*)NULL);
return TCL_ERROR;
}
if (Tix_DItemType(chPtr->indicator) == TIX_DITEM_WINDOW) {
Tix_WindowItemListRemove(&wPtr->mappedWindows,
chPtr->indicator);
}
/* Free the item and leave a blank! */
Tix_DItemFree(chPtr->indicator);
chPtr->indicator = NULL;
Tix_HLMarkElementDirty(wPtr, chPtr);
Tix_HLResizeWhenIdle(wPtr);
return TCL_OK;
}
/*----------------------------------------------------------------------
* "indicator exists" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLIndExists(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListElement * chPtr;
if ((chPtr = Tix_HLFindElement(interp, wPtr, argv[0])) == NULL) {
return TCL_ERROR;
}
if (chPtr->indicator == NULL) {
Tcl_AppendResult(interp, "0", NULL);
} else {
Tcl_AppendResult(interp, "1", NULL);
}
return TCL_OK;
}
/*----------------------------------------------------------------------
* "indicator size" sub command
*----------------------------------------------------------------------
*/
static int
Tix_HLIndSize(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
HListElement * chPtr;
char buff[100];
if ((chPtr = Tix_HLFindElement(interp, wPtr, argv[0])) == NULL) {
return TCL_ERROR;
}
if (chPtr->indicator == NULL) {
Tcl_AppendResult(interp, "entry \"", argv[0],
"\" does not have an indicator", (char*)NULL);
return TCL_ERROR;
}
sprintf(buff, "%d %d",
Tix_DItemWidth(chPtr->indicator),
Tix_DItemHeight(chPtr->indicator));
Tcl_AppendResult(interp, buff, NULL);
return TCL_OK;
}

4452
generic/tixHList.c Normal file

File diff suppressed because it is too large Load Diff

319
generic/tixHList.h Normal file
View File

@@ -0,0 +1,319 @@
/* $Id: tixHList.h,v 1.2 2004/03/28 02:44:56 hobbs Exp $ */
/*
* tixHList.h --
*
* Defines the data structures and functions used by the tixHList
* widget.
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#ifndef _TIX_HLIST_H_
#define _TIX_HLIST_H_
#ifndef _TIX_INT_H_
#include <tixInt.h>
#endif
#define HLTYPE_COLUMN 1
#define HLTYPE_HEADER 2
#define HLTYPE_ENTRY 3
/* This is used to indetify what object has caused a DItemSizeChange
* All data structs for objects that manage DItems must have these two
* members as the beginning of the struct.
*/
typedef struct HLItemTypeInfo {
int type;
char * self;
} HLItemTypeInfo;
typedef struct HListColumn {
/* generic type info section */
int type;
char * self;
struct _HListElement * chPtr;
/* other data */
Tix_DItem * iPtr;
int width;
} HListColumn;
typedef struct HListHeader {
/* generic type info section */
int type;
char * self;
struct HListStruct * wPtr;
/* other data */
Tix_DItem * iPtr;
int width;
Tk_3DBorder background; /* Used for drawing the 3d border. */
int relief; /* Indicates whether window as a whole is
* raised, sunken, or flat. */
int borderWidth;
} HListHeader;
/*----------------------------------------------------------------------
* A HListElement structure contain the information about each element
* inside the HList.
*
*/
typedef struct _HListElement {
/* generic type info section */
int type;
char * self;
/* other data */
struct HListStruct * wPtr;
struct _HListElement * parent;
struct _HListElement * prev;
struct _HListElement * next;
struct _HListElement * childHead;
struct _HListElement * childTail;
int numSelectedChild; /* number of childs that has selection(s) in
* them (either this child is selected or some
* of its descendants are selected */
int numCreatedChild; /* this var gets increment by one each
* time a child is created */
char * pathName; /* Full pathname of this element */
char * name; /* Name of this element */
int height; /* Height of this element, including padding
* and selBorderWidth;
*/
int allHeight; /* Height of all descendants and self */
Tk_Uid state; /* State of Tab's for display purposes:
* normal or disabled. */
char * data; /* user data field */
/* bottom-middle position of the bitmap/image branch (offset from
* the top-left corner of the item)
*/
int branchX;
int branchY;
/* offset of the left-middle position of the icon */
int iconX;
int iconY;
/*----------------------------------*/
/* Things to display in the element */
/*----------------------------------*/
HListColumn * col; /* the multi-column display items */
HListColumn _oneCol; /* If we have only one column, then this
* space is used (pointed to by column).
* This will save one Malloc */
int indent;
Tix_DItem * indicator; /* indicator: little triangle on Mac */
/*----------------------------------*/
/* Flags */
/*----------------------------------*/
Tix_DItemInfo * diTypePtr;
unsigned int selected : 1;
unsigned int hidden : 1;
unsigned int dirty : 1; /* If it is dirty then its geometry needs
* be recalculated */
} Tix_HListElement, HListElement;
/*
* A data structure of the following type is kept for each
* widget managed by this file:
*/
typedef struct HListStruct {
Tix_DispData dispData;
Tcl_Command widgetCmd; /* Token for button's widget command. */
/*
* Information used when displaying widget:
*/
char *command; /* Command prefix to use when invoking
* scrolling commands. NULL means don't
* invoke commands. Malloc'ed. */
int width, height; /* For app programmer to request size */
/*
* Information used when displaying widget:
*/
/* Border and general drawing */
int borderWidth; /* Width of 3-D borders. */
int selBorderWidth; /* Width of 3-D borders for selected items */
int relief; /* Indicates whether window as a whole is
* raised, sunken, or flat. */
int indent; /* How much should the children be indented
* (to the right)?, in pixels */
Tk_3DBorder border; /* Used for drawing the 3d border. */
Tk_3DBorder selectBorder; /* Used for selected background. */
XColor *normalFg; /* Normal foreground for text. */
XColor *normalBg; /* Normal bachground for text. */
XColor *selectFg; /* Color for drawing selected text. */
TixFont font; /* The default font used in the DItems. */
GC backgroundGC; /* GC for drawing background. */
GC normalGC; /* GC for drawing text in normal mode. */
GC selectGC; /* GC for drawing selected background. */
GC anchorGC; /* GC for drawing dotted anchor highlight. */
GC dropSiteGC; /* GC for drawing dotted anchor highlight. */
Cursor cursor; /* Current cursor for window, or None. */
int topPixel; /* Vertical offset */
int leftPixel; /* Horizontal offset */
int bottomPixel;
int wideSelect; /* BOOL: if 1, use a wide selection: the
* selection background color covers the whole
* widget. If 0, only the "significant" part
* of a list entry is highlighted */
int selectWidth; /* Width of the selection: takes effect only
* if wideSelect == 1 */
/* For highlights */
int highlightWidth; /* Width in pixels of highlight to draw
* around widget when it has the focus.
* <= 0 means don't draw a highlight. */
XColor *highlightColorPtr; /* Color for drawing traversal highlight. */
GC highlightGC; /* For drawing traversal highlight. */
/* default pad and gap values */
int gap, padX, padY;
char * separator;
Tk_Uid selectMode; /* Selection style: single, browse, multiple,
* or extended. This value isn't used in C
* code, but the Tcl bindings use it. */
int drawBranch; /* Whether to draw the "branch" lines from
* parent entry to children */
Tcl_HashTable childTable; /* Hash table to translate child names
* into (HListElement *) */
HListElement * root; /* Mother of all elements */
HListElement * anchor; /* The current anchor item */
HListElement * dragSite; /* The current drag site */
HListElement * dropSite; /* The current drop site */
char *yScrollCmd; /* Command prefix for communicating with
* vertical scrollbar. NULL means no command
* to issue. Malloc'ed. */
char *xScrollCmd; /* Command prefix for communicating with
* horizontal scrollbar. NULL means no command
* to issue. Malloc'ed. */
char *sizeCmd; /* The command to call when the size of
* the listbox changes. E.g., when the user
* add/deletes elements. Useful for
* auto-scrollbar geometry managers */
char *browseCmd; /* The command to call when the selection
* changes. */
char *indicatorCmd; /* The command to call when the user touches
* the indicator. */
char *dragCmd; /* The command to call when info about a
* drag source is needed */
char *dropCmd; /* The command to call when action at a drop
* side needs to be performed */
char *takeFocus; /* Value of -takefocus option; not used in
* the C code, but used by keyboard traversal
* scripts. Malloc'ed, but may be NULL. */
Tix_LinkList mappedWindows; /* Those windows that are are mapped by this
* widget*/
int serial; /* this number is incremented before each time
* the widget is redisplayed */
int numColumns; /* number of columns in the tixHList widget,
* cannot be changed after the widget's
* creation */
int totalSize[2];
HListColumn * reqSize; /* Requested column sizes by the user:
take precedence */
HListColumn * actualSize; /* Actual column sizes, calculated using
* the sizes of the ditems */
HListHeader ** headers; /* Stores all the headers for a HList widget */
int useHeader; /* whether headers should be used */
int headerHeight; /* required height of the header */
Tix_DItemInfo * diTypePtr; /* Default item type */
Tix_StyleTemplate stTmpl;
int useIndicator; /* should indicators be displayed */
int scrollUnit[2];
Tk_Window headerWin; /* subwindow, used to draw the headers */
char * elmToSee; /* name of element to "see" the next time
* this widget is redrawn */
unsigned redrawing : 1;
unsigned redrawingFrame : 1;
unsigned resizing : 1;
unsigned hasFocus : 1;
unsigned allDirty : 1;
unsigned initialized : 1;
unsigned headerDirty : 1;
unsigned needToRaise : 1; /* The header subwindow needs to be raised
* if we add a new window item into the
* HList widget (either in the list or
* in the header */
} HList;
#define TIX_X 0
#define TIX_Y 1
#define UNINITIALIZED -1
typedef HList WidgetRecord;
typedef HList * WidgetPtr;
EXTERN HListColumn * Tix_HLAllocColumn _ANSI_ARGS_((
WidgetPtr wPtr, HListElement * chPtr));
EXTERN void Tix_HLCancelResizeWhenIdle _ANSI_ARGS_((
WidgetPtr wPtr));
EXTERN void Tix_HLComputeGeometry _ANSI_ARGS_((
ClientData clientData));
EXTERN HListElement * Tix_HLFindElement _ANSI_ARGS_((Tcl_Interp *interp,
WidgetPtr wPtr, CONST84 char * pathName));
EXTERN void Tix_HLFreeMappedWindow _ANSI_ARGS_((WidgetPtr wPtr,
HListElement * chPtr));
EXTERN int Tix_HLElementTopOffset _ANSI_ARGS_((
WidgetPtr wPtr, HListElement *chPtr));
EXTERN int Tix_HLElementLeftOffset _ANSI_ARGS_((
WidgetPtr wPtr, HListElement *chPtr));
EXTERN int Tix_HLItemInfo _ANSI_ARGS_((Tcl_Interp *interp,
WidgetPtr wPtr, int argc, CONST84 char** argv));
EXTERN int Tix_HLHeader _ANSI_ARGS_((ClientData clientData,
Tcl_Interp *interp, int argc, CONST84 char **argv));
EXTERN int Tix_HLCreateHeaders _ANSI_ARGS_((
Tcl_Interp *interp, WidgetPtr wPtr));
EXTERN void Tix_HLFreeHeaders _ANSI_ARGS_((
Tcl_Interp *interp, WidgetPtr wPtr));
EXTERN void Tix_HLDrawHeader _ANSI_ARGS_((
WidgetPtr wPtr, Pixmap pixmap, GC gc,
int hdrX, int hdrY, int hdrW, int hdrH,
int xOffset));
EXTERN void Tix_HLComputeHeaderGeometry _ANSI_ARGS_((
WidgetPtr wPtr));
EXTERN void Tix_HLMarkElementDirty _ANSI_ARGS_((WidgetPtr wPtr,
HListElement *chPtr));
EXTERN void Tix_HLResizeWhenIdle _ANSI_ARGS_((WidgetPtr wPtr));
EXTERN void Tix_HLResizeNow _ANSI_ARGS_((WidgetPtr wPtr));
EXTERN void Tix_HLComputeGeometry _ANSI_ARGS_((
ClientData clientData));
EXTERN void Tix_HLCancelResizeWhenIdle _ANSI_ARGS_((
WidgetPtr wPtr));
/* in tixHLCol.c */
EXTERN TIX_DECLARE_SUBCMD(Tix_HLColumn);
EXTERN TIX_DECLARE_SUBCMD(Tix_HLItem);
/* in tixHLInd.c */
EXTERN TIX_DECLARE_SUBCMD(Tix_HLIndicator);
#endif /*_TIX_HLIST_H_ */

1513
generic/tixImgCmp.c Normal file

File diff suppressed because it is too large Load Diff

1304
generic/tixImgXpm.c Normal file

File diff suppressed because it is too large Load Diff

134
generic/tixImgXpm.h Normal file
View File

@@ -0,0 +1,134 @@
/* $Id: tixImgXpm.h,v 1.1.1.1 2000/05/17 11:08:42 idiscovery Exp $ */
/*
* tixImgXpm.h --
*
* Generic header file for the pixmap image type. This is NOT a public
* header file!
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#ifndef _TIX_IMG_XPM_H_
#define _TIX_IMG_XPM_H_
/*
* Constants
*/
#define XPM_MONO 1
#define XPM_GRAY_4 2
#define XPM_GRAY 3
#define XPM_COLOR 4
#define XPM_SYMBOLIC 5
#define XPM_UNKNOWN 6
/*
* The following data structure represents the master for a pixmap
* image:
*/
typedef struct PixmapMaster {
Tk_ImageMaster tkMaster; /* Tk's token for image master. NULL means
* the image is being deleted. */
Tcl_Interp *interp; /* Interpreter for application that is
* using image. */
Tcl_Command imageCmd; /* Token for image command (used to delete
* it when the image goes away). NULL means
* the image command has already been
* deleted. */
char *fileString; /* Value of -file option (malloc'ed).
* valid only if the -file option is specified
*/
char *dataString; /* Value of -data option (malloc'ed).
* valid only if the -data option is specified
*/
/* First in list of all instances associated
* with this master. */
Tk_Uid id; /* ID's for XPM data already compiled
* into the tixwish binary */
int size[2]; /* width and height */
int ncolors; /* number of colors */
int cpp; /* characters per pixel */
char ** data; /* The data that defines this pixmap
* image (array of strings). It is
* converted into an X Pixmap when this
* image is instanciated
*/
int isDataAlloced; /* False iff the data is got from
* the -id switch */
struct PixmapInstance *instancePtr;
} PixmapMaster;
typedef struct ColorStruct {
char c; /* This is used if CPP is one */
char * cstring; /* This is used if CPP is bigger than one */
XColor * colorPtr;
} ColorStruct;
/*----------------------------------------------------------------------
* PixmapInstance --
*
* Represents all of the instances of an image that lie within a
* particular window:
*
* %% ToDo
* Currently one instance is created for each window that uses
* this pixmap. This is usually OK because pixmaps are usually
* not shared or only shared by a small number of windows. To
* improve resource allocation, we can create an instance for
* each (Display x Visual x Depth) combo. This will usually
* reduce the number of instances to one.
*----------------------------------------------------------------------
*/
typedef struct PixmapInstance {
int refCount; /* Number of instances that share this
* data structure. */
PixmapMaster *masterPtr; /* Pointer to master for image. */
Tk_Window tkwin; /* Window in which the instances will be
* displayed. */
Pixmap pixmap; /* The pixmap to display. */
struct PixmapInstance *nextPtr;
/* Next in list of all instance structures
* associated with masterPtr (NULL means
* end of list).
*/
ColorStruct * colors;
ClientData clientData; /* Place holder for platform specific
* instance data */
} PixmapInstance;
EXTERN void TixpInitPixmapInstance _ANSI_ARGS_((
PixmapMaster *masterPtr,
PixmapInstance *instancePtr));
EXTERN void TixpXpmAllocTmpBuffer _ANSI_ARGS_((
PixmapMaster * masterPtr,
PixmapInstance * instancePtr,
XImage ** imagePtr, XImage ** maskPtr));
EXTERN void TixpXpmFreeTmpBuffer _ANSI_ARGS_((
PixmapMaster * masterPtr,
PixmapInstance * instancePtr,
XImage * image, XImage * mask));
EXTERN void TixpXpmSetPixel _ANSI_ARGS_((
PixmapInstance * instancePtr, XImage * image,
XImage * mask, int x, int y, XColor * colorPtr,
int * isTranspPtr));
EXTERN void TixpXpmRealizePixmap _ANSI_ARGS_((
PixmapMaster * masterPtr,
PixmapInstance * instancePtr,
XImage * image, XImage * mask, int isTransp));
EXTERN void TixpXpmFreeInstanceData _ANSI_ARGS_((
PixmapInstance *instancePtr, int delete,
Display *display));
EXTERN void TixpXpmDisplay _ANSI_ARGS_((ClientData clientData,
Display *display, Drawable drawable,
int imageX, int imageY, int width, int height,
int drawableX, int drawableY));
#endif

367
generic/tixInit.c Normal file
View File

@@ -0,0 +1,367 @@
/* $Id: tixInit.c,v 1.20 2008/02/28 22:25:56 hobbs Exp $ */
/*
* tixInit.c --
*
* Initialze the Tix native code as well as the script library.
*
* Copyright (c) 1993-1999 Ioi Kim Lam.
* Copyright (c) 2000-2001 Tix Project Group.
* Copyright 2004 ActiveState
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tixInit.c,v 1.20 2008/02/28 22:25:56 hobbs Exp $
*/
#include <tixPort.h>
#include <tixInt.h>
/*
* Minimum required version of Tcl and Tk. These are used when we access
* Tcl/Tk using the stubs API.
*/
#define MIN_TCL_VERSION "8.4"
#define MIN_TK_VERSION "8.4"
/*
* All the Tix commands implemented in C code.
*/
static Tix_TclCmd commands[] = {
/*
* Commands that are part of the intrinsics:
*/
{"tixCallMethod", Tix_CallMethodCmd},
{"tixChainMethod", Tix_ChainMethodCmd},
{"tixClass", Tix_ClassCmd},
{"tixDisplayStyle", Tix_ItemStyleCmd},
{"tixDoWhenIdle", Tix_DoWhenIdleCmd},
{"tixDoWhenMapped", Tix_DoWhenMappedCmd},
{"tixFlushX", Tix_FlushXCmd},
{"tixForm", Tix_FormCmd},
{"tixGeometryRequest", Tix_GeometryRequestCmd},
{"tixGet3DBorder", Tix_Get3DBorderCmd},
{"tixGetDefault", Tix_GetDefaultCmd},
{"tixGetMethod", Tix_GetMethodCmd},
{"tixGrid", Tix_GridCmd},
{"tixHandleOptions", Tix_HandleOptionsCmd},
{"tixHList", Tix_HListCmd},
#if !defined(__WIN32__) && !defined(MAC_OSX_TK)
{"tixInputOnly", Tix_InputOnlyCmd},
#endif
{"tixManageGeometry", Tix_ManageGeometryCmd},
{"tixMapWindow", Tix_MapWindowCmd},
{"tixMoveResizeWindow", Tix_MoveResizeWindowCmd},
#if !defined(__WIN32__) && !defined(MAC_OSX_TK)
{"tixMwm", Tix_MwmCmd},
#endif
{"tixNoteBookFrame", Tix_NoteBookFrameCmd},
{"tixTList", Tix_TListCmd},
{"tixTmpLine", Tix_TmpLineCmd},
{"tixUnmapWindow", Tix_UnmapWindowCmd},
{"tixWidgetClass", Tix_ClassCmd},
{"tixWidgetDoWhenIdle", Tix_DoWhenIdleCmd},
{(char *) NULL, (Tix_CmdProc)NULL}
};
typedef struct {
char * binding;
int isDebug;
char * fontSet;
char * scheme;
char * schemePriority;
} OptionStruct;
static OptionStruct tixOption;
/*
* TIX_DEF_FONTSET and TIX_DEF_SCHEME should have been defined in the
* Makefile by the configure script. We define them here just in case
* the configure script failed to determine the proper values.
*/
#ifndef TIX_DEF_FONTSET
#define TIX_DEF_FONTSET "WmDefault"
#endif
#ifndef TIX_DEF_SCHEME
#define TIX_DEF_SCHEME "WmDefault"
#endif
#define DEF_TIX_TOOLKIT_OPTION_BINDING "TK"
#define DEF_TIX_TOOLKIT_OPTION_DEBUG "0"
#define DEF_TIX_TOOLKIT_OPTION_FONTSET TIX_DEF_FONTSET
#define DEF_TIX_TOOLKIT_OPTION_SCHEME TIX_DEF_SCHEME
#define DEF_TIX_TOOLKIT_OPTION_SCHEME_PRIORITY "20" /* widgetDefault */
static Tk_ConfigSpec configSpecs[] = {
{TK_CONFIG_STRING, "-binding", "binding", "TixBinding",
DEF_TIX_TOOLKIT_OPTION_BINDING, Tk_Offset(OptionStruct, binding),
0},
{TK_CONFIG_BOOLEAN, "-debug", "tixDebug", "TixDebug",
DEF_TIX_TOOLKIT_OPTION_DEBUG, Tk_Offset(OptionStruct, isDebug),
0},
{TK_CONFIG_STRING, "-fontset", "tixFontSet", "TixFontSet",
DEF_TIX_TOOLKIT_OPTION_FONTSET, Tk_Offset(OptionStruct, fontSet),
0},
{TK_CONFIG_STRING, "-scheme", "tixScheme", "TixScheme",
DEF_TIX_TOOLKIT_OPTION_SCHEME, Tk_Offset(OptionStruct, scheme),
0},
{TK_CONFIG_STRING, "-schemepriority", "tixSchemePriority", "TixSchemePriority",
DEF_TIX_TOOLKIT_OPTION_SCHEME_PRIORITY,
Tk_Offset(OptionStruct, schemePriority),
0},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, 0}
};
/*----------------------------------------------------------------------
*
* Some global variables
*
*----------------------------------------------------------------------
*/
Tk_Uid tixNormalUid = (Tk_Uid)NULL;
Tk_Uid tixCellUid = (Tk_Uid)NULL;
Tk_Uid tixRowUid = (Tk_Uid)NULL;
Tk_Uid tixColumnUid = (Tk_Uid)NULL;
Tk_Uid tixDisabledUid = (Tk_Uid)NULL;
static int ParseToolkitOptions _ANSI_ARGS_((Tcl_Interp * interp));
/*
*----------------------------------------------------------------------
* ParseToolkitOptions() --
*
* Before the Tix initialized, we need to determine the toolkit
* options which are set by the options database.
*
* Results:
* A standard Tcl completion code (TCL_OK or TCL_ERROR). Also
* leaves information in the interp's result.
*
* Side effects:
* Sets several variables in the global Tcl array "tixPriv".
*
*----------------------------------------------------------------------
*/
static int
ParseToolkitOptions(interp)
Tcl_Interp * interp;
{
char buff[10];
int flag;
tixOption.binding = NULL;
tixOption.isDebug = 0;
tixOption.fontSet = NULL;
tixOption.scheme = NULL;
tixOption.schemePriority = NULL;
/*
* The toolkit options may be set in the resources of the main
* window, probably by using your .Xdefaults file.
*/
if (Tk_ConfigureWidget(interp, Tk_MainWindow(interp), configSpecs,
0, 0, (char *) &tixOption, 0) != TCL_OK) {
return TCL_ERROR;
}
/*
* Now lets set the Tix toolkit variables so that the Toolkit can
* initialize according to user options.
*/
flag = TCL_GLOBAL_ONLY;
Tcl_SetVar2(interp, "tix_priv", "-binding",
tixOption.binding, flag);
sprintf(buff, "%d", tixOption.isDebug);
Tcl_SetVar2(interp, "tix_priv", "-debug",
buff, flag);
Tcl_SetVar2(interp, "tix_priv", "-fontset",
tixOption.fontSet, flag);
Tcl_SetVar2(interp, "tix_priv", "-scheme",
tixOption.scheme, flag);
Tcl_SetVar2(interp, "tix_priv", "-schemepriority",
tixOption.schemePriority, flag);
Tk_FreeOptions(configSpecs, (char *)&tixOption,
Tk_Display(Tk_MainWindow(interp)), 0);
return TCL_OK;
}
/*
*------------------------------------------------------------------------
* Package initialization.
* tcl_findLibrary basename version patch initScript enVarName varName
* We use patchLevel instead of version as we use the full patchlevel
* in the directory naming on install.
*------------------------------------------------------------------------
*/
static char initScript[] = "if {[info proc tixInit]==\"\"} {\n\
proc tixInit {} {\n\
global tix_library tix_version tix_patchLevel\n\
rename tixInit {}\n\
tcl_findLibrary Tix $tix_patchLevel $tix_patchLevel Init.tcl TIX_LIBRARY tix_library\n\
}\n\
}\n\
tixInit";
/*
*----------------------------------------------------------------------
*
* Tix_Init() --
*
* Initialize the Tix library.
*
* Results:
* A standard Tcl completion code (TCL_OK or TCL_ERROR). Also
* leaves information in the interp's result.
*
* Side effects:
* Sets "tix_library" Tcl variable, runs "Init.tcl" script from
* the Tix script library directory.
*
*----------------------------------------------------------------------
*/
int
Tix_Init(interp)
Tcl_Interp * interp;
{
Tk_Window topLevel;
/*
* This procedure may be called several times for several
* interpreters. Since some global variables are shared by
* all of the interpreters, we initialize these variables only
* once. The variable "globalInitialized" keeps track of this
*/
static int globalInitialized = 0;
#ifdef USE_TCL_STUBS
if ((Tcl_InitStubs(interp, MIN_TK_VERSION, 0) == NULL)
|| (Tk_InitStubs(interp, MIN_TK_VERSION, 0) == NULL)) {
return TCL_ERROR;
}
#else
if ((Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 1) == NULL)
|| (Tcl_PkgRequire(interp, "Tk", TK_VERSION, 1) == NULL)) {
return TCL_ERROR;
}
#endif /* USE_TCL_STUBS */
if (Tcl_PkgProvide(interp, "Tix", TIX_PATCH_LEVEL) != TCL_OK) {
return TCL_ERROR;
}
if (!globalInitialized) {
globalInitialized = 1;
/*
* Initialize the global variables shared by all interpreters
*/
tixNormalUid = Tk_GetUid("normal");
tixCellUid = Tk_GetUid("cell");
tixRowUid = Tk_GetUid("row");
tixColumnUid = Tk_GetUid("column");
tixDisabledUid = Tk_GetUid("disabled");
#if !defined(__WIN32__) && !defined(MAC_OSX_TK)
/* This is for tixMwm command */
Tk_CreateGenericHandler(TixMwmProtocolHandler, NULL);
#endif
/*
* Initialize the image readers
*/
Tk_CreateImageType(&tixPixmapImageType);
Tk_CreateImageType(&tixCompoundImageType);
/*
* Initialize the display item subsystem.
*/
TixInitializeDisplayItems();
}
/*
* Initialize the per-interpreter variables
*/
/* Set the "tix_version" variable */
Tcl_SetVar(interp, "tix_version", TIX_VERSION, TCL_GLOBAL_ONLY);
Tcl_SetVar(interp, "tix_patchLevel", TIX_PATCH_LEVEL,TCL_GLOBAL_ONLY);
Tcl_SetVar(interp, "tix_release", TIX_RELEASE, TCL_GLOBAL_ONLY);
/*
* Initialize the Tix commands
*/
topLevel = Tk_MainWindow(interp);
Tix_CreateCommands(interp, commands, (ClientData) topLevel,
(void (*)_ANSI_ARGS_((ClientData))) NULL);
/*
* Parse options database for fontSets, schemes, etc
*/
if (ParseToolkitOptions(interp) == TCL_ERROR) {
return TCL_ERROR;
}
/*
* In normal operation mode, we use the command defined in
* tixInitScript to load the Tix library scripts off the file
* system
*/
return Tcl_EvalEx(interp, initScript, -1, TCL_GLOBAL_ONLY);
}
/*----------------------------------------------------------------------
* Tix_SafeInit --
*
* Initializes Tix for a safe interpreter.
*
* TODO: the week security check in Tix is probably not complete
* and may lead to security holes. This function is temporarily
* disabled.
*
* Results:
* A standard Tcl completion code (TCL_OK or TCL_ERROR). Also
* leaves information in the interp's result.
*
* Side effects:
* Sets "tix_library" Tcl variable, runs "Init.tcl" script from
* the Tix script library directory.
*
*----------------------------------------------------------------------
*/
int
Tix_SafeInit(interp)
Tcl_Interp * interp;
{
#if 0
Tcl_SetVar2(interp, "tix_priv", "isSafe", "1", TCL_GLOBAL_ONLY);
return Tix_Init(interp);
#else
Tcl_AppendResult(interp, "Tix has not been tested for use in a safe ",
"interppreter. Modify tixInit.c at your own risks", NULL);
return TCL_ERROR;
#endif
}

446
generic/tixInputO.c Normal file
View File

@@ -0,0 +1,446 @@
/* $Id: tixInputO.c,v 1.4 2008/02/28 04:05:29 hobbs Exp $ */
/*
* tixInputO.c --
*
* This module implements "InputOnly" widgets.
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*
*/
#include <tkInt.h>
#include <tixPort.h>
#include <tix.h>
#ifndef MAC_OSX_TK
/*
* A data structure of the following type is kept for each
* widget managed by this file:
*/
typedef struct Tix_InputOnlyStruct {
Tk_Window tkwin; /* Window that embodies the widget. NULL
* means window has been deleted but
* widget record hasn't been cleaned up yet. */
Tcl_Command widgetCmd; /* Token for button's widget command. */
Display *display; /* X's token for the window's display. */
Tcl_Interp *interp; /* Interpreter associated with widget. */
/*
* Information used when displaying widget:
*/
int width;
int height;
/* Cursor */
Cursor cursor; /* Current cursor for window, or None. */
int changed;
} Tix_InputOnly;
typedef Tix_InputOnly WidgetRecord;
typedef Tix_InputOnly * WidgetPtr;
/*
* hint:: Place these into a default.f file
*/
#define DEF_INPUTONLY_CURSOR ""
#define DEF_INPUTONLY_WIDTH "0"
#define DEF_INPUTONLY_HEIGHT "0"
/*
* Information used for argv parsing.
*/
static Tk_ConfigSpec configSpecs[] = {
{TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
DEF_INPUTONLY_CURSOR, Tk_Offset(WidgetRecord, cursor),
TK_CONFIG_NULL_OK},
{TK_CONFIG_PIXELS, "-height", "height", "Height",
DEF_INPUTONLY_HEIGHT, Tk_Offset(WidgetRecord, height), 0},
{TK_CONFIG_PIXELS, "-width", "width", "Width",
DEF_INPUTONLY_WIDTH, Tk_Offset(WidgetRecord, width), 0},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, 0}
};
/*
* Forward declarations for procedures defined later in this file:
*/
static void WidgetCmdDeletedProc _ANSI_ARGS_((
ClientData clientData));
static int WidgetConfigure _ANSI_ARGS_((Tcl_Interp *interp,
WidgetPtr wPtr, int argc, CONST84 char **argv,
int flags));
static void WidgetDestroy _ANSI_ARGS_((ClientData clientData));
static void WidgetEventProc _ANSI_ARGS_((ClientData clientData,
XEvent *eventPtr));
static int WidgetCommand _ANSI_ARGS_((ClientData clientData,
Tcl_Interp *, int argc, CONST84 char **argv));
static void Tix_MakeInputOnlyWindowExist _ANSI_ARGS_((
WidgetPtr wPtr));
#define INPUT_ONLY_EVENTS_MASK \
KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask| \
EnterWindowMask|LeaveWindowMask|PointerMotionMask| \
VisibilityChangeMask|SubstructureNotifyMask| \
FocusChangeMask|PropertyChangeMask
static XSetWindowAttributes inputOnlyAtts = {
None, /* background_pixmap */
0, /* background_pixel */
None, /* border_pixmap */
0, /* border_pixel */
ForgetGravity, /* bit_gravity */
NorthWestGravity, /* win_gravity */
NotUseful, /* backing_store */
(unsigned) ~0, /* backing_planes */
0, /* backing_pixel */
False, /* save_under */
INPUT_ONLY_EVENTS_MASK, /* event_mask */
0, /* do_not_propagate_mask */
False, /* override_redirect */
None, /* colormap */
None /* cursor */
};
static
void Tix_MakeInputOnlyWindowExist(wPtr)
WidgetPtr wPtr;
{
TkWindow* winPtr;
Tcl_HashEntry *hPtr;
int new;
Window parent;
winPtr = (TkWindow*) wPtr->tkwin;
inputOnlyAtts.cursor = winPtr->atts.cursor;
if (winPtr->flags & TK_TOP_LEVEL) {
parent = XRootWindow(winPtr->display, winPtr->screenNum);
} else {
if (winPtr->parentPtr->window == None) {
Tk_MakeWindowExist((Tk_Window) winPtr->parentPtr);
}
parent = winPtr->parentPtr->window;
}
winPtr->window = XCreateWindow(winPtr->display,
parent,
winPtr->changes.x, winPtr->changes.y,
(unsigned) winPtr->changes.width,
(unsigned) winPtr->changes.height,
0, 0,
InputOnly,
CopyFromParent,
CWEventMask|CWCursor,
&inputOnlyAtts);
hPtr = Tcl_CreateHashEntry(&winPtr->dispPtr->winTable,
(char *) winPtr->window, &new);
Tcl_SetHashValue(hPtr, winPtr);
winPtr->dirtyAtts = 0;
winPtr->dirtyChanges = 0;
#ifdef TK_USE_INPUT_METHODS
winPtr->inputContext = NULL;
#endif /* TK_USE_INPUT_METHODS */
}
/*
*--------------------------------------------------------------
*
* Tix_InputOnlyCmd --
*
* This procedure is invoked to process the "inputOnly" Tcl
* command. It creates a new "InputOnly" widget.
*
* Results:
* A standard Tcl result.
*
* Side effects:
* A new widget is created and configured.
*
*--------------------------------------------------------------
*/
int
Tix_InputOnlyCmd(clientData, interp, argc, argv)
ClientData clientData; /* Main window associated with
* interpreter. */
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
Tk_Window mainwin = (Tk_Window) clientData;
WidgetPtr wPtr;
Tk_Window tkwin;
if (argc < 2) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
argv[0], " pathName ?options?\"", (char *) NULL);
return TCL_ERROR;
}
tkwin = Tk_CreateWindowFromPath(interp, mainwin, argv[1], (char *) NULL);
if (tkwin == NULL) {
return TCL_ERROR;
}
/*
* Allocate and initialize the widget record.
*/
wPtr = (WidgetPtr) ckalloc(sizeof(WidgetRecord));
wPtr->tkwin = tkwin;
wPtr->display = Tk_Display(tkwin);
wPtr->interp = interp;
wPtr->width = 0;
wPtr->height = 0;
wPtr->cursor = None;
wPtr->changed = 0;
Tk_SetClass(tkwin, "TixInputOnly");
Tix_MakeInputOnlyWindowExist(wPtr);
Tk_CreateEventHandler(wPtr->tkwin, StructureNotifyMask,
WidgetEventProc, (ClientData) wPtr);
wPtr->widgetCmd = Tcl_CreateCommand(interp, Tk_PathName(wPtr->tkwin),
WidgetCommand, (ClientData) wPtr, WidgetCmdDeletedProc);
if (WidgetConfigure(interp, wPtr, argc-2, argv+2, 0) != TCL_OK) {
Tk_DestroyWindow(wPtr->tkwin);
return TCL_ERROR;
}
Tcl_SetResult(interp, Tk_PathName(wPtr->tkwin), TCL_STATIC);
return TCL_OK;
}
/*
*--------------------------------------------------------------
*
* WidgetCommand --
*
* This procedure is invoked to process the Tcl command
* that corresponds to a widget managed by this module.
* See the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
*
* Side effects:
* See the user documentation.
*
*--------------------------------------------------------------
*/
static int
WidgetCommand(clientData, interp, argc, argv)
ClientData clientData; /* Information about the widget. */
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
int result = TCL_OK;
size_t length;
char c;
if (argc < 2) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
argv[0], " option ?arg arg ...?\"", (char *) NULL);
return TCL_ERROR;
}
Tk_Preserve((ClientData) wPtr);
c = argv[1][0];
length = strlen(argv[1]);
if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)) {
if (argc == 2) {
result = Tk_ConfigureInfo(interp, wPtr->tkwin, configSpecs,
(char *) wPtr, (char *) NULL, 0);
} else if (argc == 3) {
result = Tk_ConfigureInfo(interp, wPtr->tkwin, configSpecs,
(char *) wPtr, argv[2], 0);
} else {
result = WidgetConfigure(interp, wPtr, argc-2, argv+2,
TK_CONFIG_ARGV_ONLY);
}
}
else if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0)) {
if (argc == 3) {
return Tk_ConfigureValue(interp, wPtr->tkwin, configSpecs,
(char *)wPtr, argv[2], 0);
} else {
return Tix_ArgcError(interp, argc, argv, 2, "option");
}
} else {
Tcl_AppendResult(interp, "bad option \"", argv[1],
"\": must be cget or configure", (char *) NULL);
goto error;
}
Tk_Release((ClientData) wPtr);
return result;
error:
Tk_Release((ClientData) wPtr);
return TCL_ERROR;
}
/*
*----------------------------------------------------------------------
*
* WidgetConfigure --
*
* This procedure is called to process an argv/argc list in
* conjunction with the Tk option database to configure (or
* reconfigure) a InputOnly widget.
*
* Results:
* The return value is a standard Tcl result. If TCL_ERROR is
* returned, then interp's result contains an error message.
*
* Side effects:
* Configuration information, such as colors, border width,
* etc. get set for wPtr; old resources get freed,
* if there were any.
*
*----------------------------------------------------------------------
*/
static int
WidgetConfigure(interp, wPtr, argc, argv, flags)
Tcl_Interp *interp; /* Used for error reporting. */
WidgetPtr wPtr; /* Information about widget. */
int argc; /* Number of valid entries in argv. */
CONST84 char **argv; /* Arguments. */
int flags; /* Flags to pass to
* Tk_ConfigureWidget. */
{
if (Tk_ConfigureWidget(interp, wPtr->tkwin, configSpecs,
argc, argv, (char *) wPtr, flags) != TCL_OK) {
return TCL_ERROR;
}
Tk_GeometryRequest(wPtr->tkwin, wPtr->width, wPtr->height);
return TCL_OK;
}
/*
*--------------------------------------------------------------
*
* WidgetEventProc --
*
* This procedure is invoked by the Tk dispatcher for various
* events on InputOnlys.
*
* Results:
* None.
*
* Side effects:
* When the window gets deleted, internal structures get
* cleaned up. When it gets exposed, it is redisplayed.
*
*--------------------------------------------------------------
*/
static void
WidgetEventProc(clientData, eventPtr)
ClientData clientData; /* Information about window. */
XEvent *eventPtr; /* Information about event. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
switch (eventPtr->type) {
case DestroyNotify:
if (wPtr->tkwin != NULL) {
wPtr->tkwin = NULL;
Tcl_DeleteCommand(wPtr->interp,
Tcl_GetCommandName(wPtr->interp, wPtr->widgetCmd));
}
Tk_EventuallyFree((ClientData) wPtr, (Tix_FreeProc*)WidgetDestroy);
break;
case MapNotify:
case ConfigureNotify:
break;
}
}
/*
*----------------------------------------------------------------------
*
* WidgetDestroy --
*
* This procedure is invoked by Tk_EventuallyFree or Tk_Release
* to clean up the internal structure of a InputOnly at a safe time
* (when no-one is using it anymore).
*
* Results:
* None.
*
* Side effects:
* Everything associated with the InputOnly is freed up.
*
*----------------------------------------------------------------------
*/
static void
WidgetDestroy(clientData)
ClientData clientData; /* Info about my widget. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
Tk_FreeOptions(configSpecs, (char *) wPtr, wPtr->display, 0);
ckfree((char *) wPtr);
}
/*
*----------------------------------------------------------------------
*
* WidgetCmdDeletedProc --
*
* This procedure is invoked when a widget command is deleted. If
* the widget isn't already in the process of being destroyed,
* this command destroys it.
*
* Results:
* None.
*
* Side effects:
* The widget is destroyed.
*
*----------------------------------------------------------------------
*/
static void
WidgetCmdDeletedProc(clientData)
ClientData clientData; /* Pointer to widget record for widget. */
{
WidgetPtr wPtr = (WidgetPtr) clientData;
/*
* This procedure could be invoked either because the window was
* destroyed and the command was then deleted (in which case tkwin
* is NULL) or because the command was deleted, and then this procedure
* destroys the widget.
*/
if (wPtr->tkwin != NULL) {
Tk_Window tkwin = wPtr->tkwin;
wPtr->tkwin = NULL;
Tk_DestroyWindow(tkwin);
}
}
#endif

858
generic/tixInt.h Normal file
View File

@@ -0,0 +1,858 @@
/*
* tixInt.h --
*
* Defines internal data types and functions used by the Tix library.
*
* Copyright (c) 1993-1999 Ioi Kim Lam.
* Copyright (c) 2000-2001 Tix Project Group.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tixInt.h,v 1.7 2008/02/28 04:29:17 hobbs Exp $
*/
#ifndef _TIX_INT_H_
#define _TIX_INT_H_
#ifndef _TIX_H_
#include <tix.h>
#endif
#ifndef _TIX_PORT_H_
#include <tixPort.h>
#endif
/*----------------------------------------------------------------------
*
* Tix Display Item Types
*
*----------------------------------------------------------------------
*/
#define TIX_DITEM_NONE 0
#define TIX_DITEM_TEXT 1
#define TIX_DITEM_IMAGETEXT 2
#define TIX_DITEM_WINDOW 3
#define TIX_DITEM_IMAGE 4
/*
* The following 12 values can be OR'ed to passed as the flags
* parameter to Tix_DItemDisplay().
*/
#define TIX_DITEM_NORMAL_BG (0x1 << 0)
#define TIX_DITEM_ACTIVE_BG (0x1 << 1)
#define TIX_DITEM_SELECTED_BG (0x1 << 2)
#define TIX_DITEM_DISABLED_BG (0x1 << 3)
#define TIX_DITEM_NORMAL_FG (0x1 << 4)
#define TIX_DITEM_ACTIVE_FG (0x1 << 5)
#define TIX_DITEM_SELECTED_FG (0x1 << 6)
#define TIX_DITEM_DISABLED_FG (0x1 << 7)
#define TIX_DITEM_FONT (0x1 << 8)
#define TIX_DITEM_PADX (0x1 << 9)
#define TIX_DITEM_PADY (0x1 << 10)
#define TIX_DITEM_ANCHOR (0x1 << 11)
#define TIX_DITEM_OTHER_BG \
(TIX_DITEM_ACTIVE_BG|TIX_DITEM_SELECTED_BG|TIX_DITEM_DISABLED_BG)
#define TIX_DITEM_ALL_BG \
(TIX_DITEM_NORMAL_BG|TIX_DITEM_OTHER_BG)
#define TIX_DONT_CALL_CONFIG TK_CONFIG_USER_BIT
/*
* These values are used ONLY for indexing the color array in
* Tix_StyleTemplate
*/
#define TIX_DITEM_NORMAL 0
#define TIX_DITEM_ACTIVE 1
#define TIX_DITEM_SELECTED 2
#define TIX_DITEM_DISABLED 3
/*
* Flags for MultiInfo
*/
#define TIX_CONFIG_INFO 1
#define TIX_CONFIG_VALUE 2
typedef union Tix_DItem Tix_DItem;
typedef union Tix_DItemStyle Tix_DItemStyle;
typedef struct Tix_DItemInfo Tix_DItemInfo;
typedef struct Tix_DispData Tix_DispData;
typedef struct Tix_StyleTemplate Tix_StyleTemplate;
typedef void Tix_DItemCalculateSizeProc(Tix_DItem * iPtr);
typedef char * Tix_DItemComponentProc(Tix_DItem * iPtr, int x, int y);
typedef int Tix_DItemConfigureProc(Tix_DItem * iPtr,
int argc, CONST84 char **argv, int flags);
typedef Tix_DItem * Tix_DItemCreateProc(Tix_DispData * ddPtr,
Tix_DItemInfo * diTypePtr);
typedef void Tix_DItemDisplayProc(Drawable drawable,
Tix_DItem * iPtr,
int x, int y, int width, int height,
int xOffset, int yOffset, int flag);
typedef void Tix_DItemFreeProc(Tix_DItem * diPtr);
typedef void Tix_DItemSizeChangedProc(Tix_DItem * iPtr);
typedef void Tix_DItemStyleChangedProc(Tix_DItem * iPtr);
typedef void Tix_DItemLostStyleProc(Tix_DItem * iPtr);
typedef int Tix_DItemStyleConfigureProc(Tix_DItemStyle* style,
int argc, CONST84 char **argv, int flags);
typedef Tix_DItemStyle* Tix_DItemStyleCreateProc(Tcl_Interp * interp,
Tk_Window tkwin,
Tix_DItemInfo * diTypePtr, char * name);
typedef void Tix_DItemStyleFreeProc(Tix_DItemStyle* style);
typedef void Tix_DItemStyleSetTemplateProc(Tix_DItemStyle* style,
Tix_StyleTemplate * tmplPtr);
/*
* These are debugging routines
*/
typedef int Tix_DItemRefCountProc();
typedef int Tix_DItemStyleRefCountProc();
/*----------------------------------------------------------------------
* Tix_DItemInfo --
*
* This structure is used to register a new display item (call
* Tix_AddDItemType).
*----------------------------------------------------------------------
*/
struct Tix_DItemInfo {
char * name;
int type;
/*
* These procedures communicate with the items
*/
Tix_DItemCreateProc * createProc;
Tix_DItemConfigureProc * configureProc;
Tix_DItemCalculateSizeProc * calculateSizeProc;
Tix_DItemComponentProc * componentProc;
Tix_DItemDisplayProc * displayProc;
Tix_DItemFreeProc * freeProc;
Tix_DItemStyleChangedProc *styleChangedProc;
Tix_DItemLostStyleProc * lostStyleProc;
/*
* These procedures communicate with the styles
*/
Tix_DItemStyleCreateProc * styleCreateProc;
Tix_DItemStyleConfigureProc * styleConfigureProc;
Tix_DItemStyleFreeProc * styleFreeProc;
Tix_DItemStyleSetTemplateProc * styleSetTemplateProc;
Tk_ConfigSpec * itemConfigSpecs;
Tk_ConfigSpec * styleConfigSpecs;
struct Tix_DItemInfo * next;
};
/*----------------------------------------------------------------------
* Tix_DispData --
*
* Information needed by the display types to display the item in
* an X drawable.
*----------------------------------------------------------------------
*/
struct Tix_DispData {
Display * display;
Tcl_Interp * interp;
Tk_Window tkwin;
Tix_DItemSizeChangedProc * sizeChangedProc;
};
/*----------------------------------------------------------------------
* Tix_StyleTemplate --
*
* A StyleTemplate is used to set the values of the default styles
* associated with a widget
*----------------------------------------------------------------------
*/
struct Tix_StyleTemplate {
int flags; /* determines which field is valid */
struct {
XColor * bg;
XColor * fg;
} colors[4]; /* colors for the four basic modes*/
int pad[2];
#if 0
/* %bordercolor not used */
XColor * borderColor;
Tix_Relief relief;
int borderWidth;
#endif
TixFont font;
};
/*----------------------------------------------------------------------
*
*
* Display Item Types
*
*
*----------------------------------------------------------------------
*/
/*
* Display Styles
*/
typedef struct TixBaseStyle TixBaseStyle;
typedef struct TixImageTextStyle TixImageTextStyle;
typedef struct TixImageStyle TixImageStyle;
typedef struct TixTextStyle TixTextStyle;
typedef struct TixWindowStyle TixWindowStyle;
typedef struct TixBaseItem TixBaseItem;
typedef struct TixColorStyle TixColorStyle;
typedef struct TixImageTextItem TixImageTextItem;
typedef struct TixImageItem TixImageItem;
typedef struct TixTextItem TixTextItem;
typedef struct TixWindowItem TixWindowItem;
/*----------------------------------------------------------------------
* TixBaseItem --
*
* This is the abstract base class for all display items. All
* display items should have the data members defined in the
* BaseItem structure
*----------------------------------------------------------------------
*/
#define ITEM_COMMON_MEMBERS \
Tix_DItemInfo * diTypePtr; \
Tix_DispData * ddPtr; \
ClientData clientData; \
int size[2]; /* Size of this element */ \
int selX, selY, selW, selH /* Location of the selection highlight */
struct TixBaseItem {
ITEM_COMMON_MEMBERS;
TixBaseStyle * stylePtr;
};
/*----------------------------------------------------------------------
* TixBaseStyle --
*
* This is the abstract base class for all display styles. All
* display items should have the data members defined in the
* BaseStyle structure. The common members are initialized by
* tixDiStyle.c
*
*----------------------------------------------------------------------
*/
#define STYLE_COMMON_MEMBERS \
Tcl_Command styleCmd; /* Token for style's command. */ \
Tcl_HashTable items; /* Ditems affected by this style */ \
int refCount; /* Number of ditems affected by this style */\
int flags; /* Various attributes */ \
Tcl_Interp *interp; /* Interpreter associated with style. */ \
Tk_Window tkwin; /* Window associated with this style */ \
Tix_DItemInfo * diTypePtr; \
Tk_Anchor anchor; /* Anchor information */ \
char * name; /* Name of this style */ \
int pad[2]; /* paddings */ \
\
struct { \
XColor * bg; \
XColor * fg; \
GC foreGC; \
GC backGC; \
GC anchorGC; \
} colors[4] /* colors and GC's for the four basic modes*/
#define STYLE_COLOR_MEMBERS /* Backwards-cimpatibility */
struct TixBaseStyle {
STYLE_COMMON_MEMBERS;
};
#define TIX_STYLE_DELETED 1
#define TIX_STYLE_DEFAULT 2
/*
* Abstract type for all styles that have a color element
*/
struct TixColorStyle {
STYLE_COMMON_MEMBERS;
};
/*----------------------------------------------------------------------
* ImageTextItem --
*
* Display an image together with a text string
*----------------------------------------------------------------------
*/
struct TixImageTextItem {
ITEM_COMMON_MEMBERS;
TixImageTextStyle *stylePtr;
/*-------------------------*/
/* Bitmap */
/*-------------------------*/
Pixmap bitmap;
int bitmapW, bitmapH; /* Size of bitmap */
/*-------------------------*/
/* Image */
/*-------------------------*/
char *imageString; /* Name of image to display (malloc'ed), or
* NULL. If non-NULL, bitmap, text, and
* textVarName are ignored. */
Tk_Image image;
int imageW, imageH; /* Size of image */
/*-------------------------*/
/* Text */
/*-------------------------*/
char * text; /* Show descriptive text */
size_t numChars; /* Size of text */
int textW, textH;
int wrapLength;
Tk_Justify justify; /* Justification to use for multi-line text. */
int underline; /* Index of character to underline. < 0 means
* don't underline anything. */
int showImage, showText;
};
struct TixImageTextStyle {
STYLE_COMMON_MEMBERS;
int wrapLength;
Tk_Justify justify; /* Justification to use for multi-line text. */
TixFont font;
int gap; /* Gap between text and image */
};
/*----------------------------------------------------------------------
* ImageItem --
*
* Displays an image
*----------------------------------------------------------------------
*/
struct TixImageItem {
ITEM_COMMON_MEMBERS;
TixImageStyle *stylePtr;
/*-------------------------*/
/* Image */
/*-------------------------*/
char *imageString; /* Name of image to display (malloc'ed), or
* NULL. If non-NULL, bitmap, text, and
* textVarName are ignored. */
Tk_Image image;
int imageW, imageH; /* Size of image */
};
struct TixImageStyle {
STYLE_COMMON_MEMBERS;
};
/*----------------------------------------------------------------------
* TextItem --
*
* Displays a text string.
*----------------------------------------------------------------------
*/
struct TixTextItem {
ITEM_COMMON_MEMBERS;
TixTextStyle *stylePtr;
/*-------------------------*/
/* Text */
/*-------------------------*/
char * text; /* Show descriptive text */
int numChars; /* Size of text */
int textW, textH;
int underline; /* Index of character to underline. < 0 means
* don't underline anything. */
};
struct TixTextStyle {
STYLE_COMMON_MEMBERS;
int wrapLength;
Tk_Justify justify; /* Justification to use for multi-line text. */
TixFont font;
};
/*----------------------------------------------------------------------
* WindowItem --
*
* Displays a window.
*----------------------------------------------------------------------
*/
struct TixWindowItem {
ITEM_COMMON_MEMBERS;
TixWindowStyle *stylePtr;
Tk_Window tkwin;
struct TixWindowItem * next;
int serial;
};
struct TixWindowStyle {
STYLE_COMMON_MEMBERS;
};
/*----------------------------------------------------------------------
* Tix_DItem and Tix_DItemStyle --
*
* These unions just make it easy to address the internals of the
* structures of the display items and styles. If you create a new
* display item, you will need to do you type casting yourself.
*----------------------------------------------------------------------
*/
union Tix_DItem {
TixBaseItem base;
TixImageTextItem imagetext;
TixTextItem text;
TixWindowItem window;
TixImageItem image;
};
union Tix_DItemStyle {
TixBaseStyle base;
TixColorStyle color;
TixImageTextStyle imagetext;
TixTextStyle text;
TixWindowStyle window;
TixImageStyle image;
};
#define Tix_DItemType(x) ((x)->base.diTypePtr->type)
#define Tix_DItemTypeName(x) ((x)->base.diTypePtr->name)
#define Tix_DItemWidth(x) ((x)->base.size[0])
#define Tix_DItemHeight(x) ((x)->base.size[1])
#define Tix_DItemConfigSpecs(x) ((x)->base.diTypePtr->itemConfigSpecs)
#define Tix_DItemPadX(x) ((x)->base.stylePtr->pad[0])
#define Tix_DItemPadY(x) ((x)->base.stylePtr->pad[1])
#define TIX_WIDTH 0
#define TIX_HEIGHT 1
typedef struct _TixpSubRegion TixpSubRegion;
/*----------------------------------------------------------------------
* Tix_ArgumentList --
*
* This data structure is used to split command arguments for
* the display item types
*----------------------------------------------------------------------
*/
#define FIXED_SIZE 4
typedef struct {
int argc;
CONST84 char **argv;
} Tix_Argument;
typedef struct {
Tix_Argument * arg;
int numLists;
Tix_Argument preAlloc[FIXED_SIZE];
} Tix_ArgumentList;
/*----------------------------------------------------------------------
* Tix_ScrollInfo --
*
* This data structure encapsulates all the necessary operations
* for scrolling widgets
*----------------------------------------------------------------------
*/
#define TIX_SCROLL_INT 1
#define TIX_SCROLL_DOUBLE 2
/* abstract type */
typedef struct Tix_ScrollInfo {
int type; /* TIX_SCROLL_INT or TIX_SCROLL_DOUBLE */
char * command;
} Tix_ScrollInfo;
typedef struct Tix_IntScrollInfo {
int type; /* TIX_SCROLL_INT */
char * command;
int total; /* total size (width or height) of the widget*/
int window; /* visible size */
int offset; /* The top/left side of the scrolled widget */
int unit; /* How much should we scroll when the user
* press the arrow on a scrollbar? */
} Tix_IntScrollInfo;
typedef struct Tix_DoubleScrollInfo {
int type; /* TIX_SCROLL_DOUBLE */
char * command;
double total; /* total size (width or height) of the widget*/
double window; /* visible size */
double offset; /* The top/left side of the scrolled widget */
double unit; /* How much should we scroll when the user
* press the arrow on a scrollbar? */
} Tix_DoubleScrollInfo;
/*----------------------------------------------------------------------
*
* Global variables
*
* Should be used only in the Tix library. Some systems don't support
* exporting of global variables from shared libraries.
*
*----------------------------------------------------------------------
*/
EXTERN Tk_Uid tixNormalUid;
EXTERN Tk_Uid tixDisabledUid;
EXTERN Tk_Uid tixCellUid;
EXTERN Tk_Uid tixRowUid;
EXTERN Tk_Uid tixColumnUid;
#define FLAG_READONLY 0
#define FLAG_STATIC 1
#define FLAG_FORCECALL 2
/*----------------------------------------------------------------------
*
*
* MEGA-WIDGET CONFIG HANDLING
*
*
*----------------------------------------------------------------------
*/
typedef struct _TixConfigSpec TixConfigSpec;
typedef struct _TixConfigAlias TixConfigAlias;
typedef struct _TixClassRecord TixClassRecord;
struct _TixConfigSpec {
unsigned int isAlias : 1;
unsigned int readOnly : 1;
unsigned int isStatic : 1;
unsigned int forceCall : 1;
char *argvName;
char * defValue;
char * dbName; /* The additional parts of a */
char * dbClass; /* TixWidgetConfigSpec structure */
char *verifyCmd;
TixConfigSpec * realPtr; /* valid only if this option is an alias */
};
/*
* Controls the access of root widget and subwidget commands and options
*/
typedef struct _Tix_ExportSpec {
Tix_LinkList exportCmds;
Tix_LinkList restrictCmds;
Tix_LinkList exportOpts;
Tix_LinkList restrictOpts;
} Tix_ExportSpec;
typedef struct _Tix_SubWidgetSpec {
struct _Tix_SubWidgetSpec * next;
CONST84 char * name;
Tix_ExportSpec export;
} Tix_SubWidgetSpec;
typedef struct _Tix_StringLink {
struct _Tix_StringLink *next;
CONST84 char * string;
} Tix_StringLink;
typedef struct _Tix_SubwidgetDef {
struct _TixSubwidgetDef * next;
CONST84 char * spec;
CONST84 char * value;
} Tix_SubwidgetDef;
typedef struct _TixClassParseStruct {
CONST84 char * alias;
CONST84 char * ClassName;
CONST84 char * configSpec;
CONST84 char * def;
CONST84 char * flag;
CONST84 char * forceCall;
CONST84 char * method;
CONST84 char * readOnly;
CONST84 char * isStatic;
CONST84 char * superClass;
CONST84 char * subWidget;
CONST84 char * isVirtual;
int optArgc;
CONST84 char ** optArgv;
} TixClassParseStruct;
struct _TixClassRecord {
TixClassRecord * next; /* Chains to the next class record in
* a superClass's unInitSubCls list */
TixClassRecord * superClass; /* The superclass of this class. Is
* NULL if this class does not have
* a superclass. */
unsigned int isWidget; /* TRUE iff this class is created by
* the "tixWidgetClass" command */
char * className; /* Instiantiation command */
char * ClassName; /* used in TK option database */
int nSpecs;
TixConfigSpec ** specs;
int nMethods;
char ** methods;
Tk_Window mainWindow; /* This variable is essentially
* a cached variable so that
* we can advoid calling
* Tk_MainWindow() */
int isVirtual; /* is this a virtual base class
* (shouldn't be instantiated)*/
TixClassParseStruct*parsePtr; /* Information supplied by the
* tixClass or tixWidgetClass
* commands */
Tix_LinkList unInitSubCls; /* The subclasses that have not been
* initialized. */
int initialized; /* Is this class initialized? A class
* is not initialized if it has been
* defined but some its superclass
* is not initialized.
*/
Tix_LinkList subWDefs; /* the -defaults option */
#if USE_ACCESS_CONTROL
Tix_LinkList subWidgets;
Tix_ExportSpec exportSpec; /* controls the export status
* of the commands and options
* of the root widget */
#endif
};
typedef struct _TixInterpState {
char * result;
char * errorInfo;
char * errorCode;
} TixInterpState;
/*----------------------------------------------------------------------
*
* Internal procedures
*
*----------------------------------------------------------------------
*/
EXTERN int Tix_CallConfigMethod(
Tcl_Interp *interp, TixClassRecord *cPtr,
CONST84 char * widRec, TixConfigSpec *spec, CONST84 char * value);
EXTERN int Tix_CallMethod(Tcl_Interp *interp,
CONST84 char *context, CONST84 char *widRec, CONST84 char *method,
int argc, CONST84 char **argv, int *foundPtr);
EXTERN int Tix_ChangeOneOption(
Tcl_Interp *interp, TixClassRecord *cPtr,
CONST84 char * widRec, TixConfigSpec *spec, CONST84 char * value,
int isDefault, int isInit);
EXTERN int Tix_ChangeOptions(
Tcl_Interp *interp, TixClassRecord *cPtr,
CONST84 char * widRec, int argc, CONST84 char **argv);
EXTERN TixConfigSpec * Tix_FindConfigSpecByName(
Tcl_Interp * interp,
TixClassRecord * cPtr, CONST84 char * name);
EXTERN CONST84 char * Tix_FindMethod(Tcl_Interp *interp,
CONST84 char *context, CONST84 char *method);
EXTERN char * Tix_FindPublicMethod(
Tcl_Interp *interp, TixClassRecord * cPtr,
CONST84 char * method);
EXTERN int Tix_GetChars(Tcl_Interp *interp,
CONST84 char *string, double *doublePtr);
EXTERN CONST84 char * Tix_GetConfigSpecFullName(CONST84 char *clasRec,
CONST84 char *flag);
EXTERN CONST84 char * Tix_GetContext(
Tcl_Interp * interp, CONST84 char * widRec);
EXTERN CONST84 char * Tix_GetMethodFullName(CONST84 char *context,
CONST84 char *method);
EXTERN void Tix_GetPublicMethods(Tcl_Interp *interp,
CONST84 char *widRec, int *numMethods,
char *** validMethods);
EXTERN int Tix_GetWidgetOption(
Tcl_Interp *interp, Tk_Window tkwin,
CONST84 char *argvName, CONST84 char *dbName, CONST84 char *dbClass,
CONST84 char *defValue, int argc, CONST84 char **argv,
int type, char *ptr);
EXTERN int Tix_GetVar(
Tcl_Interp *interp, TixClassRecord *cPtr,
CONST84 char * widRec, CONST84 char * flag);
EXTERN int Tix_QueryAllOptions(
Tcl_Interp *interp, TixClassRecord * cPtr,
CONST84 char *widRec);
EXTERN int Tix_QueryOneOption(
Tcl_Interp *interp, TixClassRecord *cPtr,
CONST84 char *widRec, CONST84 char *flag);
EXTERN int Tix_SuperClass(Tcl_Interp *interp,
CONST84 char *widClass, CONST84 char ** superClass_ret);
EXTERN int Tix_UnknownPublicMethodError(
Tcl_Interp *interp, TixClassRecord * cPtr,
CONST84 char * widRec, CONST84 char * method);
EXTERN int Tix_ValueMissingError(Tcl_Interp *interp,
CONST84 char *spec);
EXTERN void Tix_AddDItemType(
Tix_DItemInfo * diTypePtr);
EXTERN int Tix_ConfigureInfo2(
Tcl_Interp *interp, Tk_Window tkwin,
CONST84 char *entRec, Tk_ConfigSpec *entConfigSpecs,
Tix_DItem * iPtr, CONST84 char *argvName, int flags);
EXTERN int Tix_ConfigureValue2(Tcl_Interp *interp,
Tk_Window tkwin, CONST84 char * entRec,
Tk_ConfigSpec *entConfigSpecs, Tix_DItem * iPtr,
CONST84 char *argvName, int flags);
EXTERN void Tix_DItemCalculateSize(
Tix_DItem * iPtr);
EXTERN char * Tix_DItemComponent(Tix_DItem * diPtr,
int x, int y);
EXTERN int Tix_DItemConfigure(
Tix_DItem * diPtr, int argc,
CONST84 char **argv, int flags);
EXTERN Tix_DItem * Tix_DItemCreate(Tix_DispData * ddPtr,
CONST84 char * type);
EXTERN void Tix_DItemDrawBackground(Drawable drawable,
TixpSubRegion *subRegPtr, Tix_DItem * iPtr,
int x, int y, int width, int height,
int xOffset, int yOffset, int flags);
EXTERN void Tix_DItemDisplay(
Drawable drawable, Tix_DItem * iPtr,
int x, int y, int width, int height,
int xOffset, int yOffset, int flag);
EXTERN int Tix_DItemFillNormalBG(Drawable drawable,
TixpSubRegion *subRegPtr, Tix_DItem * iPtr,
int x, int y, int width, int height,
int xOffset, int yOffset, int flags);
EXTERN void Tix_DItemFree(
Tix_DItem * iPtr);
EXTERN void TixDItemStyleChanged(
Tix_DItemInfo * diTypePtr,
Tix_DItemStyle * stylePtr);
EXTERN void TixDItemStyleConfigureGCs(
Tix_DItemStyle *style);
EXTERN void TixDItemStyleFree(Tix_DItem *iPtr,
Tix_DItemStyle * stylePtr);
EXTERN void TixDItemGetAnchor(Tk_Anchor anchor,
int x, int y, int cav_w, int cav_h,
int width, int height, int * x_ret, int * y_ret);
EXTERN void Tix_FreeArgumentList(
Tix_ArgumentList *argListPtr);
EXTERN void TixGetColorDItemGC(
Tix_DItem * iPtr, GC * backGC_ret,
GC * foreGC_ret, GC * anchorGC_ret, int flags);
EXTERN Tix_DItemStyle* TixGetDefaultDItemStyle(
Tix_DispData * ddPtr, Tix_DItemInfo * diTypePtr,
Tix_DItem *iPtr, Tix_DItemStyle* oldStylePtr);
EXTERN Tix_DItemInfo * Tix_GetDItemType(
Tcl_Interp * interp, CONST84 char *type);
EXTERN void Tix_GetScrollFractions(
Tix_ScrollInfo * siPtr,
double * first_ret, double * last_ret);
EXTERN void Tix_InitScrollInfo(
Tix_ScrollInfo * siPtr, int type);
EXTERN int Tix_MultiConfigureInfo(
Tcl_Interp * interp,
Tk_Window tkwin, Tk_ConfigSpec **specsList,
int numLists, CONST84 char **widgRecList, CONST84 char *argvName,
int flags, int request);
EXTERN void Tix_SetDefaultStyleTemplate(
Tk_Window tkwin, Tix_StyleTemplate * tmplPtr);
EXTERN int Tix_SetScrollBarView(
Tcl_Interp *interp, Tix_ScrollInfo * siPtr,
int argc, CONST84 char **argv, int compat);
EXTERN void Tix_SetWindowItemSerial(
Tix_LinkList * lPtr, Tix_DItem * iPtr,
int serial);
EXTERN int Tix_SplitConfig(Tcl_Interp * interp,
Tk_Window tkwin, Tk_ConfigSpec ** specsList,
int numLists, int argc, CONST84 char **argv,
Tix_ArgumentList * argListPtr);
EXTERN void Tix_UnmapInvisibleWindowItems(
Tix_LinkList * lPtr, int serial);
EXTERN void Tix_UpdateScrollBar(
Tcl_Interp *interp, Tix_ScrollInfo * siPtr);
EXTERN int Tix_WidgetConfigure2(
Tcl_Interp *interp, Tk_Window tkwin, CONST84 char * entRec,
Tk_ConfigSpec *entConfigSpecs,
Tix_DItem * iPtr, int argc, CONST84 char **argv,
int flags, int forced, int * sizeChanged_ret);
EXTERN void Tix_WindowItemListRemove(
Tix_LinkList * lPtr, Tix_DItem * iPtr);
/*
* Functions that should be used by Tix only. Functions prefixed by "Tix"
* are generic functions that has one implementation for all platforms.
* Functions prefixed with "Tixp" requires one implementation on each
* platform.
*/
extern void TixInitializeDisplayItems(void);
extern void TixpDrawAnchorLines(Display *display,
Drawable drawable, GC gc, int x, int y,
int w, int h);
extern void TixpDrawTmpLine(int x1, int y1,
int x2, int y2, Tk_Window tkwin);
extern void TixpEndSubRegionDraw(Display *display,
Drawable drawable, GC gc,
TixpSubRegion * subRegPtr);
extern int TixpSetWindowParent(Tcl_Interp * interp,
Tk_Window tkwin, Tk_Window newParent,
int parentId);
extern void TixpStartSubRegionDraw(Display *display,
Drawable drawable, GC gc,
TixpSubRegion * subRegPtr, int origX,
int origY, int x, int y, int width, int height,
int needWidth, int needHeight);
extern void TixpSubRegDisplayText(Display *display,
Drawable drawable, GC gc,
TixpSubRegion * subRegPtr,
TixFont font, CONST84 char *string,
int numChars, int x, int y, int length,
Tk_Justify justify, int underline);
extern void TixpSubRegDrawBitmap(Display *display,
Drawable drawable, GC gc,
TixpSubRegion * subRegPtr, Pixmap bitmap,
int src_x, int src_y, int width, int height,
int dest_x, int dest_y, unsigned long plane);
extern void TixpSubRegDrawImage(
TixpSubRegion * subRegPtr, Tk_Image image,
int imageX, int imageY, int width, int height,
Drawable drawable, int drawableX, int drawableY);
extern void TixpSubRegDrawAnchorLines(
Display *display, Drawable drawable,
GC gc, TixpSubRegion * subRegPtr,
int x, int y, int w, int h);
extern void TixpSubRegFillRectangle(Display *display,
Drawable drawable, GC gc,
TixpSubRegion * subRegPtr, int x, int y,
int width, int height);
extern void TixpSubRegSetClip(
Display *display, TixpSubRegion * subRegPtr,
GC gc);
extern void TixpSubRegUnsetClip(
Display *display, TixpSubRegion * subRegPtr,
GC gc);
extern char * tixStrDup( CONST char * s);
extern int TixMwmProtocolHandler(
ClientData clientData, XEvent *eventPtr);
/*
* Image types implemented by Tix.
*/
extern Tk_ImageType tixPixmapImageType;
extern Tk_ImageType tixCompoundImageType;
/*
* Display Items implemented in the Tix core.
*/
extern Tix_DItemInfo tix_ImageTextItemType;
extern Tix_DItemInfo tix_TextItemType;
extern Tix_DItemInfo tix_WindowItemType;
extern Tix_DItemInfo tix_ImageItemType;
#endif /* _TIX_INT_H_ */

319
generic/tixList.c Normal file
View File

@@ -0,0 +1,319 @@
/* $Id: tixList.c,v 1.1.1.1 2000/05/17 11:08:42 idiscovery Exp $ */
/*
* tixList.c --
*
* Implements easy-to-use link lists.
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#include <tixPort.h>
#include <tixInt.h>
#define NEXT(info,ptr) (char*)(*(char**)((ptr+(info->nextOffset))))
#define PREV(info,ptr) (char*)(*(char**)((ptr+(info->prevOffset))))
static void SetNext _ANSI_ARGS_((Tix_ListInfo * info,
char * ptr, char * next));
static void SetNext(info, ptr, next)
Tix_ListInfo * info;
char * ptr;
char * next;
{
char ** next_ptr = (char**)((ptr+(info->nextOffset)));
* next_ptr = next;
}
void Tix_LinkListInit(lPtr)
Tix_LinkList * lPtr;
{
lPtr->numItems = 0;
lPtr->head = (char*)NULL;
lPtr->tail = (char*)NULL;
}
void
Tix_LinkListAppend(infoPtr, lPtr, itemPtr, flags)
Tix_ListInfo * infoPtr;
Tix_LinkList * lPtr;
char * itemPtr;
int flags;
{
char * ptr;
if (flags | TIX_UNIQUE) {
/* Check for uniqueness */
for (ptr=lPtr->head;
ptr!=NULL;
ptr=NEXT(infoPtr,ptr)) {
if (ptr == itemPtr) {
return;
}
}
}
if (lPtr->head == NULL) {
lPtr->head = lPtr->tail = itemPtr;
} else {
SetNext(infoPtr, lPtr->tail, itemPtr);
lPtr->tail = itemPtr;
}
SetNext(infoPtr, itemPtr, NULL);
++ lPtr->numItems;
}
void Tix_LinkListIteratorInit(liPtr)
Tix_ListIterator * liPtr;
{
liPtr->started = 0;
}
void Tix_LinkListStart(infoPtr, lPtr, liPtr)
Tix_ListInfo * infoPtr;
Tix_LinkList * lPtr;
Tix_ListIterator * liPtr;
{
if (lPtr->head == NULL) {
liPtr->last = NULL;
liPtr->curr = NULL;
} else {
liPtr->last = liPtr->curr = lPtr->head;
}
liPtr->deleted = 0;
liPtr->started = 1;
}
void Tix_LinkListNext(infoPtr, lPtr, liPtr)
Tix_ListInfo * infoPtr;
Tix_LinkList * lPtr;
Tix_ListIterator * liPtr;
{
if (liPtr->curr == NULL) {
return;
}
if (liPtr->deleted == 1) {
/* the curr pointer has already been adjusted */
liPtr->deleted = 0;
return;
}
liPtr->last = liPtr->curr;
liPtr->curr = NEXT(infoPtr, liPtr->curr);
}
/*
*----------------------------------------------------------------------
* Tix_LinkListDelete --
*
* Deletes an element from the linklist. The proper step of deleting
* an element is:
*
* for (Tix_SimpleListStart(&list, &li); !Tix_SimpleListDone(&li);
* Tix_SimpleListNext (&list, &li)) {
* MyData * p = (MyData*)li.curr;
* if (someCondition) {
* Tix_SimpleListDelete(&cPtr->subWDefs, &li);
* ckfree((char*)p);
* }
* }
*
* i.e., The pointer can be freed only after Tix_SimpleListDelete().
*
* Results:
* None.
*
* Side effects:
* The pointers in the list are adjusted and the liPtr is advanced
* to the next element.
*----------------------------------------------------------------------
*/
void
Tix_LinkListDelete(infoPtr, lPtr, liPtr)
Tix_ListInfo * infoPtr;
Tix_LinkList * lPtr;
Tix_ListIterator * liPtr;
{
if (liPtr->curr == NULL) {
/* %% probably is a mistake */
return;
}
if (liPtr->deleted == 1) {
/* %% probably is a mistake */
return;
}
if (lPtr->head == lPtr->tail) {
lPtr->head = lPtr->tail = NULL;
liPtr->curr = NULL;
}
else if (lPtr->head == liPtr->curr) {
lPtr->head = NEXT(infoPtr, liPtr->curr);
liPtr->curr = lPtr->head;
liPtr->last = lPtr->head;
}
else if (lPtr->tail == liPtr->curr) {
lPtr->tail = liPtr->last;
SetNext(infoPtr, lPtr->tail, NULL);
liPtr->curr = NULL;
}
else {
SetNext(infoPtr, liPtr->last, NEXT(infoPtr, liPtr->curr));
liPtr->curr = NEXT(infoPtr, liPtr->last);
}
-- lPtr->numItems;
liPtr->deleted = 1;
}
/*----------------------------------------------------------------------
* Tix_LinkListInsert --
*
* Insert the item at the position indicated by liPtr
*----------------------------------------------------------------------
*/
void Tix_LinkListInsert(infoPtr, lPtr, itemPtr, liPtr)
Tix_ListInfo * infoPtr;
Tix_LinkList * lPtr;
char * itemPtr;
Tix_ListIterator * liPtr;
{
if (lPtr->numItems == 0) {
/* Just do an append
*/
Tix_LinkListAppend(infoPtr, lPtr, itemPtr, 0);
/* Fix the iterator (%% I am not sure if this is necessary)
*/
liPtr->curr = liPtr->last = lPtr->head;
return;
}
if (liPtr->curr == NULL) {
/* %% probably is a mistake */
return;
}
if (lPtr->head == lPtr->tail) {
lPtr->head = itemPtr;
SetNext(infoPtr, lPtr->head, lPtr->tail);
liPtr->last = itemPtr;
liPtr->curr = itemPtr;
}
else if (liPtr->curr == lPtr->head) {
lPtr->head = itemPtr;
SetNext(infoPtr, lPtr->head, liPtr->curr);
liPtr->last = itemPtr;
liPtr->curr = itemPtr;
}
else {
SetNext(infoPtr, liPtr->last, itemPtr);
SetNext(infoPtr, itemPtr, liPtr->curr);
liPtr->last = itemPtr;
}
++ lPtr->numItems;
}
/*----------------------------------------------------------------------
* Tix_LinkListFindAndDelete --
*
* Find an element and delete it.
*
* liPtr:
* Can be NULL.
* If non-NULL, the search will start from the current entry indexed
* by liPtr;
*
* Return value:
* 1 if element is found and deleted
* 0 if element is not found
*----------------------------------------------------------------------
*/
int Tix_LinkListFindAndDelete(infoPtr, lPtr, itemPtr, liPtr)
Tix_ListInfo * infoPtr;
Tix_LinkList * lPtr;
char * itemPtr;
Tix_ListIterator * liPtr;
{
Tix_ListIterator defIterator;
if (liPtr == NULL) {
Tix_LinkListIteratorInit(&defIterator);
liPtr = &defIterator;
}
if (!liPtr->started) {
Tix_LinkListStart(infoPtr, lPtr, liPtr);
}
if (Tix_LinkListFind(infoPtr, lPtr, itemPtr, liPtr)) {
Tix_LinkListDelete(infoPtr, lPtr, liPtr);
return 1;
} else {
return 0;
}
}
int Tix_LinkListDeleteRange(infoPtr, lPtr, fromPtr, toPtr, liPtr)
Tix_ListInfo * infoPtr;
Tix_LinkList * lPtr;
char * fromPtr;
char * toPtr;
Tix_ListIterator * liPtr;
{
Tix_ListIterator defIterator;
int start = 0;
int deleted = 0;
if (liPtr == NULL) {
Tix_LinkListIteratorInit(&defIterator);
liPtr = &defIterator;
}
if (!liPtr->started) {
Tix_LinkListStart(infoPtr, lPtr, liPtr);
}
for (;
!Tix_LinkListDone(liPtr);
Tix_LinkListNext (infoPtr, lPtr, liPtr)) {
if (liPtr->curr == fromPtr) {
start = 1;
}
if (start) {
Tix_LinkListDelete(infoPtr, lPtr, liPtr);
++ deleted;
}
if (liPtr->curr == toPtr) {
break;
}
}
return deleted;
}
int Tix_LinkListFind(infoPtr, lPtr, itemPtr, liPtr)
Tix_ListInfo * infoPtr;
Tix_LinkList * lPtr;
char * itemPtr;
Tix_ListIterator * liPtr;
{
if (!liPtr->started) {
Tix_LinkListStart(infoPtr, lPtr, liPtr);
}
for (Tix_LinkListStart(infoPtr, lPtr, liPtr);
!Tix_LinkListDone(liPtr);
Tix_LinkListNext (infoPtr, lPtr, liPtr)) {
if (liPtr->curr == itemPtr) {
return 1; /* found! */
}
}
return 0; /* Can't find */
}

574
generic/tixMethod.c Normal file
View File

@@ -0,0 +1,574 @@
/*
* tixMethod.c --
*
* Handle the calling of class methods.
*
* Implements the basic OOP class mechanism for the Tix Intrinsics.
*
* Copyright (c) 1993-1999 Ioi Kim Lam.
* Copyright (c) 2000-2001 Tix Project Group.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tixMethod.c,v 1.5 2008/02/28 04:05:29 hobbs Exp $
*/
#include <tk.h>
#include <tixPort.h>
#include <tixInt.h>
#define GetMethodTable(interp) \
(TixGetHashTable(interp, "tixMethodTab", MethodTableDeleteProc, \
TCL_STRING_KEYS))
static int Tix_CallMethodByContext _ANSI_ARGS_((
Tcl_Interp *interp, CONST84 char *context,
CONST84 char *widRec, CONST84 char *method,
int argc, CONST84 char **argv));
static void Tix_RestoreContext _ANSI_ARGS_((
Tcl_Interp *interp, CONST84 char *widRec,
CONST84 char *oldContext));
static void Tix_SetContext _ANSI_ARGS_((
Tcl_Interp *interp, CONST84 char *widRec,
CONST84 char *newContext));
static char * Tix_SaveContext _ANSI_ARGS_((Tcl_Interp *interp,
CONST84 char *widRec));
static void MethodTableDeleteProc _ANSI_ARGS_((
ClientData clientData, Tcl_Interp *interp));
/*
*
* argv[1] = widget record
* argv[2] = method
* argv[3+] = args
*
*/
TIX_DEFINE_CMD(Tix_CallMethodCmd)
{
CONST84 char *context;
CONST84 char *newContext;
CONST84 char *widRec = argv[1];
CONST84 char *method = argv[2];
int result;
if (argc<3) {
return Tix_ArgcError(interp, argc, argv, 1, "w method ...");
}
if ((context = GET_RECORD(interp, widRec, "className")) == NULL) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "invalid object reference \"", widRec,
"\"", (char*)NULL);
return TCL_ERROR;
}
newContext = Tix_FindMethod(interp, context, method);
if (newContext) {
result = Tix_CallMethodByContext(interp, newContext, widRec, method,
argc-3, argv+3);
} else {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "cannot call method \"", method,
"\" for context \"", context, "\".", (char*)NULL);
Tcl_SetVar(interp, "errorInfo", Tcl_GetStringResult(interp),
TCL_GLOBAL_ONLY);
result = TCL_ERROR;
}
return result;
}
/*
*
* argv[1] = widget record
* argv[2] = method
* argv[3+] = args
*
*/
TIX_DEFINE_CMD(Tix_ChainMethodCmd)
{
CONST84 char *context;
CONST84 char *superClassContext;
CONST84 char *newContext;
CONST84 char *widRec = argv[1];
CONST84 char *method = argv[2];
int result;
if (argc<3) {
return Tix_ArgcError(interp, argc, argv, 1, "w method ...");
}
if ((context = Tix_GetContext(interp, widRec)) == NULL) {
return TCL_ERROR;
}
if (Tix_SuperClass(interp, context, &superClassContext) != TCL_OK) {
return TCL_ERROR;
}
if (superClassContext == NULL) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "no superclass exists for context \"",
context, "\".", (char*)NULL);
result = TCL_ERROR;
goto done;
}
newContext = Tix_FindMethod(interp, superClassContext, method);
if (newContext) {
result = Tix_CallMethodByContext(interp, newContext, widRec,
method, argc-3, argv+3);
} else {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "cannot chain method \"", method,
"\" for context \"", context, "\".", (char*)NULL);
Tcl_SetVar(interp, "errorInfo", Tcl_GetStringResult(interp),
TCL_GLOBAL_ONLY);
result = TCL_ERROR;
goto done;
}
done:
return result;
}
/*
*
* argv[1] = widget record
* argv[2] = class (context)
* argv[3] = method
*
*/
TIX_DEFINE_CMD(Tix_GetMethodCmd)
{
CONST84 char *newContext;
CONST84 char *context= argv[2];
CONST84 char *method = argv[3];
CONST84 char *cmdName;
if (argc!=4) {
return Tix_ArgcError(interp, argc, argv, 1, "w class method");
}
newContext = Tix_FindMethod(interp, context, method);
if (newContext) {
cmdName = Tix_GetMethodFullName(newContext, method);
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, cmdName, NULL);
ckfree((char *) cmdName);
} else {
Tcl_SetResult(interp, "", TCL_STATIC);
}
return TCL_OK;
}
/*----------------------------------------------------------------------
* Tix_FindMethod
*
* Starting with class "context", find the first class that defines
* the method. This class must be the same as the class "context" or
* a superclass of the class "context".
*/
CONST84 char *
Tix_FindMethod(interp, context, method)
Tcl_Interp *interp;
CONST84 char *context;
CONST84 char *method;
{
CONST84 char *theContext;
int isNew;
CONST84 char *key;
Tcl_HashEntry *hashPtr;
key = Tix_GetMethodFullName(context, method);
hashPtr = Tcl_CreateHashEntry(GetMethodTable(interp), key, &isNew);
ckfree((char *) key);
if (!isNew) {
theContext = (char *) Tcl_GetHashValue(hashPtr);
} else {
for (theContext = context; theContext;) {
if (Tix_ExistMethod(interp, theContext, method)) {
break;
}
/* Go to its superclass and see if it has the method */
if (Tix_SuperClass(interp, theContext, &theContext) != TCL_OK) {
return NULL;
}
if (theContext == NULL) {
return NULL;
}
}
if (theContext != NULL) {
/*
* theContext may point to the stack. We have to put it
* in some more permanent place.
*/
theContext = tixStrDup(theContext);
}
Tcl_SetHashValue(hashPtr, (char*)theContext);
}
return theContext;
}
/*
*----------------------------------------------------------------------
* Tix_CallMethod
*
* Starting with class "context", find the first class that defines
* the method. If found, call this method.
*
* Results:
* A standard Tcl completion code (TCL_OK or TCL_ERROR). Also
* leaves information in the interp's result.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
Tix_CallMethod(interp, context, widRec, method, argc, argv, foundPtr)
Tcl_Interp *interp; /* Tcl interpreter to execute the method in */
CONST84 char *context; /* context */
CONST84 char *widRec; /* Name of the widget record */
CONST84 char *method; /* Name of the method */
int argc; /* Number of arguments passed to the method */
CONST84 char **argv; /* Arguments */
int *foundPtr; /* If non-NULL. returns whether the
* method has been found */
{
CONST84 char *targetContext;
targetContext = Tix_FindMethod(interp, context, method);
if (foundPtr != NULL) {
*foundPtr = (targetContext != NULL);
}
if (targetContext != NULL) {
return Tix_CallMethodByContext(interp, targetContext, widRec, method,
argc, argv);
} else {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "cannot call method \"", method,
"\" for context \"", context, "\".", (char*)NULL);
Tcl_SetVar(interp, "errorInfo", Tcl_GetStringResult(interp),
TCL_GLOBAL_ONLY);
return TCL_ERROR;
}
}
/*----------------------------------------------------------------------
* Tix_FindConfigSpec
*
* Starting with class "classRec", find the first class that defines
* the option flag. This class must be the same as the class "classRec" or
* a superclass of the class "classRec".
*/
/* save the old context: calling a method of a superclass will
* change the context of a widget.
*/
static char *Tix_SaveContext(interp, widRec)
Tcl_Interp *interp;
CONST84 char *widRec;
{
CONST84 char *context;
if ((context = GET_RECORD(interp, widRec, "context")) == NULL) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "invalid object reference \"", widRec,
"\"", (char*)NULL);
return NULL;
}
else {
return tixStrDup(context);
}
}
static void Tix_RestoreContext(interp, widRec, oldContext)
Tcl_Interp *interp;
CONST84 char *widRec;
CONST84 char *oldContext;
{
SET_RECORD(interp, widRec, "context", oldContext);
ckfree((char *) oldContext);
}
static void Tix_SetContext(interp, widRec, newContext)
Tcl_Interp *interp;
CONST84 char *widRec;
CONST84 char *newContext;
{
SET_RECORD(interp, widRec, "context", newContext);
}
CONST84 char *
Tix_GetContext(interp, widRec)
Tcl_Interp *interp;
CONST84 char *widRec;
{
CONST84 char *context;
if ((context = GET_RECORD(interp, widRec, "context")) == NULL) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "invalid object reference \"", widRec,
"\"", (char*)NULL);
return NULL;
} else {
return context;
}
}
int
Tix_SuperClass(interp, class, superClass_ret)
Tcl_Interp *interp;
CONST84 char *class;
CONST84 char **superClass_ret;
{
CONST84 char *superclass;
if ((superclass = GET_RECORD(interp, class, "superClass")) == NULL) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "invalid class \"", class,
"\"; ", (char*)NULL);
return TCL_ERROR;
}
if (strlen(superclass) == 0) {
*superClass_ret = (char*) NULL;
} else {
*superClass_ret = superclass;
}
return TCL_OK;
}
CONST84 char *
Tix_GetMethodFullName(context, method)
CONST84 char *context;
CONST84 char *method;
{
char *buff;
int max;
int conLen;
conLen = strlen(context);
max = conLen + strlen(method) + 3;
buff = (char*)ckalloc(max * sizeof(char));
strcpy(buff, context);
strcpy(buff+conLen, ":");
strcpy(buff+conLen+1, method);
return buff;
}
int Tix_ExistMethod(interp, context, method)
Tcl_Interp *interp;
CONST84 char *context;
CONST84 char *method;
{
CONST84 char *cmdName;
Tcl_CmdInfo dummy;
int exist;
/*
* TODO: does Tcl_GetCommandInfo check in global namespace??
*/
cmdName = Tix_GetMethodFullName(context, method);
exist = Tcl_GetCommandInfo(interp, cmdName, &dummy);
if (!exist) {
if (Tix_GlobalVarEval(interp, "auto_load ", cmdName,
(char*)NULL)!= TCL_OK) {
goto done;
}
if (strcmp(Tcl_GetStringResult(interp), "1") == 0) {
exist = 1;
}
}
done:
ckfree((char *) cmdName);
Tcl_SetResult(interp, NULL, TCL_STATIC);
return exist;
}
/* %% There is a dirty version that uses the old argv, without having to
* malloc a new argv.
*/
static int
Tix_CallMethodByContext(interp, context, widRec, method, argc, argv)
Tcl_Interp *interp;
CONST84 char *context;
CONST84 char *widRec;
CONST84 char *method;
int argc;
CONST84 char **argv;
{
CONST84 char *cmdName;
int i, result;
CONST84 char *oldContext;
CONST84 char **newArgv;
if ((oldContext = Tix_SaveContext(interp, widRec)) == NULL) {
return TCL_ERROR;
}
Tix_SetContext(interp, widRec, context);
cmdName = Tix_GetMethodFullName(context, method);
/* Create a new argv list */
newArgv = (CONST84 char**)ckalloc((argc+2)*sizeof(char*));
newArgv[0] = cmdName;
newArgv[1] = widRec;
for (i=0; i< argc; i++) {
newArgv[i+2] = argv[i];
}
result = Tix_EvalArgv(interp, argc+2, newArgv);
Tix_RestoreContext(interp, widRec, oldContext);
ckfree((char*)newArgv);
ckfree((char*)cmdName);
return result;
}
/*
* Deprecated: use Tcl_EvalObjv instead. Will be removed.
*/
int Tix_EvalArgv(interp, argc, argv)
Tcl_Interp *interp;
int argc;
CONST84 char **argv;
{
register Tcl_Obj *objPtr;
register int i;
int result;
#define NUM_ARGS 20
Tcl_Obj *(objStorage[NUM_ARGS]);
register Tcl_Obj **objv = objStorage;
/*
* TODO: callers to this method should be changed to use Tcl_EvalObjv
* directly.
*/
/*
* Create the object argument array "objv". Make sure objv is large
* enough to hold the objc arguments plus 1 extra for the zero
* end-of-objv word.
*/
if ((argc + 1) > NUM_ARGS) {
objv = (Tcl_Obj **)
ckalloc((unsigned)(argc + 1) * sizeof(Tcl_Obj *));
}
for (i = 0; i < argc; i++) {
objv[i] = Tcl_NewStringObj(argv[i], -1);
Tcl_IncrRefCount(objv[i]);
}
objv[argc] = NULL;
result = Tcl_EvalObjv(interp, argc, objv, TCL_EVAL_GLOBAL);
/*
* Get the interpreter's string result. We do this because some
* of our callers expect to find result inside interp->result.
*/
Tcl_GetStringResult(interp);
/*
* Decrement the ref counts on the objv elements since we are done
* with them.
*/
for (i = 0; i < argc; i++) {
objPtr = objv[i];
Tcl_DecrRefCount(objPtr);
}
/*
* Free the objv array if malloc'ed storage was used.
*/
if (objv != objStorage) {
ckfree((char *) objv);
}
return result;
#undef NUM_ARGS
}
char *
Tix_FindPublicMethod(interp, cPtr, method)
Tcl_Interp *interp;
TixClassRecord *cPtr;
CONST84 char *method;
{
int i;
unsigned int len = strlen(method);
for (i=0; i<cPtr->nMethods; i++) {
if (cPtr->methods[i][0] == method[0] &&
strncmp(cPtr->methods[i], method, len)==0) {
return cPtr->methods[i];
}
}
return 0;
}
/*
*----------------------------------------------------------------------
* MethodTableDeleteProc --
*
* This procedure is called when the interp is about to
* be deleted. It cleans up the hash entries and destroys the hash
* table.
*
* Results:
* None.
*
* Side effects:
* All class method contexts are deleted for this interpreter.
*----------------------------------------------------------------------
*/
static void
MethodTableDeleteProc(clientData, interp)
ClientData clientData;
Tcl_Interp *interp;
{
Tcl_HashTable *methodTablePtr = (Tcl_HashTable*)clientData;
Tcl_HashSearch hashSearch;
Tcl_HashEntry *hashPtr;
CONST84 char *context;
for (hashPtr = Tcl_FirstHashEntry(methodTablePtr, &hashSearch);
hashPtr;
hashPtr = Tcl_NextHashEntry(&hashSearch)) {
context = (char*)Tcl_GetHashValue(hashPtr);
if (context) {
ckfree((char *) context);
}
Tcl_DeleteHashEntry(hashPtr);
}
Tcl_DeleteHashTable(methodTablePtr);
ckfree((char*)methodTablePtr);
}

1644
generic/tixNBFrame.c Normal file

File diff suppressed because it is too large Load Diff

409
generic/tixOption.c Normal file
View File

@@ -0,0 +1,409 @@
/* $Id: tixOption.c,v 1.4 2008/02/28 04:29:03 hobbs Exp $ */
/*
* tixOption.c --
*
* Handle the "$widget config" commands
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
/* ToDo:
*
* 1) ConfigSpec structures shouldn't be shared between parent and child
* classes.
* 2) Specs array should be compacted (no duplication) and sorted according
* to argvName during class declaration.
* 3) Merge aliases with specs
*
*/
#include <tk.h>
#include <tixPort.h>
#include <tixInt.h>
static char * FormatConfigInfo(Tcl_Interp *interp,
TixClassRecord *cPtr, CONST84 char * widRec, TixConfigSpec * spec);
/*
* This is a lightweight interface for querying the value of a
* variable in the object. This is simpler compared to
* [lindex [$w config -flag] 4]
*/
int Tix_GetVar (interp, cPtr, widRec, flag)
Tcl_Interp *interp;
TixClassRecord *cPtr;
CONST84 char * widRec;
CONST84 char * flag;
{
TixConfigSpec * spec;
CONST84 char * value;
spec = Tix_FindConfigSpecByName(interp, cPtr, flag);
if (spec != NULL) {
if (spec->isAlias) {
flag = spec->realPtr->argvName;
} else {
/* The user may have specified a shorthand like -backgro */
flag = spec->argvName;
}
value = Tcl_GetVar2(interp, widRec, flag, TCL_GLOBAL_ONLY);
Tcl_AppendResult(interp, value, (char*)NULL);
return TCL_OK;
}
else {
return TCL_ERROR;
}
}
int
Tix_QueryOneOption(interp, cPtr, widRec, flag)
Tcl_Interp *interp;
TixClassRecord *cPtr;
CONST84 char *widRec;
CONST84 char *flag;
{
TixConfigSpec * spec;
char * list;
spec = Tix_FindConfigSpecByName(interp, cPtr, flag);
if (spec != NULL) {
list = FormatConfigInfo(interp, cPtr, widRec, spec);
Tcl_SetResult(interp, list, TCL_VOLATILE);
ckfree((char *) list);
return TCL_OK;
}
else {
return TCL_ERROR;
}
}
/*
* Tix_QueryAllOptions --
*
* Note: This function does not call Tix_FindConfigSpec() because
* it just needs to print out the list of all configSpecs from the
* class structure.
*
*/
int
Tix_QueryAllOptions (interp, cPtr, widRec)
Tcl_Interp *interp;
TixClassRecord * cPtr;
CONST84 char *widRec;
{
int i, code = TCL_OK;
char *list;
CONST84 char *lead = "{";
/* Iterate over all the options of class */
for (i=0; i<cPtr->nSpecs; i++) {
if (cPtr->specs[i] && cPtr->specs[i]->argvName) {
list = FormatConfigInfo(interp, cPtr, widRec, cPtr->specs[i]);
Tcl_AppendResult(interp, lead, list, "}", (char *) NULL);
ckfree((char *) list);
lead = " {";
}
}
return code;
}
TixConfigSpec *
Tix_FindConfigSpecByName(interp, cPtr, flag)
Tcl_Interp *interp;
TixClassRecord *cPtr;
CONST84 char *flag;
{
CONST84 char *classRec;
CONST84 char *key;
int nMatch, i;
size_t len;
Tcl_HashEntry *hashPtr;
TixConfigSpec *configSpec;
classRec = cPtr->className;
/*
* First try to look up the confifspec in a hash table,
* it should be faster.
*/
key = Tix_GetConfigSpecFullName(classRec, flag);
hashPtr = Tcl_FindHashEntry(TixGetHashTable(interp, "tixSpecTab", NULL,
TCL_STRING_KEYS), key);
ckfree((char *) key);
if (hashPtr) {
return (TixConfigSpec *) Tcl_GetHashValue(hashPtr);
}
/*
* The user may specified a partial name. Try to match, but will
* return error if we don't get exactly one match.
*/
len = strlen(flag);
for (configSpec=NULL,nMatch=0,i=0; i<cPtr->nSpecs; i++) {
if (strncmp(flag, cPtr->specs[i]->argvName, len) == 0) {
if (nMatch > 0) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "ambiguous option \"", flag, "\"",
(char*)NULL);
return NULL;
} else {
nMatch ++;
configSpec = cPtr->specs[i];
}
}
}
if (configSpec == NULL) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "unknown option \"", flag, "\"", (char*)NULL);
return NULL;
} else {
return configSpec;
}
}
CONST84 char *
Tix_GetConfigSpecFullName(classRec, flag)
CONST84 char * classRec;
CONST84 char * flag;
{
char * buff;
int max;
int conLen;
conLen = strlen(classRec);
max = conLen + strlen(flag) + 1;
buff = (char*)ckalloc(max * sizeof(char));
strcpy(buff, classRec);
strcpy(buff+conLen, flag);
return buff;
}
int Tix_ChangeOptions(interp, cPtr, widRec, argc, argv)
Tcl_Interp *interp;
TixClassRecord *cPtr;
CONST84 char * widRec;
int argc;
CONST84 char ** argv;
{
int i, code = TCL_OK;
TixConfigSpec * spec;
if (argc == 0) {
goto done;
}
if ((argc %2) != 0) {
if (Tix_FindConfigSpecByName(interp, cPtr, argv[argc-1])) {
Tcl_AppendResult(interp, "value for \"", argv[argc-1],
"\" missing", (char*)NULL);
} else {
/* The error message is already appended by
* Tix_FindConfigSpecByName()
*/
}
code = TCL_ERROR;
goto done;
}
for (i=0; i<argc; i+=2) {
spec = Tix_FindConfigSpecByName(interp, cPtr, argv[i]);
if (spec == NULL) {
code = TCL_ERROR;
goto done;
}
if (Tix_ChangeOneOption(interp, cPtr, widRec, spec,
argv[i+1], 0, 0)!=TCL_OK) {
code = TCL_ERROR;
goto done;
}
}
done:
return code;
}
int Tix_CallConfigMethod(interp, cPtr, widRec, spec, value)
Tcl_Interp *interp;
TixClassRecord *cPtr;
CONST84 char * widRec;
TixConfigSpec *spec;
CONST84 char * value;
{
#define STATIC_SPACE_SIZE 60
CONST84 char * argv[2];
char buff[STATIC_SPACE_SIZE];
char * method = buff;
CONST84 char * context = Tix_GetContext(interp, widRec);
CONST84 char * c;
unsigned int bufsize = strlen(spec->argvName) + 7;
int code;
if (bufsize > STATIC_SPACE_SIZE) {
method = ckalloc(bufsize);
}
sprintf(method, "config%s", spec->argvName);
c = Tix_FindMethod(interp, context, method);
if (c != NULL) {
argv[0] = value;
code = Tix_CallMethod(interp, c, widRec, method, 1, argv, NULL);
goto done;
}
c = Tix_FindMethod(interp, context, "config");
if (c != NULL) {
argv[0] = spec->argvName;
argv[1] = value;
code = Tix_CallMethod(interp, c, widRec, "config", 2, argv, NULL);
goto done;
}
code = TCL_OK;
done:
if (method != buff) {
ckfree((char *) method);
}
return code;
#undef STATIC_SPACE_SIZE
}
int Tix_ChangeOneOption(interp, cPtr, widRec, spec, value, isDefault, isInit)
Tcl_Interp *interp;
TixClassRecord *cPtr;
CONST84 char * widRec;
TixConfigSpec *spec;
CONST84 char * value;
int isDefault; /* Set to be true when Tix tries to set
* the options according to their default
* values */
int isInit; /* Set to true only if the option was
* specified at the widget creation command
*/
{
int code = TCL_OK;
const char *newValue = NULL;
if (spec->isAlias) {
spec = spec->realPtr;
}
/* -- STEP 1 --
* Check if these variables are protected.
* readonly means the variable can never be assigned to.
* static means ths variable can only ne assigned during initialization.
*/
if (!isDefault && spec->readOnly) {
Tcl_AppendResult(interp, "cannot assigned to readonly variable \"",
spec->argvName, "\"", (char*) NULL);
code = TCL_ERROR;
goto done;
}
if (!(isInit || isDefault) && spec->isStatic) {
Tcl_AppendResult(interp, "cannot assigned to static variable \"",
spec->argvName, "\"", (char*) NULL);
code = TCL_ERROR;
goto done;
}
/* -- STEP 2 --
* Call the verify command to check whether the value is acceptable
*
*/
if (spec->verifyCmd != NULL) {
CONST84 char * cmdArgv[2];
cmdArgv[0] = spec->verifyCmd;
cmdArgv[1] = value;
if (Tix_EvalArgv(interp, 2, cmdArgv) != TCL_OK) {
code = TCL_ERROR;
goto done;
} else {
newValue = value = tixStrDup(Tcl_GetStringResult(interp));
}
}
/* -- STEP 3 --
* Call the configuration method of the widget. This method may
* override the user-supplied value. The configuration method should
* not be called during initialization.
*/
if (isInit || isDefault) {
/* No need to call the configuration method */
Tcl_SetVar2(interp, widRec, spec->argvName, value,TCL_GLOBAL_ONLY);
} else {
const char *str;
if (Tix_CallConfigMethod(interp, cPtr, widRec, spec, value)!=TCL_OK) {
code = TCL_ERROR;
goto done;
}
/* -- STEP 4 --
* If the configuration method does not override the value, set
* it in the widget record.
*
* If the configuration method has override the value, it will
* return a non-empty string. In this case, it is the configuration
* method's responsibility to set the value in the widget record.
*/
str = Tcl_GetStringResult(interp);
if (str && *str) {
/* value was overrided. Don't do anything */
Tcl_ResetResult(interp);
} else {
Tcl_SetVar2(interp, widRec, spec->argvName, value,TCL_GLOBAL_ONLY);
}
}
done:
if (newValue) {
ckfree((char *) newValue);
}
return code;
}
static char *
FormatConfigInfo(interp, cPtr, widRec, sPtr)
Tcl_Interp *interp;
TixClassRecord *cPtr;
CONST84 char * widRec;
TixConfigSpec * sPtr;
{
CONST84 char *argv[6];
if (sPtr->isAlias) {
if (cPtr->isWidget) {
argv[0] = sPtr->argvName;
argv[1] = sPtr->realPtr->dbName;
} else {
argv[0] = sPtr->argvName;
argv[1] = sPtr->realPtr->argvName;
}
return Tcl_Merge(2, argv);
} else {
argv[0] = sPtr->argvName;
argv[1] = sPtr->dbName;
argv[2] = sPtr->dbClass;
argv[3] = sPtr->defValue;
argv[4] = Tcl_GetVar2(interp, widRec, argv[0], TCL_GLOBAL_ONLY);
return Tcl_Merge(5, argv);
}
}

100
generic/tixPort.h Normal file
View File

@@ -0,0 +1,100 @@
/* $Id: tixPort.h,v 1.6 2005/03/25 20:15:53 hobbs Exp $ */
/*
* tixPort.h --
*
* This header file handles porting issues that occur because of
* differences between systems. It reads in platform specific
* portability files.
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#ifndef _TIX_PORT_H_
#define _TIX_PORT_H_
#ifndef _TCL
#include "tcl.h"
#endif
#ifndef _TK
#include "tk.h"
#endif
#if (!defined(__WIN32__)) && (!defined(_WIN32)) && (!defined(MAC_TCL))
/*
* The Tcl/Tk porting stuff is needed only in Unix.
*/
#if !defined(_TCLPORT) && !defined(_TKPORT)
# ifdef _TKINT
# include "tkPort.h"
# else
# include "tclPort.h"
# endif
#endif
#endif
#ifndef _TIX_H_
#include <tix.h>
#endif
#if defined(__WIN32__) || defined(_WIN32)
# include "tixWinPort.h"
#else
# if defined(MAC_TCL)
# include "tixMacPort.h"
# else
# if defined(MAC_OSX_TK)
# include <X11/X.h>
# define Cursor XCursor
# define Region XRegion
# include "../unix/tixUnixPort.h"
# else
# include "../unix/tixUnixPort.h"
# endif
# endif
#endif
EXTERN Tcl_HashTable * TixGetHashTable _ANSI_ARGS_((Tcl_Interp * interp,
char * name, Tcl_InterpDeleteProc *deleteProc,
int keyType));
/*
* Some pre-Tk8.0 style font handling. Should be updated to new Tk
* font functions soon.
*/
typedef Tk_Font TixFont;
#define TixFontId(font) Tk_FontId(font)
EXTERN void TixComputeTextGeometry _ANSI_ARGS_((
TixFont fontStructPtr, CONST84 char *string,
int numChars, int wrapLength, int *widthPtr,
int *heightPtr));
EXTERN void TixDisplayText _ANSI_ARGS_((Display *display,
Drawable drawable, TixFont font,
CONST84 char *string, int numChars, int x, int y,
int length, Tk_Justify justify, int underline,
GC gc));
#define TixFreeFont Tk_FreeFont
#define TixNameOfFont Tk_NameOfFont
#define TixGetFont Tk_GetFont
/*
* Tcl 8.4.a2 defines this macro that causes Tix compiled with
* Tcl 8.4 to break in Tcl 8.3
*/
#if defined(Tcl_InitHashTable) && defined(USE_TCL_STUBS)
#undef Tcl_InitHashTable
#define Tcl_InitHashTable \
(tclStubsPtr->tcl_InitHashTable)
#endif
#endif /* _TIX_PORT_H_ */

191
generic/tixScroll.c Normal file
View File

@@ -0,0 +1,191 @@
/* $Id: tixScroll.c,v 1.2 2004/03/28 02:44:57 hobbs Exp $ */
/*
* tixScroll.c -- Handle all the mess of Tk scroll bars
*
*
*
*/
#include <tixInt.h>
void Tix_InitScrollInfo(siPtr, type)
Tix_ScrollInfo * siPtr;
int type;
{
Tix_IntScrollInfo* isiPtr = (Tix_IntScrollInfo*) siPtr;
Tix_DoubleScrollInfo* dsiPtr = (Tix_DoubleScrollInfo*)siPtr;
siPtr->command = NULL;
siPtr->type = type;
if (type == TIX_SCROLL_INT) {
isiPtr->total = 1;
isiPtr->window = 1;
isiPtr->offset = 0;
isiPtr->unit = 1;
}
else {
dsiPtr->total = 1.0;
dsiPtr->window = 1.0;
dsiPtr->offset = 0.0;
dsiPtr->unit = 1.0;
}
}
/*----------------------------------------------------------------------
* Tix_GetScrollFractions --
*
* Compute the fractions of a scroll-able widget.
*
*/
void Tix_GetScrollFractions(siPtr, first_ret, last_ret)
Tix_ScrollInfo * siPtr;
double * first_ret;
double * last_ret;
{
Tix_IntScrollInfo* isiPtr = (Tix_IntScrollInfo*) siPtr;
Tix_DoubleScrollInfo* dsiPtr = (Tix_DoubleScrollInfo*)siPtr;
double total, window, first;
if (siPtr->type == TIX_SCROLL_INT) {
total = isiPtr->total;
window = isiPtr->window;
first = isiPtr->offset;
} else {
total = dsiPtr->total;
window = dsiPtr->window;
first = dsiPtr->offset;
}
if (total == 0 || total < window) {
*first_ret = 0.0;
*last_ret = 1.0;
} else {
*first_ret = first / total;
*last_ret = (first+window) / total;
}
}
void Tix_UpdateScrollBar(interp, siPtr)
Tcl_Interp *interp;
Tix_ScrollInfo * siPtr;
{
Tix_IntScrollInfo* isiPtr = (Tix_IntScrollInfo*) siPtr;
Tix_DoubleScrollInfo* dsiPtr = (Tix_DoubleScrollInfo*)siPtr;
double d_first, d_last;
char string[100];
if (siPtr->type == TIX_SCROLL_INT) {
/* Check whether the topPixel is out of bound */
if (isiPtr->offset < 0) {
isiPtr->offset = 0;
} else {
if (isiPtr->window > isiPtr->total) {
isiPtr->offset = 0;
}
else if((isiPtr->offset+isiPtr->window) > isiPtr->total) {
isiPtr->offset = isiPtr->total - isiPtr->window;
}
}
} else {
/* Check whether the topPixel is out of bound */
if (dsiPtr->offset < 0) {
dsiPtr->offset = 0;
} else {
if (dsiPtr->window > dsiPtr->total) {
dsiPtr->offset = 0;
}
else if((dsiPtr->offset+dsiPtr->window) > dsiPtr->total) {
dsiPtr->offset = dsiPtr->total - dsiPtr->window;
}
}
}
if (siPtr->command) {
Tix_GetScrollFractions(siPtr, &d_first, &d_last);
sprintf(string, " %f %f", d_first, d_last);
if (Tcl_VarEval(interp, siPtr->command, string,
(char *) NULL) != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (scrolling command executed by tixTList)");
Tk_BackgroundError(interp);
}
}
}
int Tix_SetScrollBarView(interp, siPtr, argc, argv, compat)
Tcl_Interp *interp; /* Current interpreter. */
Tix_ScrollInfo * siPtr;
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
int compat; /* compatibility mode */
{
Tix_IntScrollInfo* isiPtr = (Tix_IntScrollInfo*) siPtr;
Tix_DoubleScrollInfo* dsiPtr = (Tix_DoubleScrollInfo*)siPtr;
int offset;
if (compat && Tcl_GetInt(interp, argv[0], &offset) == TCL_OK) {
/* backward-compatible mode */
if (siPtr->type == TIX_SCROLL_INT) {
isiPtr->offset = offset;
}
else {
dsiPtr->offset = (double)offset;
}
return TCL_OK;
}
else {
int type, count;
double fraction;
Tcl_ResetResult(interp);
/* Tk_GetScrollInfo () wants strange argc,argv combinations .. */
type = Tk_GetScrollInfo(interp, argc+2, argv-2, &fraction, &count);
if (siPtr->type == TIX_SCROLL_INT) {
switch (type) {
case TK_SCROLL_ERROR:
return TCL_ERROR;
case TK_SCROLL_MOVETO:
isiPtr->offset =
(int)(fraction * (double)isiPtr->total);
break;
case TK_SCROLL_PAGES:
isiPtr->offset += count * isiPtr->window;
break;
case TK_SCROLL_UNITS:
isiPtr->offset += count * isiPtr->unit;
break;
}
} else {
switch (type) {
case TK_SCROLL_ERROR:
return TCL_ERROR;
case TK_SCROLL_MOVETO:
dsiPtr->offset =
fraction * dsiPtr->total;
break;
case TK_SCROLL_PAGES:
dsiPtr->offset += count * dsiPtr->window;
break;
case TK_SCROLL_UNITS:
dsiPtr->offset += count * dsiPtr->unit;
break;
}
}
}
return TCL_OK;
}

124
generic/tixSmpLs.c Normal file
View File

@@ -0,0 +1,124 @@
/* $Id: tixSmpLs.c,v 1.1.1.1 2000/05/17 11:08:42 idiscovery Exp $ */
/*
* tixSmpLs.c --
*
* To implement simple link lists (next is always the first
* member of the list).
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#include <tixPort.h>
#include <tixInt.h>
static Tix_ListInfo simpleListInfo = {
0,
TIX_UNDEFINED,
};
void Tix_SimpleListInit(lPtr)
Tix_LinkList * lPtr;
{
Tix_LinkListInit(lPtr);
}
void
Tix_SimpleListAppend(lPtr, itemPtr, flags)
Tix_LinkList * lPtr;
char * itemPtr;
int flags;
{
Tix_LinkListAppend(&simpleListInfo, lPtr, itemPtr, flags);
}
void Tix_SimpleListIteratorInit(liPtr)
Tix_ListIterator * liPtr;
{
Tix_LinkListIteratorInit(liPtr);
}
void Tix_SimpleListStart(lPtr, liPtr)
Tix_LinkList * lPtr;
Tix_ListIterator * liPtr;
{
Tix_LinkListStart(&simpleListInfo, lPtr, liPtr);
}
void Tix_SimpleListNext(lPtr, liPtr)
Tix_LinkList * lPtr;
Tix_ListIterator * liPtr;
{
Tix_LinkListNext(&simpleListInfo, lPtr, liPtr);
}
/*
* To delete consecutive elements, you must delete, next, delete, next ...
*/
void Tix_SimpleListDelete(lPtr, liPtr)
Tix_LinkList * lPtr;
Tix_ListIterator * liPtr;
{
Tix_LinkListDelete(&simpleListInfo, lPtr, liPtr);
}
/*----------------------------------------------------------------------
* Tix_SimpleListInsert --
*
* Insert the item at the position indicated by liPtr
*----------------------------------------------------------------------
*/
void Tix_SimpleListInsert(lPtr, itemPtr, liPtr)
Tix_LinkList * lPtr;
char * itemPtr;
Tix_ListIterator * liPtr;
{
Tix_LinkListInsert(&simpleListInfo, lPtr, itemPtr, liPtr);
}
/*----------------------------------------------------------------------
* Tix_SimpleListFindAndDelete --
*
* Find an element and delete it.
*
* liPtr:
* Can be zero.
* If non-zero, the search will start from the current entry indexed
* by liPtr;
*
* Return value:
* 1 if element is found and deleted
* 0 if element is not found
*----------------------------------------------------------------------
*/
int Tix_SimpleListFindAndDelete(lPtr, itemPtr, liPtr)
Tix_LinkList * lPtr;
char * itemPtr;
Tix_ListIterator * liPtr;
{
return Tix_LinkListFindAndDelete(&simpleListInfo, lPtr, itemPtr, liPtr);
}
int Tix_SimpleListDeleteRange(lPtr, fromPtr, toPtr, liPtr)
Tix_LinkList * lPtr;
char * fromPtr;
char * toPtr;
Tix_ListIterator * liPtr;
{
return Tix_LinkListDeleteRange(&simpleListInfo, lPtr,
fromPtr, toPtr, liPtr);
}
int Tix_SimpleListFind(lPtr, itemPtr, liPtr)
Tix_LinkList * lPtr;
char * itemPtr;
Tix_ListIterator * liPtr;
{
return Tix_LinkListFind(&simpleListInfo, lPtr, itemPtr, liPtr);
}

2493
generic/tixTList.c Normal file

File diff suppressed because it is too large Load Diff

144
generic/tixTList.h Normal file
View File

@@ -0,0 +1,144 @@
/* $Id: tixTList.h,v 1.2 2000/12/24 07:06:22 ioilam Exp $ */
/*
* tixTList.h --
*
* This header file defines the data structures used by the tixTList
* widget.
*
* Copyright (c) 1996, Expert Interface Technologies
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
*/
#ifndef _TIX_TLIST_H_
#define _TIX_TLIST_H_
#define TIX_X 0
#define TIX_Y 1
typedef struct ListEntry {
struct ListEntry * next;
Tix_DItem * iPtr;
Tk_Uid state;
int size[2];
unsigned int selected : 1;
} ListEntry;
typedef struct ListRow {
ListEntry * chPtr;
int size[2];
int numEnt;
} ListRow;
/*
* A data structure of the following type is kept for each
* widget managed by this file:
*/
typedef struct ListStruct {
Tix_DispData dispData;
Tcl_Command widgetCmd; /* Token for button's widget command. */
/*
* Information used when displaying widget:
*/
int width, height; /* For app programmer to request size */
/*
* Information used when displaying widget:
*/
/* Border and general drawing */
int borderWidth; /* Width of 3-D borders. */
int selBorderWidth; /* Width of 3-D borders for selected items */
int relief; /* Indicates whether window as a whole is
* raised, sunken, or flat. */
Tk_3DBorder border; /* Used for drawing the 3d border. */
Tk_3DBorder selectBorder; /* Used for selected background. */
XColor *normalFg; /* Normal foreground for text. */
XColor *normalBg; /* Normal background for text. */
XColor *selectFg; /* Color for drawing selected text. */
/* GC and stuff */
GC backgroundGC; /* GC for drawing background. */
GC selectGC; /* GC for drawing selected background. */
GC anchorGC; /* GC for drawing dotted anchor highlight
* around a selected item */
GC anchorGC2; /* GC for drawing dotted anchor highlight
* around an unselected item */
TixFont font; /* Default font used by the DItems. */
/* Text drawing */
Cursor cursor; /* Current cursor for window, or None. */
/* For highlights */
int highlightWidth; /* Width in pixels of highlight to draw
* around widget when it has the focus.
* <= 0 means don't draw a highlight. */
XColor *highlightColorPtr; /* Color for drawing traversal highlight. */
GC highlightGC; /* For drawing traversal highlight. */
/* default pad and gap values */
int padX, padY;
Tk_Uid selectMode; /* Selection style: single, browse, multiple,
* or extended. This value isn't used in C
* code, but the Tcl bindings use it. */
Tk_Uid state; /* State can only be normal or disabled. */
Tix_LinkList entList;
int numRowAllocd;
int numRow;
ListRow * rows;
ListEntry * seeElemPtr; /* The current item to "see" */
ListEntry * anchor; /* The current anchor item */
ListEntry * active; /* The current active item */
ListEntry * dropSite; /* The current drop site */
ListEntry * dragSite; /* The current drop site */
/*
* Commands
*/
char *command; /* The command when user double-clicks */
char *browseCmd; /* The command to call when the selection
* changes. */
char *sizeCmd; /* The command to call when the size of
* the listbox changes. E.g., when the user
* add/deletes elements. Useful for
* auto-scrollbar geometry managers */
/* These options control how the items are arranged on the list */
Tk_Uid orientUid; /* Can be "vertical" or "horizontal" */
int packMode[2]; /* is row and column packed */
int numMajor[2]; /* num of rows and columns */
int itemSize[2]; /* horizontal and vertical size of items, -1
* means natural size */
/* Info for laying out */
int maxSize[2]; /* max size of all elements in X and Y, (they
* do not need to be the same element, may be
* invalid according to mode */
char *takeFocus; /* Value of -takefocus option; not used in
* the C code, but used by keyboard traversal
* scripts. Malloc'ed, but may be NULL. */
int serial; /* this number is incremented before each time
* the widget is redisplayed */
Tix_DItemInfo * diTypePtr; /* Default item type */
Tix_IntScrollInfo scrollInfo[2];
unsigned int redrawing : 1;
unsigned int resizing : 1;
unsigned int hasFocus : 1;
unsigned int isVertical : 1;
} TixTListWidget;
typedef TixTListWidget WidgetRecord;
typedef TixTListWidget * WidgetPtr;
#endif /* _TIX_TLIST_H_ */

821
generic/tixUtils.c Normal file
View File

@@ -0,0 +1,821 @@
/*
* tixUtils.c --
*
* This file contains some utility functions for Tix, such as the
* subcommand handling functions and option handling functions.
*
* Copyright (c) 1993-1999 Ioi Kim Lam.
* Copyright (c) 2000-2001 Tix Project Group.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tixUtils.c,v 1.13 2008/02/28 04:29:17 hobbs Exp $
*/
#include <tcl.h>
#include <tixPort.h>
#include <tixInt.h>
/*
* Forward declarations for procedures defined later in this file:
*/
static int ReliefParseProc(ClientData clientData,
Tcl_Interp *interp, Tk_Window tkwin, CONST84 char *value,
char *widRec, int offset);
static char * ReliefPrintProc(ClientData clientData,
Tk_Window tkwin, char *widRec, int offset,
Tix_FreeProc **freeProcPtr);
#define WRONG_ARGC 1
#define NO_MATCH 2
/*----------------------------------------------------------------------
* Tix_HandleSubCmds --
*
* This function makes it easier to write major-minor style TCL
* commands. It matches the minor command (sub-command) names
* with names defined in the cmdInfo structure and call the
* appropriate sub-command functions for you. This function will
* automatically generate error messages when the user calls an
* invalid sub-command or calls a sub-command with incorrect
* number of arguments.
*
*----------------------------------------------------------------------
*/
int Tix_HandleSubCmds(cmdInfo, subCmdInfo, clientData, interp, argc, argv)
Tix_CmdInfo * cmdInfo;
Tix_SubCmdInfo * subCmdInfo;
ClientData clientData; /* Main window associated with
* interpreter. */
Tcl_Interp *interp; /* Current interpreter. */
int argc; /* Number of arguments. */
CONST84 char **argv; /* Argument strings. */
{
int i;
int error = NO_MATCH;
unsigned int len;
Tix_SubCmdInfo * s;
/*
* First check if the number of arguments to the major command
* is correct
*/
argc -= 1;
if (argc < cmdInfo->minargc ||
(cmdInfo->maxargc != TIX_VAR_ARGS && argc > cmdInfo->maxargc)) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
argv[0], " ", cmdInfo->info, "\".", (char *) NULL);
return TCL_ERROR;
}
/*
* Now try to match the subcommands with argv[1]
*/
argc -= 1;
len = strlen(argv[1]);
for (i = 0, s = subCmdInfo; i < cmdInfo->numSubCmds; i++, s++) {
if (s->name == TIX_DEFAULT_SUBCMD) {
if (s->checkArgvProc) {
if (!((*s->checkArgvProc)(clientData, interp, argc+1, argv+1))) {
/* Some improper argv in the arguments of the default
* subcommand
*/
break;
}
}
return (*s->proc)(clientData, interp, argc+1, argv+1);
}
if (s->namelen == TIX_DEFAULT_LEN) {
s->namelen = strlen(s->name);
}
if (s->name[0] == argv[1][0] && strncmp(argv[1],s->name,len)==0) {
if (argc < s->minargc) {
error = WRONG_ARGC;
break;
}
if (s->maxargc != TIX_VAR_ARGS &&
argc > s->maxargc) {
error = WRONG_ARGC;
break;
}
/*
* Here we have a matched argc and command name --> go for it!
*/
return (*s->proc)(clientData, interp, argc, argv+2);
}
}
if (error == WRONG_ARGC) {
/*
* got a match but incorrect number of arguments
*/
Tcl_AppendResult(interp, "wrong # args: should be \"",
argv[0], " ", argv[1], " ", s->info, "\"", (char *) NULL);
} else {
int max;
/*
* no match: let print out all the options
*/
Tcl_AppendResult(interp, "unknown option \"",
argv[1], "\".", (char *) NULL);
if (cmdInfo->numSubCmds == 0) {
max = 0;
} else {
if (subCmdInfo[cmdInfo->numSubCmds-1].name == TIX_DEFAULT_SUBCMD) {
max = cmdInfo->numSubCmds-1;
} else {
max = cmdInfo->numSubCmds;
}
}
if (max == 0) {
Tcl_AppendResult(interp,
" This command does not take any options.",
(char *) NULL);
} else if (max == 1) {
Tcl_AppendResult(interp,
" Must be ", subCmdInfo->name, ".", (char *)NULL);
} else {
Tcl_AppendResult(interp, " Must be ", (char *) NULL);
for (i = 0, s = subCmdInfo; i < max; i++, s++) {
if (i == max-1) {
Tcl_AppendResult(interp,"or ",s->name, ".", (char *) NULL);
} else if (i == max-2) {
Tcl_AppendResult(interp, s->name, " ", (char *) NULL);
} else {
Tcl_AppendResult(interp, s->name, ", ", (char *) NULL);
}
}
}
}
return TCL_ERROR;
}
/*----------------------------------------------------------------------
* Tix_Exit --
*
* Call the "exit" tcl command so that things can be cleaned up
* before calling the unix exit(2);
*
*----------------------------------------------------------------------
*/
void Tix_Exit(interp, code)
Tcl_Interp* interp;
int code;
{
const char *str;
if (code != 0 && interp && ((str = Tcl_GetStringResult(interp)) != NULL)) {
fprintf(stderr, "%s\n", str);
fprintf(stderr, "%s\n",
Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY));
}
if (interp) {
Tcl_EvalEx(interp, "exit", -1, TCL_GLOBAL_ONLY);
}
exit(code);
}
/*----------------------------------------------------------------------
* Tix_CreateCommands --
*
*
* Creates a list of commands stored in the array "commands"
*----------------------------------------------------------------------
*/
static int initialized = 0;
void Tix_CreateCommands(interp, commands, clientData, deleteProc)
Tcl_Interp *interp;
Tix_TclCmd *commands;
ClientData clientData;
Tcl_CmdDeleteProc *deleteProc;
{
Tix_TclCmd * cmdPtr;
if (!initialized) {
Tcl_CmdInfo cmdInfo;
initialized = 1;
if (!Tcl_GetCommandInfo(interp,"image", (Tcl_CmdInfo *) &cmdInfo)) {
Tcl_Panic("cannot find the \"image\" command");
} else if (cmdInfo.isNativeObjectProc == 1) {
initialized = 2; /* we use objects */
}
}
for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {
Tcl_CreateCommand(interp, cmdPtr->name,
cmdPtr->cmdProc, clientData, deleteProc);
}
}
/*
*----------------------------------------------------------------------
* Tix_GetAnchorGC --
*
* Get the GC for drawing the anchor dotted lines around anchor
* elements.
*
* Results:
* Returns a GC that can be passed to Tix_DrawAnchorLines for
* drawing an anchor line for the given background color.
*
* Side effects:
* None.
*----------------------------------------------------------------------
*/
GC
Tix_GetAnchorGC(tkwin, bgColor)
Tk_Window tkwin;
XColor *bgColor;
{
XGCValues gcValues;
XColor valueKey;
XColor * anchorColor;
int r, g, b;
int max;
/*
* Get the best color to draw the dotted lines on the given background
* color.
*/
r = bgColor->red;
g = bgColor->green;
b = bgColor->blue;
r = (65535 - r) & 0xffff;
g = (65535 - g) & 0xffff;
b = (65535 - b) & 0xffff;
max = r;
if (max < g) {
max = g;
}
if (max < b) {
max = b;
}
max = max / 256;
if (max > 96) {
/*
* scale color up
*/
r = (r * 255) / max;
g = (g * 255) / max;
b = (b * 255) / max;
} else {
/*
* scale color down
*/
int min = r;
if (min > g) {
min = g;
}
if (min > b) {
min = b;
}
r = r - min;
g = g - min;
b = b - min;
}
valueKey.red = r;
valueKey.green = g;
valueKey.blue = b;
anchorColor = Tk_GetColorByValue(tkwin, &valueKey);
gcValues.foreground = anchorColor->pixel;
gcValues.graphics_exposures = False;
gcValues.subwindow_mode = IncludeInferiors;
return Tk_GetGC(tkwin, GCForeground|GCGraphicsExposures|GCSubwindowMode,
&gcValues);
}
/*
*----------------------------------------------------------------------
* Tix_DrawAnchorLines --
*
* Draw dotted anchor lines around anchor elements. The exact
* behavior is defined in the platform-specific
* TixpDrawAnchorLines function.
*
* Results:
* None.
*
* Side effects:
* None.
*----------------------------------------------------------------------
*/
void
Tix_DrawAnchorLines(display, drawable, gc, x, y, w, h)
Display *display;
Drawable drawable;
GC gc;
int x;
int y;
int w;
int h;
{
TixpDrawAnchorLines(display, drawable, gc, x, y, w, h);
}
/*----------------------------------------------------------------------
* Tix_CreateSubWindow --
*
* Creates a subwindow for a widget (usually used to draw headers,
* e.g, HList and Grid widgets)
*----------------------------------------------------------------------
*/
Tk_Window
Tix_CreateSubWindow(interp, tkwin, subPath)
Tcl_Interp * interp;
Tk_Window tkwin;
CONST84 char * subPath;
{
Tcl_DString dString;
Tk_Window subwin;
Tcl_DStringInit(&dString);
Tcl_DStringAppend(&dString, Tk_PathName(tkwin),
(int) strlen(Tk_PathName(tkwin)));
Tcl_DStringAppend(&dString, ".tixsw:", 7);
Tcl_DStringAppend(&dString, subPath, (int) strlen(subPath));
subwin = Tk_CreateWindowFromPath(interp, tkwin, dString.string,
(char *) NULL);
Tcl_DStringFree(&dString);
return subwin;
}
static int
ErrorProc(clientData, errorEventPtr)
ClientData clientData;
XErrorEvent *errorEventPtr; /* unused */
{
int * badAllocPtr = (int*) clientData;
* badAllocPtr = 1;
return 0; /* return 0 means error has been
* handled properly */
}
/*
*----------------------------------------------------------------------
* Tix_GetRenderBuffer --
*
* Returns a drawable for rendering a widget. If there is
* sufficient graphics resource, a pixmap is returned so that
* double-buffering can be done. However, if resource is
* insufficient, then the windowId is returned. In the second
* case happens, the caller of this function has two choices: (1)
* draw to the window directly (which may lead to flickering on
* the screen) or (2) try to allocate smaller pixmaps.
*
* Results:
* An allocated pixmap of the same depth as the window, or the
* window itself.
*
* Side effects:
* A pixmap may be allocated. The caller should call
* Tk_FreePixmap() to free the pixmap returned by this function.
*
*----------------------------------------------------------------------
*/
/*
* Uncomment this if you want to use single-buffer mode drawing to
* debug paintings.
*/
/* #define PAINT_DEBUG 1 */
Drawable
Tix_GetRenderBuffer(display, windowId, width, height, depth)
Display *display; /* Display of the windowId */
Window windowId; /* Window to draw into */
int width; /* width of the drawing region */
int height; /* height of the drawing region */
int depth; /* Depth of the window. TODO remove this arg*/
{
#ifdef PAINT_DEBUG
return windowId;
#else
Tk_ErrorHandler handler;
Pixmap pixmap;
int badAlloc = 0;
handler= Tk_CreateErrorHandler(display, BadAlloc,
-1, -1, (Tk_ErrorProc *) ErrorProc, (ClientData) &badAlloc);
pixmap = Tk_GetPixmap(display, windowId, width, height, depth);
#if !defined(__WIN32__) && !defined(MAC_TCL) && !defined(MAC_OSX_TK) /* UNIX */
/*
* This XSync call is necessary because X may delay the delivery of the
* error message. This will make our graphics a bit slower, though,
* especially over slow lines
*/
XSync(display, 0);
#endif
/* If ErrorProc() is eevr called, it is called before XSync returns */
Tk_DeleteErrorHandler(handler);
if (!badAlloc) {
return pixmap;
} else {
return windowId;
}
#endif
}
/*
*----------------------------------------------------------------------
*
* Tix_GlobalVarEval --
*
* Given a variable number of string arguments, concatenate them
* all together and execute the result as a Tcl command in the global
* scope.
*
* Results:
* A standard Tcl return result. An error message or other
* result may be left in the interp's result.
*
* Side effects:
* Depends on what was done by the command.
*
*----------------------------------------------------------------------
*/
/* VARARGS2 */ /* ARGSUSED */
int
Tix_GlobalVarEval TCL_VARARGS_DEF(Tcl_Interp *,arg1)
{
va_list argList;
Tcl_DString buf;
char *string;
Tcl_Interp *interp;
int result;
/*
* Copy the strings one after the other into a single larger
* string. Use stack-allocated space for small commands, but if
* the command gets too large than call ckalloc to create the
* space.
*/
interp = TCL_VARARGS_START(Tcl_Interp *,arg1,argList);
Tcl_DStringInit(&buf);
while (1) {
string = va_arg(argList, char *);
if (string == NULL) {
break;
}
Tcl_DStringAppend(&buf, string, -1);
}
va_end(argList);
result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf),
Tcl_DStringLength(&buf), TCL_GLOBAL_ONLY);
Tcl_DStringFree(&buf);
return result;
}
/*----------------------------------------------------------------------
* TixGetHashTable --
*
* This functions makes it possible to keep one hash table per
* interpreter. This way, Tix classes can be used in multiple
* interpreters.
*
*----------------------------------------------------------------------
*/
static void DeleteHashTableProc _ANSI_ARGS_((ClientData clientData,
Tcl_Interp * interp));
static void
DeleteHashTableProc(clientData, interp)
ClientData clientData;
Tcl_Interp * interp;
{
Tcl_HashTable * htPtr = (Tcl_HashTable *)clientData;
Tcl_HashSearch hashSearch;
Tcl_HashEntry * hashPtr;
for (hashPtr = Tcl_FirstHashEntry(htPtr, &hashSearch);
hashPtr;
hashPtr = Tcl_NextHashEntry(&hashSearch)) {
Tcl_DeleteHashEntry(hashPtr);
}
Tcl_DeleteHashTable(htPtr);
ckfree((char*)htPtr);
}
/*
*----------------------------------------------------------------------
* TixGetHashTable() --
*
* Returns a named hashtable to be used for the given
* interpreter. Creates the hashtable if it doesn't exist yet. It
* uses Tcl_GetAssocData to make sure that the hashtable is not
* shared by different interpreters.
*
* Results:
* Pointer to the hashtable.
*
* Side effects:
* The hashtable is created if it doesn't exist yet.
*
*----------------------------------------------------------------------
*/
Tcl_HashTable *
TixGetHashTable(interp, name, deleteProc, keyType)
Tcl_Interp * interp;
char * name;
Tcl_InterpDeleteProc *deleteProc;
int keyType;
{
Tcl_HashTable * htPtr;
htPtr = (Tcl_HashTable*)Tcl_GetAssocData(interp, name, NULL);
if (htPtr == NULL) {
htPtr = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));
Tcl_InitHashTable(htPtr, keyType);
Tcl_SetAssocData(interp, name, NULL, (ClientData)htPtr);
if (deleteProc) {
Tcl_CallWhenDeleted(interp, deleteProc, (ClientData)htPtr);
} else {
Tcl_CallWhenDeleted(interp, DeleteHashTableProc,
(ClientData)htPtr);
}
}
return htPtr;
}
/*----------------------------------------------------------------------
*
* The Tix Customed Config Options
*
*----------------------------------------------------------------------
*/
/*----------------------------------------------------------------------
* ReliefParseProc --
*
* Parse the text string and store the Tix_Relief information
* inside the widget record.
*----------------------------------------------------------------------
*/
static int
ReliefParseProc(clientData, interp, tkwin, value, widRec,offset)
ClientData clientData;
Tcl_Interp *interp;
Tk_Window tkwin;
CONST84 char *value;
char *widRec; /* Must point to a valid Tix_DItem struct */
int offset;
{
Tix_Relief * ptr = (Tix_Relief *)(widRec + offset);
Tix_Relief newVal;
if (value != NULL) {
size_t len = strlen(value);
if (strncmp(value, "raised", len) == 0) {
newVal = TIX_RELIEF_RAISED;
} else if (strncmp(value, "flat", len) == 0) {
newVal = TIX_RELIEF_FLAT;
} else if (strncmp(value, "sunken", len) == 0) {
newVal = TIX_RELIEF_SUNKEN;
} else if (strncmp(value, "groove", len) == 0) {
newVal = TIX_RELIEF_GROOVE;
} else if (strncmp(value, "ridge", len) == 0) {
newVal = TIX_RELIEF_RIDGE;
} else if (strncmp(value, "solid", len) == 0) {
newVal = TIX_RELIEF_SOLID;
} else {
goto error;
}
} else {
value = "";
goto error;
}
*ptr = newVal;
return TCL_OK;
error:
Tcl_AppendResult(interp, "bad relief type \"", value,
"\": must be flat, groove, raised, ridge, solid or sunken", NULL);
return TCL_ERROR;
}
static char *
ReliefPrintProc(clientData, tkwin, widRec,offset, freeProcPtr)
ClientData clientData;
Tk_Window tkwin;
char *widRec;
int offset;
Tix_FreeProc **freeProcPtr;
{
Tix_Relief *ptr = (Tix_Relief*)(widRec+offset);
switch (*ptr) {
case TIX_RELIEF_RAISED:
return "raised";
case TIX_RELIEF_FLAT:
return "flat";
case TIX_RELIEF_SUNKEN:
return "sunken";
case TIX_RELIEF_GROOVE:
return "groove";
case TIX_RELIEF_RIDGE:
return "ridge";
case TIX_RELIEF_SOLID:
return "solid";
default:
return "unknown";
}
}
/*
* The global data structures to use in widget configSpecs arrays
*
* These are declared in <tix.h>
*/
Tk_CustomOption tixConfigRelief = {
ReliefParseProc, ReliefPrintProc, 0,
};
/* Tix_SetRcFileName --
*
* Sets a user-specific startup file in a way that's compatible with
* different versions of Tclsh
*/
void Tix_SetRcFileName(interp, rcFileName)
Tcl_Interp * interp;
CONST84 char * rcFileName;
{
/*
* Starting from TCL 7.5, the symbol tcl_rcFileName is no longer
* exported by libtcl.a. Instead, this variable must be set using
* a TCL global variable
*/
Tcl_SetVar(interp, "tcl_rcFileName", rcFileName, TCL_GLOBAL_ONLY);
}
/*
* The TkComputeTextGeometry function is no longer supported in Tk 8.0+
*/
/*
*----------------------------------------------------------------------
*
* TixComputeTextGeometry --
*
* This procedure computes the amount of screen space needed to
* display a multi-line string of text.
*
* Results:
* There is no return value. The dimensions of the screen area
* needed to display the text are returned in *widthPtr, and *heightPtr.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
TixComputeTextGeometry(font, string, numChars, wrapLength,
widthPtr, heightPtr)
TixFont font; /* Font that will be used to display text. */
CONST84 char *string; /* String whose dimensions are to be
* computed. */
int numChars; /* Number of characters to consider from
* string. -1 means the entire size of
* the text string */
int wrapLength; /* Longest permissible line length, in
* pixels. <= 0 means no automatic wrapping:
* just let lines get as long as needed. */
int *widthPtr; /* Store width of string here. */
int *heightPtr; /* Store height of string here. */
{
Tk_TextLayout textLayout;
/*
* The justification itself doesn't affect the geometry (size) of
* the text string. We pass TK_JUSTIFY_LEFT.
*/
textLayout = Tk_ComputeTextLayout(font,
string, numChars, wrapLength, TK_JUSTIFY_LEFT, 0,
widthPtr, heightPtr);
Tk_FreeTextLayout(textLayout);
}
/*
*----------------------------------------------------------------------
*
* TixDisplayText --
*
* Display a text string on one or more lines.
*
* Results:
* None.
*
* Side effects:
* The text given by "string" gets displayed at the given location
* in the given drawable with the given font etc.
*
*----------------------------------------------------------------------
*/
void
TixDisplayText(display, drawable, font, string, numChars, x, y,
length, justify, underline, gc)
Display *display; /* X display to use for drawing text. */
Drawable drawable; /* Window or pixmap in which to draw the
* text. */
TixFont font; /* Font that determines geometry of text
* (should be same as font in gc). */
CONST84 char *string; /* String to display; may contain embedded
* newlines. */
int numChars; /* Number of characters to use from string. */
int x, y; /* Pixel coordinates within drawable of
* upper left corner of display area. */
int length; /* Line length in pixels; used to compute
* word wrap points and also for
* justification. Must be > 0. */
Tk_Justify justify; /* How to justify lines. */
int underline; /* Index of character to underline, or < 0
* for no underlining. */
GC gc; /* Graphics context to use for drawing text. */
{
Tk_TextLayout textLayout;
int dummyx, dummyy;
textLayout = Tk_ComputeTextLayout(font,
string, numChars, length, justify, 0,
&dummyx, &dummyy);
Tk_DrawTextLayout(display, drawable, gc, textLayout,
x, y, 0, -1);
Tk_UnderlineTextLayout(display, drawable, gc,
textLayout, x, y, underline);
Tk_FreeTextLayout(textLayout);
}
/*
*----------------------------------------------------------------------
* Tix_ZAlloc --
*
* Allocate the memory block with ckalloc and zeros it.
*
* Results:
* Same as ckalloc() except the new memory block is filled with
* zero. Returns NULL if memory allocation fails.
*
* Side effects:
* None.
*----------------------------------------------------------------------
*/
char * Tix_ZAlloc(nbytes)
unsigned int nbytes; /* size of memory block to alloc, in
* number of bytes.*/
{
char * ptr = (char*)ckalloc(nbytes);
if (ptr) {
memset(ptr, 0, nbytes);
}
return ptr;
}

277
generic/tixWidget.c Normal file
View File

@@ -0,0 +1,277 @@
/*
* tixWidget.c --
*
* Constructs Tix-based mega widgets
*
* Copyright (c) 1993-1999 Ioi Kim Lam.
* Copyright (c) 2000-2001 Tix Project Group.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tixWidget.c,v 1.7 2008/02/28 04:29:17 hobbs Exp $
*/
#include <tclInt.h>
#include <tixInt.h>
static int ParseOptions(Tcl_Interp *interp, TixClassRecord *cPtr,
CONST84 char *widRec, int argc, CONST84 char** argv);
TIX_DECLARE_CMD(Tix_InstanceCmd);
/*----------------------------------------------------------------------
* Tix_CreateWidgetCmd
*
* Create an instance object of a Tix widget class.
*
* argv[0] = object name.
* argv[1+] = args
*----------------------------------------------------------------------
*/
TIX_DEFINE_CMD(Tix_CreateWidgetCmd)
{
TixClassRecord * cPtr =(TixClassRecord *)clientData;
TixConfigSpec * spec;
CONST84 char * value;
CONST84 char * widRec = NULL;
char * widCmd = NULL, * rootCmd = NULL;
int i;
int code = TCL_OK;
Tk_Window mainWin = Tk_MainWindow(interp);
if (argc <= 1) {
return Tix_ArgcError(interp, argc, argv, 1, "pathname ?arg? ...");
} else {
widRec = argv[1];
}
if (strstr(argv[1], "::") != NULL) {
/*
* Cannot contain :: in widget name, otherwise all hell will
* rise w.r.t. namespace
*/
Tcl_AppendResult(interp, "invalid widget name \"", argv[1],
"\": may not contain substring \"::\"", NULL);
return TCL_ERROR;
}
Tcl_ResetResult(interp);
if (Tk_NameToWindow(interp, widRec, mainWin) != NULL) {
Tcl_AppendResult(interp, "window name \"", widRec,
"\" already exists", NULL);
return TCL_ERROR;
}
/*
* Before doing anything, let's reset the TCL result, errorInfo,
* errorCode, etc.
*/
Tcl_SetVar2(interp, "errorInfo", NULL, "", TCL_GLOBAL_ONLY);
Tcl_SetVar2(interp, "errorCode", NULL, "", TCL_GLOBAL_ONLY);
/*
* Set up the widget record
*
* TODO: avoid buffer allocation if possible.
*/
widCmd = ckalloc(strlen(widRec) + 3);
sprintf(widCmd, "::%s", widRec);
rootCmd = ckalloc(strlen(widRec) + 8);
sprintf(rootCmd, "::%s:root", widRec);
Tcl_SetVar2(interp, widRec, "className", cPtr->className, TCL_GLOBAL_ONLY);
Tcl_SetVar2(interp, widRec, "ClassName", cPtr->ClassName, TCL_GLOBAL_ONLY);
Tcl_SetVar2(interp, widRec, "context", cPtr->className, TCL_GLOBAL_ONLY);
Tcl_SetVar2(interp, widRec, "w:root", widRec, TCL_GLOBAL_ONLY);
Tcl_SetVar2(interp, widRec, "rootCmd", rootCmd, TCL_GLOBAL_ONLY);
/* We need to create the root widget in order to parse the options
* database
*/
if (Tix_CallMethod(interp, cPtr->className, widRec, "CreateRootWidget",
argc-2, argv+2, NULL) != TCL_OK) {
code = TCL_ERROR;
goto done;
}
/* Parse the options specified in the option database and supplied
* in the command line.
*/
Tcl_ResetResult(interp);
if (ParseOptions(interp, cPtr, widRec, argc-2, argv+2) != TCL_OK) {
code = TCL_ERROR;
goto done;
}
/* Rename the root widget command and create a new TCL command for
* this widget
*/
if (TclRenameCommand(interp, widCmd, rootCmd) != TCL_OK) {
code = TCL_ERROR;
goto done;
}
Tcl_CreateCommand(interp, widRec, Tix_InstanceCmd,
(ClientData)cPtr, NULL);
/* Now call the initialization methods defined by the Tix Intrinsics
*/
if (Tix_CallMethod(interp, cPtr->className, widRec, "InitWidgetRec",
0, 0, NULL) != TCL_OK) {
code = TCL_ERROR;
goto done;
}
if (Tix_CallMethod(interp, cPtr->className, widRec, "ConstructWidget",
0, 0, NULL) != TCL_OK) {
code = TCL_ERROR;
goto done;
}
if (Tix_CallMethod(interp, cPtr->className, widRec, "SetBindings",
0, 0, NULL) != TCL_OK) {
code = TCL_ERROR;
goto done;
}
/* The widget has been successfully initialized. Now call the config
* method for all -forceCall options
*/
for (i=0; i<cPtr->nSpecs; i++) {
spec = cPtr->specs[i];
if (spec->forceCall) {
value = Tcl_GetVar2(interp, widRec, spec->argvName,
TCL_GLOBAL_ONLY);
if (Tix_CallConfigMethod(interp, cPtr, widRec, spec,
value)!=TCL_OK){
code = TCL_ERROR;
goto done;
}
}
}
Tcl_SetResult(interp, (char *) widRec, TCL_VOLATILE);
done:
if (code != TCL_OK) {
Tk_Window topLevel, tkwin;
Tcl_SavedResult state;
/* We need to save the current interp state as it may be changed by
* some of the following function calls.
*/
Tcl_SaveResult(interp, &state);
Tcl_ResetResult(interp);
/* (1) window */
topLevel = cPtr->mainWindow;
if (widRec != NULL) {
Display *display = NULL;
tkwin = Tk_NameToWindow(interp, widRec, topLevel);
if (tkwin != NULL) {
display = Tk_Display(tkwin);
Tk_DestroyWindow(tkwin);
}
/*
* (2) Clean up widget command + root command. Because widCmd
* and rootCmd contains ::, the commands will be correctly
* deleted from the global namespace.
*/
Tcl_DeleteCommand(interp, widCmd);
Tcl_DeleteCommand(interp, rootCmd);
/* (3) widget record */
Tcl_UnsetVar(interp, widRec, TCL_GLOBAL_ONLY);
if (display) {
#if !defined(__WIN32__) && !defined(MAC_TCL) && !defined(MAC_OSX_TK) /* UNIX */
/* TODO: why is this necessary?? */
XSync(display, False);
#endif
while (1) {
if (Tk_DoOneEvent(TK_X_EVENTS|TK_DONT_WAIT) == 0) {
break;
}
}
}
}
Tcl_RestoreResult(interp, &state);
}
if (widCmd) {
ckfree(widCmd);
}
if (rootCmd) {
ckfree(rootCmd);
}
return code;
}
/*----------------------------------------------------------------------
* Subroutines for object instantiation.
*
*
*----------------------------------------------------------------------
*/
static int ParseOptions(interp, cPtr, widRec, argc, argv)
Tcl_Interp * interp;
TixClassRecord * cPtr;
CONST84 char *widRec;
int argc;
CONST84 char** argv;
{
int i;
TixConfigSpec *spec;
Tk_Window tkwin;
CONST84 char * value;
if ((argc %2) != 0) {
Tcl_AppendResult(interp, "missing argument for \"", argv[argc-1],
"\"", NULL);
return TCL_ERROR;
}
if ((tkwin = Tk_NameToWindow(interp, widRec, cPtr->mainWindow)) == NULL) {
return TCL_ERROR;
}
/* Set all specs by their default values */
/* BUG: default value may be override by options database */
for (i=0; i<cPtr->nSpecs; i++) {
spec = cPtr->specs[i];
if (!spec->isAlias) {
if ((value=Tk_GetOption(tkwin,spec->dbName,spec->dbClass))==NULL) {
value = spec->defValue;
}
if (Tix_ChangeOneOption(interp, cPtr, widRec, spec,
value, 1, 0)!=TCL_OK) {
return TCL_ERROR;
}
}
}
/* Set specs according to argument line values */
for (i=0; i<argc; i+=2) {
spec = Tix_FindConfigSpecByName(interp, cPtr, argv[i]);
if (spec == NULL) { /* this is an invalid flag */
return TCL_ERROR;
}
if (Tix_ChangeOneOption(interp, cPtr, widRec, spec,
argv[i+1], 0, 1)!=TCL_OK) {
return TCL_ERROR;
}
}
return TCL_OK;
}